40 #include <google/protobuf/util/internal/testdata/maps.pb.h>
41 #include <google/protobuf/util/json_format.pb.h>
42 #include <google/protobuf/util/json_format_proto3.pb.h>
54 using proto3::TestAny;
55 using proto3::TestEnumValue;
56 using proto3::TestMap;
57 using proto3::TestMessage;
58 using proto3::TestOneof;
59 using proto_util_converter::testing::MapIn;
77 const JsonParseOptions&
options) {
82 return FromJson(json,
message, JsonParseOptions());
88 TEST_F(JsonUtilTest, TestWhitespaces) {
90 m.mutable_message_value();
97 " \"messageValue\": {}\n"
102 TEST_F(JsonUtilTest, TestDefaultValues) {
106 options.always_print_primitive_fields =
true;
108 "{\"boolValue\":false,"
110 "\"int64Value\":\"0\","
112 "\"uint64Value\":\"0\","
115 "\"stringValue\":\"\","
116 "\"bytesValue\":\"\","
117 "\"enumValue\":\"FOO\","
118 "\"repeatedBoolValue\":[],"
119 "\"repeatedInt32Value\":[],"
120 "\"repeatedInt64Value\":[],"
121 "\"repeatedUint32Value\":[],"
122 "\"repeatedUint64Value\":[],"
123 "\"repeatedFloatValue\":[],"
124 "\"repeatedDoubleValue\":[],"
125 "\"repeatedStringValue\":[],"
126 "\"repeatedBytesValue\":[],"
127 "\"repeatedEnumValue\":[],"
128 "\"repeatedMessageValue\":[]"
132 options.always_print_primitive_fields =
true;
133 m.set_string_value(
"i am a test string value");
134 m.set_bytes_value(
"i am a test bytes value");
136 "{\"boolValue\":false,"
138 "\"int64Value\":\"0\","
140 "\"uint64Value\":\"0\","
143 "\"stringValue\":\"i am a test string value\","
144 "\"bytesValue\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
145 "\"enumValue\":\"FOO\","
146 "\"repeatedBoolValue\":[],"
147 "\"repeatedInt32Value\":[],"
148 "\"repeatedInt64Value\":[],"
149 "\"repeatedUint32Value\":[],"
150 "\"repeatedUint64Value\":[],"
151 "\"repeatedFloatValue\":[],"
152 "\"repeatedDoubleValue\":[],"
153 "\"repeatedStringValue\":[],"
154 "\"repeatedBytesValue\":[],"
155 "\"repeatedEnumValue\":[],"
156 "\"repeatedMessageValue\":[]"
160 options.preserve_proto_field_names =
true;
161 m.set_string_value(
"i am a test string value");
162 m.set_bytes_value(
"i am a test bytes value");
164 "{\"bool_value\":false,"
166 "\"int64_value\":\"0\","
167 "\"uint32_value\":0,"
168 "\"uint64_value\":\"0\","
170 "\"double_value\":0,"
171 "\"string_value\":\"i am a test string value\","
172 "\"bytes_value\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
173 "\"enum_value\":\"FOO\","
174 "\"repeated_bool_value\":[],"
175 "\"repeated_int32_value\":[],"
176 "\"repeated_int64_value\":[],"
177 "\"repeated_uint32_value\":[],"
178 "\"repeated_uint64_value\":[],"
179 "\"repeated_float_value\":[],"
180 "\"repeated_double_value\":[],"
181 "\"repeated_string_value\":[],"
182 "\"repeated_bytes_value\":[],"
183 "\"repeated_enum_value\":[],"
184 "\"repeated_message_value\":[]"
189 TEST_F(JsonUtilTest, TestPreserveProtoFieldNames) {
191 m.mutable_message_value();
194 options.preserve_proto_field_names =
true;
198 TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) {
200 orig.set_enum_value(proto3::BAR);
201 orig.add_repeated_enum_value(proto3::FOO);
202 orig.add_repeated_enum_value(proto3::BAR);
204 JsonPrintOptions print_options;
205 print_options.always_print_enums_as_ints =
true;
207 std::string expected_json =
"{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}";
208 EXPECT_EQ(expected_json, ToJson(orig, print_options));
211 JsonParseOptions parse_options;
212 ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
214 EXPECT_EQ(proto3::BAR, parsed.enum_value());
215 EXPECT_EQ(2, parsed.repeated_enum_value_size());
216 EXPECT_EQ(proto3::FOO, parsed.repeated_enum_value(0));
217 EXPECT_EQ(proto3::BAR, parsed.repeated_enum_value(1));
220 TEST_F(JsonUtilTest, TestPrintEnumsAsIntsWithDefaultValue) {
223 orig.set_enum_value2(proto3::FOO);
224 orig.set_enum_value3(proto3::BAR);
226 JsonPrintOptions print_options;
227 print_options.always_print_enums_as_ints =
true;
228 print_options.always_print_primitive_fields =
true;
231 "{\"enumValue1\":0,\"enumValue2\":0,\"enumValue3\":1}";
232 EXPECT_EQ(expected_json, ToJson(orig, print_options));
234 TestEnumValue parsed;
235 JsonParseOptions parse_options;
236 ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
238 EXPECT_EQ(proto3::FOO, parsed.enum_value1());
239 EXPECT_EQ(proto3::FOO, parsed.enum_value2());
240 EXPECT_EQ(proto3::BAR, parsed.enum_value3());
248 " \"int32Value\": 1024,\n"
249 " \"repeatedInt32Value\": [1, 2],\n"
250 " \"messageValue\": {\n"
253 " \"repeatedMessageValue\": [\n"
254 " {\"value\": 40}, {\"value\": 96}\n"
265 ASSERT_EQ(2,
m.repeated_message_value_size());
266 EXPECT_EQ(40,
m.repeated_message_value(0).value());
267 EXPECT_EQ(96,
m.repeated_message_value(1).value());
272 (*
message.mutable_string_map())[
"hello"] = 1234;
273 JsonPrintOptions print_options;
274 JsonParseOptions parse_options;
275 EXPECT_EQ(
"{\"stringMap\":{\"hello\":1234}}", ToJson(
message, print_options));
281 TEST_F(JsonUtilTest, ParsePrimitiveMapIn) {
283 JsonPrintOptions print_options;
284 print_options.always_print_primitive_fields =
true;
285 JsonParseOptions parse_options;
286 EXPECT_EQ(
"{\"other\":\"\",\"things\":[],\"mapInput\":{},\"mapAny\":{}}",
287 ToJson(
message, print_options));
293 TEST_F(JsonUtilTest, PrintPrimitiveOneof) {
296 options.always_print_primitive_fields =
true;
297 message.mutable_oneof_message_value();
300 message.set_oneof_int32_value(1);
304 TEST_F(JsonUtilTest, TestParseIgnoreUnknownFields) {
307 options.ignore_unknown_fields =
true;
311 TEST_F(JsonUtilTest, TestParseErrors) {
320 TEST_F(JsonUtilTest, TestDynamicMessage) {
324 " \"int32Value\": 1024,\n"
325 " \"repeatedInt32Value\": [1, 2],\n"
326 " \"messageValue\": {\n"
329 " \"repeatedMessageValue\": [\n"
330 " {\"value\": 40}, {\"value\": 96}\n"
338 DynamicMessageFactory factory;
339 std::unique_ptr<Message>
message(
340 factory.GetPrototype(
pool.FindMessageTypeByName(
"proto3.TestMessage"))
345 TestMessage generated;
347 EXPECT_EQ(1024, generated.int32_value());
348 ASSERT_EQ(2, generated.repeated_int32_value_size());
349 EXPECT_EQ(1, generated.repeated_int32_value(0));
350 EXPECT_EQ(2, generated.repeated_int32_value(1));
351 EXPECT_EQ(2048, generated.message_value().value());
352 ASSERT_EQ(2, generated.repeated_message_value_size());
353 EXPECT_EQ(40, generated.repeated_message_value(0).value());
354 EXPECT_EQ(96, generated.repeated_message_value(1).value());
360 TEST_F(JsonUtilTest, TestParsingUnknownAnyFields) {
364 " \"@type\": \"type.googleapis.com/proto3.TestMessage\",\n"
365 " \"unknown_field\": \"UNKNOWN_VALUE\",\n"
366 " \"string_value\": \"expected_value\"\n"
374 options.ignore_unknown_fields =
true;
379 EXPECT_EQ(
"expected_value", t.string_value());
382 TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto2) {
385 " \"a\": \"UNKNOWN_VALUE\"\n"
387 protobuf_unittest::TestNumbers
m;
391 options.ignore_unknown_fields =
true;
396 TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto3) {
403 " \"enum_value\":\"UNKNOWN_VALUE\"\n"
405 m.set_enum_value(proto3::BAR);
409 options.ignore_unknown_fields =
true;
418 " \"enum_value\":12345\n"
420 m.set_enum_value(proto3::BAR);
424 options.ignore_unknown_fields =
true;
435 " \"enum_value\":{}\n"
437 options.ignore_unknown_fields =
true;
439 options.ignore_unknown_fields =
false;
448 " \"enum_value\":[]\n"
451 options.ignore_unknown_fields =
true;
456 TEST_F(JsonUtilTest, TestParsingEnumIgnoreCase) {
462 " \"enum_value\":\"bar\"\n"
464 m.set_enum_value(proto3::FOO);
471 options.case_insensitive_enum_parsing =
false;
474 " \"enum_value\":\"bar\"\n"
476 m.set_enum_value(proto3::FOO);
482 options.case_insensitive_enum_parsing =
true;
485 " \"enum_value\":\"bar\"\n"
487 m.set_enum_value(proto3::FOO);
493 typedef std::pair<char*, int> Segment;
495 class SegmentedZeroCopyOutputStream :
public io::ZeroCopyOutputStream {
497 explicit SegmentedZeroCopyOutputStream(std::list<Segment> segments)
514 virtual void BackUp(
int length) {
533 TEST(ZeroCopyStreamByteSinkTest, TestAllInputOutputPatterns) {
534 static const int kOutputBufferLength = 10;
537 static const int kSkippedPatternCount = 7;
539 char buffer[kOutputBufferLength];
540 for (
int split_pattern = 0; split_pattern < (1 << (kOutputBufferLength - 1));
541 split_pattern += kSkippedPatternCount) {
543 std::list<Segment> segments;
544 int segment_start = 0;
545 for (
int i = 0;
i < kOutputBufferLength - 1; ++
i) {
546 if (split_pattern & (1 <<
i)) {
548 Segment(
buffer + segment_start,
i - segment_start + 1));
549 segment_start =
i + 1;
553 Segment(
buffer + segment_start, kOutputBufferLength - segment_start));
557 for (
int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
558 input_pattern += kSkippedPatternCount) {
561 SegmentedZeroCopyOutputStream output_stream(segments);
562 internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
564 for (
int j = 0; j < input_data.length() - 1; ++j) {
565 if (input_pattern & (1 << j)) {
566 byte_sink.Append(&input_data[
start], j -
start + 1);
570 byte_sink.Append(&input_data[
start], input_data.length() -
start);
576 input_data =
"012345678";
577 for (
int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
578 input_pattern += kSkippedPatternCount) {
581 SegmentedZeroCopyOutputStream output_stream(segments);
582 internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
584 for (
int j = 0; j < input_data.length() - 1; ++j) {
585 if (input_pattern & (1 << j)) {
586 byte_sink.Append(&input_data[
start], j -
start + 1);
590 byte_sink.Append(&input_data[
start], input_data.length() -
start);
598 input_data =
"0123456789A";
599 for (
int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
600 input_pattern += kSkippedPatternCount) {
603 SegmentedZeroCopyOutputStream output_stream(segments);
604 internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
606 for (
int j = 0; j < input_data.length() - 1; ++j) {
607 if (input_pattern & (1 << j)) {
608 byte_sink.Append(&input_data[
start], j -
start + 1);
612 byte_sink.Append(&input_data[
start], input_data.length() -
start);
614 EXPECT_EQ(input_data.substr(0, kOutputBufferLength),
620 TEST_F(JsonUtilTest, TestWrongJsonInput) {
621 const char json[] =
"{\"unknown_field\":\"some_value\"}";
622 io::ArrayInputStream input_stream(json, strlen(json));
623 char proto_buffer[10000];
624 io::ArrayOutputStream output_stream(proto_buffer,
sizeof(proto_buffer));
630 &input_stream, &output_stream);
639 TEST_F(JsonUtilTest, HtmlEscape) {
641 m.set_string_value(
"</script>");