• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "upb/json/encode.h"
9 
10 #include <cstddef>
11 #include <string>
12 
13 #include "google/protobuf/struct.upb.h"
14 #include <gtest/gtest.h>
15 #include "upb/base/status.hpp"
16 #include "upb/base/upcast.h"
17 #include "upb/json/test.upb.h"
18 #include "upb/json/test.upbdefs.h"
19 #include "upb/mem/arena.h"
20 #include "upb/mem/arena.hpp"
21 #include "upb/reflection/def.hpp"
22 
JsonEncode(const upb_test_Box * msg,int options)23 static std::string JsonEncode(const upb_test_Box* msg, int options) {
24   upb::Arena a;
25   upb::Status status;
26   upb::DefPool defpool;
27   upb::MessageDefPtr m(upb_test_Box_getmsgdef(defpool.ptr()));
28   EXPECT_TRUE(m.ptr() != nullptr);
29 
30   size_t json_size = upb_JsonEncode(UPB_UPCAST(msg), m.ptr(), defpool.ptr(),
31                                     options, nullptr, 0, status.ptr());
32   char* json_buf = (char*)upb_Arena_Malloc(a.ptr(), json_size + 1);
33 
34   size_t size = upb_JsonEncode(UPB_UPCAST(msg), m.ptr(), defpool.ptr(), options,
35                                json_buf, json_size + 1, status.ptr());
36   EXPECT_EQ(size, json_size);
37   return std::string(json_buf, json_size);
38 }
39 
40 // Encode a single optional enum.
TEST(JsonTest,EncodeEnum)41 TEST(JsonTest, EncodeEnum) {
42   upb::Arena a;
43 
44   upb_test_Box* foo = upb_test_Box_new(a.ptr());
45   upb_test_Box_set_first_tag(foo, upb_test_Z_BAR);
46 
47   EXPECT_EQ(R"({"firstTag":"Z_BAR"})", JsonEncode(foo, 0));
48   EXPECT_EQ(R"({"firstTag":1})",
49             JsonEncode(foo, upb_JsonEncode_FormatEnumsAsIntegers));
50 }
51 
52 // Encode a single optional negative enum.
TEST(JsonTest,EncodeNegativeEnum)53 TEST(JsonTest, EncodeNegativeEnum) {
54   upb::Arena a;
55 
56   upb_test_Box* foo = upb_test_Box_new(a.ptr());
57   upb_test_Box_set_last_tag(foo, upb_test_Z_BAZ);
58 
59   EXPECT_EQ(R"({"lastTag":"Z_BAZ"})", JsonEncode(foo, 0));
60   EXPECT_EQ(R"({"lastTag":-2})",
61             JsonEncode(foo, upb_JsonEncode_FormatEnumsAsIntegers));
62 }
63 
64 // Encode a single repeated enum.
TEST(JsonTest,EncodeRepeatedEnum)65 TEST(JsonTest, EncodeRepeatedEnum) {
66   upb::Arena a;
67 
68   upb_test_Box* foo = upb_test_Box_new(a.ptr());
69   upb_test_Box_add_more_tags(foo, upb_test_Z_BAT, a.ptr());
70 
71   EXPECT_EQ(R"({"moreTags":["Z_BAT"]})", JsonEncode(foo, 0));
72   EXPECT_EQ(R"({"moreTags":[13]})",
73             JsonEncode(foo, upb_JsonEncode_FormatEnumsAsIntegers));
74 }
75 
76 // Special case: encode null enum.
TEST(JsonTest,EncodeNullEnum)77 TEST(JsonTest, EncodeNullEnum) {
78   upb::Arena a;
79 
80   upb_test_Box* foo = upb_test_Box_new(a.ptr());
81   google_protobuf_Value_set_null_value(upb_test_Box_mutable_val(foo, a.ptr()),
82                                        google_protobuf_NULL_VALUE);
83 
84   EXPECT_EQ(R"({"val":null})", JsonEncode(foo, 0));
85   EXPECT_EQ(R"({"val":null})",
86             JsonEncode(foo, upb_JsonEncode_FormatEnumsAsIntegers));
87 }
88 
TEST(JsonTest,EncodeConflictJsonName)89 TEST(JsonTest, EncodeConflictJsonName) {
90   upb::Arena a;
91   upb_test_Box* box = upb_test_Box_new(a.ptr());
92   upb_test_Box_set_value(box, 2);
93   EXPECT_EQ(R"({"old_value":2})", JsonEncode(box, 0));
94 
95   upb_test_Box* new_box = upb_test_Box_new(a.ptr());
96   upb_test_Box_set_new_value(new_box, 2);
97   EXPECT_EQ(R"({"value":2})", JsonEncode(new_box, 0));
98 }
99