blob: fc0605bfc4a20bcd9fc81c3a4b1b20478fc52a14 [file] [log] [blame]
Josh Haberman35a1cc72015-04-01 17:23:48 -07001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
Josh Haberman35a1cc72015-04-01 17:23:48 -070031#include <stdarg.h>
Josh Haberman35a1cc72015-04-01 17:23:48 -070032#include <string>
33
34#include "conformance.pb.h"
Josh Haberman4e63b522015-04-14 13:45:39 -070035#include "conformance_test.h"
Josh Haberman35a1cc72015-04-01 17:23:48 -070036#include <google/protobuf/stubs/common.h>
Josh Haberman4e63b522015-04-14 13:45:39 -070037#include <google/protobuf/stubs/stringprintf.h>
Josh Habermanb0500b32015-07-10 16:36:59 -070038#include <google/protobuf/text_format.h>
39#include <google/protobuf/util/json_util.h>
Feng Xiaoe841bac2015-12-11 17:09:20 -080040#include <google/protobuf/util/field_comparator.h>
Josh Habermanb0500b32015-07-10 16:36:59 -070041#include <google/protobuf/util/message_differencer.h>
42#include <google/protobuf/util/type_resolver_util.h>
Josh Haberman35a1cc72015-04-01 17:23:48 -070043#include <google/protobuf/wire_format_lite.h>
44
Feng Xiaoa0cecfd2015-12-14 18:33:38 -080045#include "third_party/jsoncpp/json.h"
Feng Xiaoe841bac2015-12-11 17:09:20 -080046
Josh Haberman35a1cc72015-04-01 17:23:48 -070047using conformance::ConformanceRequest;
48using conformance::ConformanceResponse;
49using conformance::TestAllTypes;
Josh Habermanb0500b32015-07-10 16:36:59 -070050using conformance::WireFormat;
Josh Haberman35a1cc72015-04-01 17:23:48 -070051using google::protobuf::Descriptor;
52using google::protobuf::FieldDescriptor;
53using google::protobuf::internal::WireFormatLite;
Josh Habermanb0500b32015-07-10 16:36:59 -070054using google::protobuf::TextFormat;
Feng Xiaoe841bac2015-12-11 17:09:20 -080055using google::protobuf::util::DefaultFieldComparator;
Josh Habermanb0500b32015-07-10 16:36:59 -070056using google::protobuf::util::JsonToBinaryString;
57using google::protobuf::util::MessageDifferencer;
58using google::protobuf::util::NewTypeResolverForDescriptorPool;
59using google::protobuf::util::Status;
Josh Haberman35a1cc72015-04-01 17:23:48 -070060using std::string;
61
Josh Haberman4e63b522015-04-14 13:45:39 -070062namespace {
Josh Haberman35a1cc72015-04-01 17:23:48 -070063
Josh Habermanb0500b32015-07-10 16:36:59 -070064static const char kTypeUrlPrefix[] = "type.googleapis.com";
65
66static string GetTypeUrl(const Descriptor* message) {
67 return string(kTypeUrlPrefix) + "/" + message->full_name();
68}
69
Josh Haberman35a1cc72015-04-01 17:23:48 -070070/* Routines for building arbitrary protos *************************************/
71
72// We would use CodedOutputStream except that we want more freedom to build
73// arbitrary protos (even invalid ones).
74
75const string empty;
76
77string cat(const string& a, const string& b,
78 const string& c = empty,
79 const string& d = empty,
80 const string& e = empty,
81 const string& f = empty,
82 const string& g = empty,
83 const string& h = empty,
84 const string& i = empty,
85 const string& j = empty,
86 const string& k = empty,
87 const string& l = empty) {
88 string ret;
89 ret.reserve(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() +
90 g.size() + h.size() + i.size() + j.size() + k.size() + l.size());
91 ret.append(a);
92 ret.append(b);
93 ret.append(c);
94 ret.append(d);
95 ret.append(e);
96 ret.append(f);
97 ret.append(g);
98 ret.append(h);
99 ret.append(i);
100 ret.append(j);
101 ret.append(k);
102 ret.append(l);
103 return ret;
104}
105
106// The maximum number of bytes that it takes to encode a 64-bit varint.
107#define VARINT_MAX_LEN 10
108
109size_t vencode64(uint64_t val, char *buf) {
110 if (val == 0) { buf[0] = 0; return 1; }
111 size_t i = 0;
112 while (val) {
113 uint8_t byte = val & 0x7fU;
114 val >>= 7;
115 if (val) byte |= 0x80U;
116 buf[i++] = byte;
117 }
118 return i;
119}
120
121string varint(uint64_t x) {
122 char buf[VARINT_MAX_LEN];
123 size_t len = vencode64(x, buf);
124 return string(buf, len);
125}
126
127// TODO: proper byte-swapping for big-endian machines.
128string fixed32(void *data) { return string(static_cast<char*>(data), 4); }
129string fixed64(void *data) { return string(static_cast<char*>(data), 8); }
130
131string delim(const string& buf) { return cat(varint(buf.size()), buf); }
132string uint32(uint32_t u32) { return fixed32(&u32); }
133string uint64(uint64_t u64) { return fixed64(&u64); }
134string flt(float f) { return fixed32(&f); }
135string dbl(double d) { return fixed64(&d); }
136string zz32(int32_t x) { return varint(WireFormatLite::ZigZagEncode32(x)); }
137string zz64(int64_t x) { return varint(WireFormatLite::ZigZagEncode64(x)); }
138
139string tag(uint32_t fieldnum, char wire_type) {
140 return varint((fieldnum << 3) | wire_type);
141}
142
143string submsg(uint32_t fn, const string& buf) {
144 return cat( tag(fn, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(buf) );
145}
146
147#define UNKNOWN_FIELD 666
148
Josh Habermand2b67382015-06-03 12:04:35 -0700149uint32_t GetFieldNumberForType(FieldDescriptor::Type type, bool repeated) {
Josh Haberman35a1cc72015-04-01 17:23:48 -0700150 const Descriptor* d = TestAllTypes().GetDescriptor();
151 for (int i = 0; i < d->field_count(); i++) {
152 const FieldDescriptor* f = d->field(i);
Josh Habermand2b67382015-06-03 12:04:35 -0700153 if (f->type() == type && f->is_repeated() == repeated) {
Josh Haberman35a1cc72015-04-01 17:23:48 -0700154 return f->number();
155 }
156 }
157 GOOGLE_LOG(FATAL) << "Couldn't find field with type " << (int)type;
158 return 0;
159}
160
Josh Habermand2b67382015-06-03 12:04:35 -0700161string UpperCase(string str) {
162 for (int i = 0; i < str.size(); i++) {
163 str[i] = toupper(str[i]);
164 }
165 return str;
166}
167
Josh Haberman4e63b522015-04-14 13:45:39 -0700168} // anonymous namespace
169
170namespace google {
171namespace protobuf {
172
Josh Habermand2b67382015-06-03 12:04:35 -0700173void ConformanceTestSuite::ReportSuccess(const string& test_name) {
174 if (expected_to_fail_.erase(test_name) != 0) {
175 StringAppendF(&output_,
176 "ERROR: test %s is in the failure list, but test succeeded. "
177 "Remove it from the failure list.\n",
178 test_name.c_str());
179 unexpected_succeeding_tests_.insert(test_name);
180 }
Josh Haberman4e63b522015-04-14 13:45:39 -0700181 successes_++;
182}
183
Josh Habermand2b67382015-06-03 12:04:35 -0700184void ConformanceTestSuite::ReportFailure(const string& test_name,
Josh Habermanb0500b32015-07-10 16:36:59 -0700185 const ConformanceRequest& request,
186 const ConformanceResponse& response,
Josh Habermand2b67382015-06-03 12:04:35 -0700187 const char* fmt, ...) {
188 if (expected_to_fail_.erase(test_name) == 1) {
Josh Habermanb0500b32015-07-10 16:36:59 -0700189 expected_failures_++;
190 if (!verbose_)
191 return;
Josh Habermand2b67382015-06-03 12:04:35 -0700192 } else {
Josh Haberman23bf3b52015-06-04 15:04:00 -0700193 StringAppendF(&output_, "ERROR, test=%s: ", test_name.c_str());
Josh Habermand2b67382015-06-03 12:04:35 -0700194 unexpected_failing_tests_.insert(test_name);
195 }
Josh Haberman4e63b522015-04-14 13:45:39 -0700196 va_list args;
197 va_start(args, fmt);
198 StringAppendV(&output_, fmt, args);
199 va_end(args);
Josh Habermanb0500b32015-07-10 16:36:59 -0700200 StringAppendF(&output_, " request=%s, response=%s\n",
201 request.ShortDebugString().c_str(),
202 response.ShortDebugString().c_str());
203}
204
205void ConformanceTestSuite::ReportSkip(const string& test_name,
206 const ConformanceRequest& request,
207 const ConformanceResponse& response) {
208 if (verbose_) {
209 StringAppendF(&output_, "SKIPPED, test=%s request=%s, response=%s\n",
210 test_name.c_str(), request.ShortDebugString().c_str(),
211 response.ShortDebugString().c_str());
212 }
213 skipped_.insert(test_name);
Josh Haberman4e63b522015-04-14 13:45:39 -0700214}
215
Josh Haberman23bf3b52015-06-04 15:04:00 -0700216void ConformanceTestSuite::RunTest(const string& test_name,
217 const ConformanceRequest& request,
Josh Haberman4e63b522015-04-14 13:45:39 -0700218 ConformanceResponse* response) {
Josh Haberman23bf3b52015-06-04 15:04:00 -0700219 if (test_names_.insert(test_name).second == false) {
220 GOOGLE_LOG(FATAL) << "Duplicated test name: " << test_name;
Josh Habermand2b67382015-06-03 12:04:35 -0700221 }
222
Josh Haberman4e63b522015-04-14 13:45:39 -0700223 string serialized_request;
224 string serialized_response;
225 request.SerializeToString(&serialized_request);
226
Feng Xiaoe841bac2015-12-11 17:09:20 -0800227 runner_->RunTest(test_name, serialized_request, &serialized_response);
Josh Haberman4e63b522015-04-14 13:45:39 -0700228
229 if (!response->ParseFromString(serialized_response)) {
230 response->Clear();
231 response->set_runtime_error("response proto could not be parsed.");
232 }
233
234 if (verbose_) {
Josh Haberman23bf3b52015-06-04 15:04:00 -0700235 StringAppendF(&output_, "conformance test: name=%s, request=%s, response=%s\n",
236 test_name.c_str(),
Josh Haberman4e63b522015-04-14 13:45:39 -0700237 request.ShortDebugString().c_str(),
238 response->ShortDebugString().c_str());
239 }
240}
241
Josh Habermanb0500b32015-07-10 16:36:59 -0700242void ConformanceTestSuite::RunValidInputTest(
243 const string& test_name, const string& input, WireFormat input_format,
244 const string& equivalent_text_format, WireFormat requested_output) {
245 TestAllTypes reference_message;
246 GOOGLE_CHECK(
Feng Xiaoe841bac2015-12-11 17:09:20 -0800247 TextFormat::ParseFromString(equivalent_text_format, &reference_message))
248 << "Failed to parse data for test case: " << test_name
249 << ", data: " << equivalent_text_format;
Josh Habermanb0500b32015-07-10 16:36:59 -0700250
251 ConformanceRequest request;
252 ConformanceResponse response;
253
254 switch (input_format) {
255 case conformance::PROTOBUF:
256 request.set_protobuf_payload(input);
257 break;
258
259 case conformance::JSON:
260 request.set_json_payload(input);
261 break;
262
Feng Xiaoe841bac2015-12-11 17:09:20 -0800263 default:
Josh Habermanb0500b32015-07-10 16:36:59 -0700264 GOOGLE_LOG(FATAL) << "Unspecified input format";
Josh Habermanb0500b32015-07-10 16:36:59 -0700265 }
266
267 request.set_requested_output_format(requested_output);
268
269 RunTest(test_name, request, &response);
270
271 TestAllTypes test_message;
272
273 switch (response.result_case()) {
274 case ConformanceResponse::kParseError:
275 case ConformanceResponse::kRuntimeError:
Feng Xiaoe841bac2015-12-11 17:09:20 -0800276 case ConformanceResponse::kSerializeError:
Josh Habermanb0500b32015-07-10 16:36:59 -0700277 ReportFailure(test_name, request, response,
Feng Xiaoe841bac2015-12-11 17:09:20 -0800278 "Failed to parse JSON input or produce JSON output.");
Josh Habermanb0500b32015-07-10 16:36:59 -0700279 return;
280
281 case ConformanceResponse::kSkipped:
282 ReportSkip(test_name, request, response);
283 return;
284
285 case ConformanceResponse::kJsonPayload: {
286 if (requested_output != conformance::JSON) {
287 ReportFailure(
288 test_name, request, response,
289 "Test was asked for protobuf output but provided JSON instead.");
290 return;
291 }
292 string binary_protobuf;
293 Status status =
294 JsonToBinaryString(type_resolver_.get(), type_url_,
295 response.json_payload(), &binary_protobuf);
296 if (!status.ok()) {
297 ReportFailure(test_name, request, response,
298 "JSON output we received from test was unparseable.");
299 return;
300 }
301
Josh Habermane891c292015-12-30 16:03:49 -0800302 if (!test_message.ParseFromString(binary_protobuf)) {
303 ReportFailure(test_name, request, response,
304 "INTERNAL ERROR: internal JSON->protobuf transcode "
305 "yielded unparseable proto.");
306 return;
307 }
308
Josh Habermanb0500b32015-07-10 16:36:59 -0700309 break;
310 }
311
312 case ConformanceResponse::kProtobufPayload: {
313 if (requested_output != conformance::PROTOBUF) {
314 ReportFailure(
315 test_name, request, response,
316 "Test was asked for JSON output but provided protobuf instead.");
317 return;
318 }
319
320 if (!test_message.ParseFromString(response.protobuf_payload())) {
321 ReportFailure(test_name, request, response,
322 "Protobuf output we received from test was unparseable.");
323 return;
324 }
325
326 break;
327 }
Feng Xiaoe841bac2015-12-11 17:09:20 -0800328
329 default:
330 GOOGLE_LOG(FATAL) << test_name << ": unknown payload type: "
331 << response.result_case();
Josh Habermanb0500b32015-07-10 16:36:59 -0700332 }
333
334 MessageDifferencer differencer;
Feng Xiaoe841bac2015-12-11 17:09:20 -0800335 DefaultFieldComparator field_comparator;
336 field_comparator.set_treat_nan_as_equal(true);
337 differencer.set_field_comparator(&field_comparator);
Josh Habermanb0500b32015-07-10 16:36:59 -0700338 string differences;
339 differencer.ReportDifferencesToString(&differences);
340
Feng Xiaoe841bac2015-12-11 17:09:20 -0800341 if (differencer.Compare(reference_message, test_message)) {
Josh Habermanb0500b32015-07-10 16:36:59 -0700342 ReportSuccess(test_name);
343 } else {
344 ReportFailure(test_name, request, response,
345 "Output was not equivalent to reference message: %s.",
346 differences.c_str());
347 }
348}
349
Josh Habermand2b67382015-06-03 12:04:35 -0700350// Expect that this precise protobuf will cause a parse error.
351void ConformanceTestSuite::ExpectParseFailureForProto(
352 const string& proto, const string& test_name) {
Josh Haberman4e63b522015-04-14 13:45:39 -0700353 ConformanceRequest request;
354 ConformanceResponse response;
355 request.set_protobuf_payload(proto);
Josh Habermanb0500b32015-07-10 16:36:59 -0700356 string effective_test_name = "ProtobufInput." + test_name;
Josh Haberman4e63b522015-04-14 13:45:39 -0700357
358 // We don't expect output, but if the program erroneously accepts the protobuf
359 // we let it send its response as this. We must not leave it unspecified.
Josh Habermanb0500b32015-07-10 16:36:59 -0700360 request.set_requested_output_format(conformance::PROTOBUF);
Josh Haberman4e63b522015-04-14 13:45:39 -0700361
Josh Habermanb0500b32015-07-10 16:36:59 -0700362 RunTest(effective_test_name, request, &response);
Josh Haberman4e63b522015-04-14 13:45:39 -0700363 if (response.result_case() == ConformanceResponse::kParseError) {
Josh Habermanb0500b32015-07-10 16:36:59 -0700364 ReportSuccess(effective_test_name);
Thomas Van Lentendf4e4d82016-01-05 16:31:40 -0500365 } else if (response.result_case() == ConformanceResponse::kSkipped) {
366 ReportSkip(effective_test_name, request, response);
Josh Haberman4e63b522015-04-14 13:45:39 -0700367 } else {
Josh Habermanb0500b32015-07-10 16:36:59 -0700368 ReportFailure(effective_test_name, request, response,
369 "Should have failed to parse, but didn't.");
Josh Haberman4e63b522015-04-14 13:45:39 -0700370 }
371}
372
Josh Haberman4e63b522015-04-14 13:45:39 -0700373// Expect that this protobuf will cause a parse error, even if it is followed
374// by valid protobuf data. We can try running this twice: once with this
375// data verbatim and once with this data followed by some valid data.
376//
377// TODO(haberman): implement the second of these.
Josh Habermand2b67382015-06-03 12:04:35 -0700378void ConformanceTestSuite::ExpectHardParseFailureForProto(
379 const string& proto, const string& test_name) {
380 return ExpectParseFailureForProto(proto, test_name);
381}
Josh Haberman4e63b522015-04-14 13:45:39 -0700382
Josh Habermanb0500b32015-07-10 16:36:59 -0700383void ConformanceTestSuite::RunValidJsonTest(
384 const string& test_name, const string& input_json,
385 const string& equivalent_text_format) {
Feng Xiaoe841bac2015-12-11 17:09:20 -0800386 RunValidInputTest("JsonInput." + test_name + ".ProtobufOutput", input_json,
Josh Habermanb0500b32015-07-10 16:36:59 -0700387 conformance::JSON, equivalent_text_format,
388 conformance::PROTOBUF);
Feng Xiaoe841bac2015-12-11 17:09:20 -0800389 RunValidInputTest("JsonInput." + test_name + ".JsonOutput", input_json,
390 conformance::JSON, equivalent_text_format,
391 conformance::JSON);
392}
393
394void ConformanceTestSuite::RunValidJsonTestWithProtobufInput(
395 const string& test_name, const TestAllTypes& input,
396 const string& equivalent_text_format) {
397 RunValidInputTest("ProtobufInput." + test_name + ".JsonOutput",
398 input.SerializeAsString(), conformance::PROTOBUF,
Josh Habermanb0500b32015-07-10 16:36:59 -0700399 equivalent_text_format, conformance::JSON);
400}
401
Feng Xiaoe841bac2015-12-11 17:09:20 -0800402// According to proto3 JSON specification, JSON serializers follow more strict
403// rules than parsers (e.g., a serializer must serialize int32 values as JSON
404// numbers while the parser is allowed to accept them as JSON strings). This
405// method allows strict checking on a proto3 JSON serializer by inspecting
406// the JSON output directly.
407void ConformanceTestSuite::RunValidJsonTestWithValidator(
408 const string& test_name, const string& input_json,
409 const Validator& validator) {
410 ConformanceRequest request;
411 ConformanceResponse response;
412 request.set_json_payload(input_json);
413 request.set_requested_output_format(conformance::JSON);
414
415 string effective_test_name = "JsonInput." + test_name + ".Validator";
416
417 RunTest(effective_test_name, request, &response);
418
Thomas Van Lentendf4e4d82016-01-05 16:31:40 -0500419 if (response.result_case() == ConformanceResponse::kSkipped) {
420 ReportSkip(effective_test_name, request, response);
421 return;
422 }
423
Feng Xiaoe841bac2015-12-11 17:09:20 -0800424 if (response.result_case() != ConformanceResponse::kJsonPayload) {
425 ReportFailure(effective_test_name, request, response,
426 "Expected JSON payload but got type %d.",
427 response.result_case());
428 return;
429 }
430 Json::Reader reader;
431 Json::Value value;
432 if (!reader.parse(response.json_payload(), value)) {
433 ReportFailure(effective_test_name, request, response,
434 "JSON payload cannot be parsed as valid JSON: %s",
435 reader.getFormattedErrorMessages().c_str());
436 return;
437 }
438 if (!validator(value)) {
439 ReportFailure(effective_test_name, request, response,
440 "JSON payload validation failed.");
441 return;
442 }
443 ReportSuccess(effective_test_name);
444}
445
446void ConformanceTestSuite::ExpectParseFailureForJson(
447 const string& test_name, const string& input_json) {
448 ConformanceRequest request;
449 ConformanceResponse response;
450 request.set_json_payload(input_json);
451 string effective_test_name = "JsonInput." + test_name;
452
453 // We don't expect output, but if the program erroneously accepts the protobuf
454 // we let it send its response as this. We must not leave it unspecified.
455 request.set_requested_output_format(conformance::JSON);
456
457 RunTest(effective_test_name, request, &response);
458 if (response.result_case() == ConformanceResponse::kParseError) {
459 ReportSuccess(effective_test_name);
Thomas Van Lentendf4e4d82016-01-05 16:31:40 -0500460 } else if (response.result_case() == ConformanceResponse::kSkipped) {
461 ReportSkip(effective_test_name, request, response);
Feng Xiaoe841bac2015-12-11 17:09:20 -0800462 } else {
463 ReportFailure(effective_test_name, request, response,
464 "Should have failed to parse, but didn't.");
465 }
466}
467
468void ConformanceTestSuite::ExpectSerializeFailureForJson(
469 const string& test_name, const string& text_format) {
470 TestAllTypes payload_message;
471 GOOGLE_CHECK(
472 TextFormat::ParseFromString(text_format, &payload_message))
473 << "Failed to parse: " << text_format;
474
475 ConformanceRequest request;
476 ConformanceResponse response;
477 request.set_protobuf_payload(payload_message.SerializeAsString());
478 string effective_test_name = test_name + ".JsonOutput";
479 request.set_requested_output_format(conformance::JSON);
480
481 RunTest(effective_test_name, request, &response);
482 if (response.result_case() == ConformanceResponse::kSerializeError) {
483 ReportSuccess(effective_test_name);
Thomas Van Lentendf4e4d82016-01-05 16:31:40 -0500484 } else if (response.result_case() == ConformanceResponse::kSkipped) {
485 ReportSkip(effective_test_name, request, response);
Feng Xiaoe841bac2015-12-11 17:09:20 -0800486 } else {
487 ReportFailure(effective_test_name, request, response,
488 "Should have failed to serialize, but didn't.");
489 }
490}
491
Josh Habermand2b67382015-06-03 12:04:35 -0700492void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
Josh Haberman35a1cc72015-04-01 17:23:48 -0700493 // Incomplete values for each wire type.
494 static const string incompletes[6] = {
495 string("\x80"), // VARINT
496 string("abcdefg"), // 64BIT
497 string("\x80"), // DELIMITED (partial length)
498 string(), // START_GROUP (no value required)
499 string(), // END_GROUP (no value required)
500 string("abc") // 32BIT
501 };
502
503 uint32_t fieldnum = GetFieldNumberForType(type, false);
504 uint32_t rep_fieldnum = GetFieldNumberForType(type, true);
Josh Habermand2b67382015-06-03 12:04:35 -0700505 WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
506 static_cast<WireFormatLite::FieldType>(type));
Josh Haberman35a1cc72015-04-01 17:23:48 -0700507 const string& incomplete = incompletes[wire_type];
Josh Habermand2b67382015-06-03 12:04:35 -0700508 const string type_name =
509 UpperCase(string(".") + FieldDescriptor::TypeName(type));
Josh Haberman35a1cc72015-04-01 17:23:48 -0700510
Josh Haberman35a1cc72015-04-01 17:23:48 -0700511 ExpectParseFailureForProto(
Josh Habermand2b67382015-06-03 12:04:35 -0700512 tag(fieldnum, wire_type),
513 "PrematureEofBeforeKnownNonRepeatedValue" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700514
Josh Haberman35a1cc72015-04-01 17:23:48 -0700515 ExpectParseFailureForProto(
Josh Habermand2b67382015-06-03 12:04:35 -0700516 tag(rep_fieldnum, wire_type),
517 "PrematureEofBeforeKnownRepeatedValue" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700518
Josh Haberman35a1cc72015-04-01 17:23:48 -0700519 ExpectParseFailureForProto(
Josh Habermand2b67382015-06-03 12:04:35 -0700520 tag(UNKNOWN_FIELD, wire_type),
521 "PrematureEofBeforeUnknownValue" + type_name);
522
523 ExpectParseFailureForProto(
524 cat( tag(fieldnum, wire_type), incomplete ),
525 "PrematureEofInsideKnownNonRepeatedValue" + type_name);
526
527 ExpectParseFailureForProto(
528 cat( tag(rep_fieldnum, wire_type), incomplete ),
529 "PrematureEofInsideKnownRepeatedValue" + type_name);
530
531 ExpectParseFailureForProto(
532 cat( tag(UNKNOWN_FIELD, wire_type), incomplete ),
533 "PrematureEofInsideUnknownValue" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700534
535 if (wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
Josh Haberman35a1cc72015-04-01 17:23:48 -0700536 ExpectParseFailureForProto(
Josh Habermand2b67382015-06-03 12:04:35 -0700537 cat( tag(fieldnum, wire_type), varint(1) ),
538 "PrematureEofInDelimitedDataForKnownNonRepeatedValue" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700539
Josh Haberman35a1cc72015-04-01 17:23:48 -0700540 ExpectParseFailureForProto(
Josh Habermand2b67382015-06-03 12:04:35 -0700541 cat( tag(rep_fieldnum, wire_type), varint(1) ),
542 "PrematureEofInDelimitedDataForKnownRepeatedValue" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700543
544 // EOF in the middle of delimited data for unknown value.
545 ExpectParseFailureForProto(
Josh Habermand2b67382015-06-03 12:04:35 -0700546 cat( tag(UNKNOWN_FIELD, wire_type), varint(1) ),
547 "PrematureEofInDelimitedDataForUnknownValue" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700548
Josh Habermand2b67382015-06-03 12:04:35 -0700549 if (type == FieldDescriptor::TYPE_MESSAGE) {
Josh Haberman35a1cc72015-04-01 17:23:48 -0700550 // Submessage ends in the middle of a value.
551 string incomplete_submsg =
552 cat( tag(WireFormatLite::TYPE_INT32, WireFormatLite::WIRETYPE_VARINT),
553 incompletes[WireFormatLite::WIRETYPE_VARINT] );
554 ExpectHardParseFailureForProto(
555 cat( tag(fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
556 varint(incomplete_submsg.size()),
Josh Habermand2b67382015-06-03 12:04:35 -0700557 incomplete_submsg ),
558 "PrematureEofInSubmessageValue" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700559 }
Josh Habermand2b67382015-06-03 12:04:35 -0700560 } else if (type != FieldDescriptor::TYPE_GROUP) {
Josh Haberman35a1cc72015-04-01 17:23:48 -0700561 // Non-delimited, non-group: eligible for packing.
562
563 // Packed region ends in the middle of a value.
564 ExpectHardParseFailureForProto(
565 cat( tag(rep_fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
566 varint(incomplete.size()),
Josh Habermand2b67382015-06-03 12:04:35 -0700567 incomplete ),
568 "PrematureEofInPackedFieldValue" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700569
570 // EOF in the middle of packed region.
571 ExpectParseFailureForProto(
572 cat( tag(rep_fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
Josh Habermand2b67382015-06-03 12:04:35 -0700573 varint(1) ),
574 "PrematureEofInPackedField" + type_name);
Josh Haberman35a1cc72015-04-01 17:23:48 -0700575 }
576}
577
Josh Habermand2b67382015-06-03 12:04:35 -0700578void ConformanceTestSuite::SetFailureList(const vector<string>& failure_list) {
579 expected_to_fail_.clear();
580 std::copy(failure_list.begin(), failure_list.end(),
581 std::inserter(expected_to_fail_, expected_to_fail_.end()));
582}
583
584bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
585 const char* msg) {
586 if (set_to_check.empty()) {
587 return true;
588 } else {
589 StringAppendF(&output_, "\n");
Josh Habermanb0500b32015-07-10 16:36:59 -0700590 StringAppendF(&output_, "%s:\n", msg);
Josh Habermand2b67382015-06-03 12:04:35 -0700591 for (set<string>::const_iterator iter = set_to_check.begin();
592 iter != set_to_check.end(); ++iter) {
Josh Habermanb0500b32015-07-10 16:36:59 -0700593 StringAppendF(&output_, " %s\n", iter->c_str());
Josh Habermand2b67382015-06-03 12:04:35 -0700594 }
Josh Habermanb0500b32015-07-10 16:36:59 -0700595 StringAppendF(&output_, "\n");
Josh Habermand2b67382015-06-03 12:04:35 -0700596 return false;
597 }
598}
599
600bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
Josh Haberman4e63b522015-04-14 13:45:39 -0700601 std::string* output) {
602 runner_ = runner;
Josh Haberman4e63b522015-04-14 13:45:39 -0700603 successes_ = 0;
Josh Habermanb0500b32015-07-10 16:36:59 -0700604 expected_failures_ = 0;
605 skipped_.clear();
Josh Habermand2b67382015-06-03 12:04:35 -0700606 test_names_.clear();
607 unexpected_failing_tests_.clear();
608 unexpected_succeeding_tests_.clear();
Josh Habermanb0500b32015-07-10 16:36:59 -0700609 type_resolver_.reset(NewTypeResolverForDescriptorPool(
610 kTypeUrlPrefix, DescriptorPool::generated_pool()));
611 type_url_ = GetTypeUrl(TestAllTypes::descriptor());
612
613 output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
Josh Haberman35a1cc72015-04-01 17:23:48 -0700614
615 for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) {
Bo Yang5db21732015-05-21 14:28:59 -0700616 if (i == FieldDescriptor::TYPE_GROUP) continue;
Josh Habermand2b67382015-06-03 12:04:35 -0700617 TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
Josh Haberman35a1cc72015-04-01 17:23:48 -0700618 }
619
Josh Habermanb0500b32015-07-10 16:36:59 -0700620 RunValidJsonTest("HelloWorld", "{\"optionalString\":\"Hello, World!\"}",
621 "optional_string: 'Hello, World!'");
Josh Haberman4e63b522015-04-14 13:45:39 -0700622
Feng Xiaoe841bac2015-12-11 17:09:20 -0800623 // Test field name conventions.
624 RunValidJsonTest(
625 "FieldNameInSnakeCase",
626 R"({
627 "fieldname1": 1,
628 "fieldName2": 2,
629 "FieldName3": 3
630 })",
631 R"(
632 fieldname1: 1
633 field_name2: 2
634 _field_name3: 3
635 )");
636 RunValidJsonTest(
637 "FieldNameWithNumbers",
638 R"({
639 "field0name5": 5,
640 "field0Name6": 6
641 })",
642 R"(
643 field0name5: 5
644 field_0_name6: 6
645 )");
646 RunValidJsonTest(
647 "FieldNameWithMixedCases",
648 R"({
649 "fieldName7": 7,
650 "fieldName8": 8,
651 "fieldName9": 9,
652 "fieldName10": 10,
653 "fIELDNAME11": 11,
654 "fIELDName12": 12
655 })",
656 R"(
657 fieldName7: 7
658 FieldName8: 8
659 field_Name9: 9
660 Field_Name10: 10
661 FIELD_NAME11: 11
662 FIELD_name12: 12
663 )");
664 // Using the original proto field name in JSON is also allowed.
665 RunValidJsonTest(
666 "OriginalProtoFieldName",
667 R"({
668 "fieldname1": 1,
669 "field_name2": 2,
670 "_field_name3": 3,
671 "field0name5": 5,
672 "field_0_name6": 6,
673 "fieldName7": 7,
674 "FieldName8": 8,
675 "field_Name9": 9,
676 "Field_Name10": 10,
677 "FIELD_NAME11": 11,
678 "FIELD_name12": 12
679 })",
680 R"(
681 fieldname1: 1
682 field_name2: 2
683 _field_name3: 3
684 field0name5: 5
685 field_0_name6: 6
686 fieldName7: 7
687 FieldName8: 8
688 field_Name9: 9
689 Field_Name10: 10
690 FIELD_NAME11: 11
691 FIELD_name12: 12
692 )");
693 // Field names can be escaped.
694 RunValidJsonTest(
695 "FieldNameEscaped",
696 R"({"fieldn\u0061me1": 1})",
697 "fieldname1: 1");
698 // Field names must be quoted (or it's not valid JSON).
699 ExpectParseFailureForJson(
700 "FieldNameNotQuoted",
701 "{fieldname1: 1}");
702 // Trailing comma is not allowed (not valid JSON).
703 ExpectParseFailureForJson(
704 "TrailingCommaInAnObject",
705 R"({"fieldname1":1,})");
706 // JSON doesn't support comments.
707 ExpectParseFailureForJson(
708 "JsonWithComments",
709 R"({
710 // This is a comment.
711 "fieldname1": 1
712 })");
713 // Duplicated field names are not allowed.
714 ExpectParseFailureForJson(
715 "FieldNameDuplicate",
716 R"({
717 "optionalNestedMessage": {a: 1},
718 "optionalNestedMessage": {}
719 })");
720 ExpectParseFailureForJson(
721 "FieldNameDuplicateDifferentCasing1",
722 R"({
723 "optional_nested_message": {a: 1},
724 "optionalNestedMessage": {}
725 })");
726 ExpectParseFailureForJson(
727 "FieldNameDuplicateDifferentCasing2",
728 R"({
729 "optionalNestedMessage": {a: 1},
730 "optional_nested_message": {}
731 })");
732 // Serializers should use lowerCamelCase by default.
733 RunValidJsonTestWithValidator(
734 "FieldNameInLowerCamelCase",
735 R"({
736 "fieldname1": 1,
737 "fieldName2": 2,
738 "FieldName3": 3
739 })",
740 [](const Json::Value& value) {
741 return value.isMember("fieldname1") &&
742 value.isMember("fieldName2") &&
743 value.isMember("FieldName3");
744 });
745 RunValidJsonTestWithValidator(
746 "FieldNameWithNumbers",
747 R"({
748 "field0name5": 5,
749 "field0Name6": 6
750 })",
751 [](const Json::Value& value) {
752 return value.isMember("field0name5") &&
753 value.isMember("field0Name6");
754 });
755 RunValidJsonTestWithValidator(
756 "FieldNameWithMixedCases",
757 R"({
758 "fieldName7": 7,
759 "fieldName8": 8,
760 "fieldName9": 9,
761 "fieldName10": 10,
762 "fIELDNAME11": 11,
763 "fIELDName12": 12
764 })",
765 [](const Json::Value& value) {
766 return value.isMember("fieldName7") &&
767 value.isMember("fieldName8") &&
768 value.isMember("fieldName9") &&
769 value.isMember("fieldName10") &&
770 value.isMember("fIELDNAME11") &&
771 value.isMember("fIELDName12");
772 });
Josh Habermand2b67382015-06-03 12:04:35 -0700773
Feng Xiaoe841bac2015-12-11 17:09:20 -0800774 // Integer fields.
775 RunValidJsonTest(
776 "Int32FieldMaxValue",
777 R"({"optionalInt32": 2147483647})",
778 "optional_int32: 2147483647");
779 RunValidJsonTest(
780 "Int32FieldMinValue",
781 R"({"optionalInt32": -2147483648})",
782 "optional_int32: -2147483648");
783 RunValidJsonTest(
784 "Uint32FieldMaxValue",
785 R"({"optionalUint32": 4294967295})",
786 "optional_uint32: 4294967295");
787 RunValidJsonTest(
788 "Int64FieldMaxValue",
789 R"({"optionalInt64": "9223372036854775807"})",
790 "optional_int64: 9223372036854775807");
791 RunValidJsonTest(
792 "Int64FieldMinValue",
793 R"({"optionalInt64": "-9223372036854775808"})",
794 "optional_int64: -9223372036854775808");
795 RunValidJsonTest(
796 "Uint64FieldMaxValue",
797 R"({"optionalUint64": "18446744073709551615"})",
798 "optional_uint64: 18446744073709551615");
799 RunValidJsonTest(
800 "Int64FieldMaxValueNotQuoted",
801 R"({"optionalInt64": 9223372036854775807})",
802 "optional_int64: 9223372036854775807");
803 RunValidJsonTest(
804 "Int64FieldMinValueNotQuoted",
805 R"({"optionalInt64": -9223372036854775808})",
806 "optional_int64: -9223372036854775808");
807 RunValidJsonTest(
808 "Uint64FieldMaxValueNotQuoted",
809 R"({"optionalUint64": 18446744073709551615})",
810 "optional_uint64: 18446744073709551615");
811 // Values can be represented as JSON strings.
812 RunValidJsonTest(
813 "Int32FieldStringValue",
814 R"({"optionalInt32": "2147483647"})",
815 "optional_int32: 2147483647");
816 RunValidJsonTest(
817 "Int32FieldStringValueEscaped",
818 R"({"optionalInt32": "2\u003147483647"})",
819 "optional_int32: 2147483647");
Josh Habermand2b67382015-06-03 12:04:35 -0700820
Feng Xiaoe841bac2015-12-11 17:09:20 -0800821 // Parsers reject out-of-bound integer values.
822 ExpectParseFailureForJson(
823 "Int32FieldTooLarge",
824 R"({"optionalInt32": 2147483648})");
825 ExpectParseFailureForJson(
826 "Int32FieldTooSmall",
827 R"({"optionalInt32": -2147483649})");
828 ExpectParseFailureForJson(
829 "Uint32FieldTooLarge",
830 R"({"optionalUint32": 4294967296})");
831 ExpectParseFailureForJson(
832 "Int64FieldTooLarge",
833 R"({"optionalInt64": "9223372036854775808"})");
834 ExpectParseFailureForJson(
835 "Int64FieldTooSmall",
836 R"({"optionalInt64": "-9223372036854775809"})");
837 ExpectParseFailureForJson(
838 "Uint64FieldTooLarge",
839 R"({"optionalUint64": "18446744073709551616"})");
840 // Parser reject non-integer numeric values as well.
841 ExpectParseFailureForJson(
842 "Int32FieldNotInteger",
843 R"({"optionalInt32": 0.5})");
844 ExpectParseFailureForJson(
845 "Uint32FieldNotInteger",
846 R"({"optionalUint32": 0.5})");
847 ExpectParseFailureForJson(
848 "Int64FieldNotInteger",
849 R"({"optionalInt64": "0.5"})");
850 ExpectParseFailureForJson(
851 "Uint64FieldNotInteger",
852 R"({"optionalUint64": "0.5"})");
Josh Habermand2b67382015-06-03 12:04:35 -0700853
Feng Xiaoe841bac2015-12-11 17:09:20 -0800854 // Integers but represented as float values are accepted.
855 RunValidJsonTest(
856 "Int32FieldFloatTrailingZero",
857 R"({"optionalInt32": 100000.000})",
858 "optional_int32: 100000");
859 RunValidJsonTest(
860 "Int32FieldExponentialFormat",
861 R"({"optionalInt32": 1e5})",
862 "optional_int32: 100000");
863 RunValidJsonTest(
864 "Int32FieldMaxFloatValue",
865 R"({"optionalInt32": 2.147483647e9})",
866 "optional_int32: 2147483647");
867 RunValidJsonTest(
868 "Int32FieldMinFloatValue",
869 R"({"optionalInt32": -2.147483648e9})",
870 "optional_int32: -2147483648");
871 RunValidJsonTest(
872 "Uint32FieldMaxFloatValue",
873 R"({"optionalUint32": 4.294967295e9})",
874 "optional_uint32: 4294967295");
875
876 // Parser reject non-numeric values.
877 ExpectParseFailureForJson(
878 "Int32FieldNotNumber",
879 R"({"optionalInt32": "3x3"})");
880 ExpectParseFailureForJson(
881 "Uint32FieldNotNumber",
882 R"({"optionalUint32": "3x3"})");
883 ExpectParseFailureForJson(
884 "Int64FieldNotNumber",
885 R"({"optionalInt64": "3x3"})");
886 ExpectParseFailureForJson(
887 "Uint64FieldNotNumber",
888 R"({"optionalUint64": "3x3"})");
889 // JSON does not allow "+" on numric values.
890 ExpectParseFailureForJson(
891 "Int32FieldPlusSign",
892 R"({"optionalInt32": +1})");
893 // JSON doesn't allow leading 0s.
894 ExpectParseFailureForJson(
895 "Int32FieldLeadingZero",
896 R"({"optionalInt32": 01})");
897 ExpectParseFailureForJson(
898 "Int32FieldNegativeWithLeadingZero",
899 R"({"optionalInt32": -01})");
900 // String values must follow the same syntax rule. Specifically leading
901 // or traling spaces are not allowed.
902 ExpectParseFailureForJson(
903 "Int32FieldLeadingSpace",
904 R"({"optionalInt32": " 1"})");
905 ExpectParseFailureForJson(
906 "Int32FieldTrailingSpace",
907 R"({"optionalInt32": "1 "})");
908
909 // 64-bit values are serialized as strings.
910 RunValidJsonTestWithValidator(
911 "Int64FieldBeString",
912 R"({"optionalInt64": 1})",
913 [](const Json::Value& value) {
914 return value["optionalInt64"].type() == Json::stringValue &&
915 value["optionalInt64"].asString() == "1";
916 });
917 RunValidJsonTestWithValidator(
918 "Uint64FieldBeString",
919 R"({"optionalUint64": 1})",
920 [](const Json::Value& value) {
921 return value["optionalUint64"].type() == Json::stringValue &&
922 value["optionalUint64"].asString() == "1";
923 });
924
925 // Bool fields.
926 RunValidJsonTest(
927 "BoolFieldTrue",
928 R"({"optionalBool":true})",
929 "optional_bool: true");
930 RunValidJsonTest(
931 "BoolFieldFalse",
932 R"({"optionalBool":false})",
933 "optional_bool: false");
934
935 // Other forms are not allowed.
936 ExpectParseFailureForJson(
937 "BoolFieldIntegerZero",
938 R"({"optionalBool":0})");
939 ExpectParseFailureForJson(
940 "BoolFieldIntegerOne",
941 R"({"optionalBool":1})");
942 ExpectParseFailureForJson(
943 "BoolFieldCamelCaseTrue",
944 R"({"optionalBool":True})");
945 ExpectParseFailureForJson(
946 "BoolFieldCamelCaseFalse",
947 R"({"optionalBool":False})");
948 ExpectParseFailureForJson(
949 "BoolFieldAllCapitalTrue",
950 R"({"optionalBool":TRUE})");
951 ExpectParseFailureForJson(
952 "BoolFieldAllCapitalFalse",
953 R"({"optionalBool":FALSE})");
954 ExpectParseFailureForJson(
955 "BoolFieldDoubleQuotedTrue",
956 R"({"optionalBool":"true"})");
957 ExpectParseFailureForJson(
958 "BoolFieldDoubleQuotedFalse",
959 R"({"optionalBool":"false"})");
960
961 // Float fields.
962 RunValidJsonTest(
963 "FloatFieldMinPositiveValue",
964 R"({"optionalFloat": 1.175494e-38})",
965 "optional_float: 1.175494e-38");
966 RunValidJsonTest(
967 "FloatFieldMaxNegativeValue",
968 R"({"optionalFloat": -1.175494e-38})",
969 "optional_float: -1.175494e-38");
970 RunValidJsonTest(
971 "FloatFieldMaxPositiveValue",
972 R"({"optionalFloat": 3.402823e+38})",
973 "optional_float: 3.402823e+38");
974 RunValidJsonTest(
975 "FloatFieldMinNegativeValue",
976 R"({"optionalFloat": 3.402823e+38})",
977 "optional_float: 3.402823e+38");
978 // Values can be quoted.
979 RunValidJsonTest(
980 "FloatFieldQuotedValue",
981 R"({"optionalFloat": "1"})",
982 "optional_float: 1");
983 // Special values.
984 RunValidJsonTest(
985 "FloatFieldNan",
986 R"({"optionalFloat": "NaN"})",
987 "optional_float: nan");
988 RunValidJsonTest(
989 "FloatFieldInfinity",
990 R"({"optionalFloat": "Infinity"})",
991 "optional_float: inf");
992 RunValidJsonTest(
993 "FloatFieldNegativeInfinity",
994 R"({"optionalFloat": "-Infinity"})",
995 "optional_float: -inf");
996 // Non-cannonical Nan will be correctly normalized.
997 {
998 TestAllTypes message;
999 // IEEE floating-point standard 32-bit quiet NaN:
1000 // 0111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
1001 message.set_optional_float(
1002 WireFormatLite::DecodeFloat(0x7FA12345));
1003 RunValidJsonTestWithProtobufInput(
1004 "FloatFieldNormalizeQuietNan", message,
1005 "optional_float: nan");
1006 // IEEE floating-point standard 64-bit signaling NaN:
1007 // 1111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
1008 message.set_optional_float(
1009 WireFormatLite::DecodeFloat(0xFFB54321));
1010 RunValidJsonTestWithProtobufInput(
1011 "FloatFieldNormalizeSignalingNan", message,
1012 "optional_float: nan");
1013 }
1014
1015 // Special values must be quoted.
1016 ExpectParseFailureForJson(
1017 "FloatFieldNanNotQuoted",
1018 R"({"optionalFloat": NaN})");
1019 ExpectParseFailureForJson(
1020 "FloatFieldInfinityNotQuoted",
1021 R"({"optionalFloat": Infinity})");
1022 ExpectParseFailureForJson(
1023 "FloatFieldNegativeInfinityNotQuoted",
1024 R"({"optionalFloat": -Infinity})");
1025 // Parsers should reject out-of-bound values.
1026 ExpectParseFailureForJson(
1027 "FloatFieldTooSmall",
1028 R"({"optionalFloat": -3.502823e+38})");
1029 ExpectParseFailureForJson(
1030 "FloatFieldTooLarge",
1031 R"({"optionalFloat": 3.502823e+38})");
1032
1033 // Double fields.
1034 RunValidJsonTest(
1035 "DoubleFieldMinPositiveValue",
1036 R"({"optionalDouble": 2.22507e-308})",
1037 "optional_double: 2.22507e-308");
1038 RunValidJsonTest(
1039 "DoubleFieldMaxNegativeValue",
1040 R"({"optionalDouble": -2.22507e-308})",
1041 "optional_double: -2.22507e-308");
1042 RunValidJsonTest(
1043 "DoubleFieldMaxPositiveValue",
1044 R"({"optionalDouble": 1.79769e+308})",
1045 "optional_double: 1.79769e+308");
1046 RunValidJsonTest(
1047 "DoubleFieldMinNegativeValue",
1048 R"({"optionalDouble": -1.79769e+308})",
1049 "optional_double: -1.79769e+308");
1050 // Values can be quoted.
1051 RunValidJsonTest(
1052 "DoubleFieldQuotedValue",
1053 R"({"optionalDouble": "1"})",
1054 "optional_double: 1");
1055 // Speical values.
1056 RunValidJsonTest(
1057 "DoubleFieldNan",
1058 R"({"optionalDouble": "NaN"})",
1059 "optional_double: nan");
1060 RunValidJsonTest(
1061 "DoubleFieldInfinity",
1062 R"({"optionalDouble": "Infinity"})",
1063 "optional_double: inf");
1064 RunValidJsonTest(
1065 "DoubleFieldNegativeInfinity",
1066 R"({"optionalDouble": "-Infinity"})",
1067 "optional_double: -inf");
1068 // Non-cannonical Nan will be correctly normalized.
1069 {
1070 TestAllTypes message;
1071 message.set_optional_double(
1072 WireFormatLite::DecodeDouble(0x7FFA123456789ABCLL));
1073 RunValidJsonTestWithProtobufInput(
1074 "DoubleFieldNormalizeQuietNan", message,
1075 "optional_double: nan");
1076 message.set_optional_double(
1077 WireFormatLite::DecodeDouble(0xFFFBCBA987654321LL));
1078 RunValidJsonTestWithProtobufInput(
1079 "DoubleFieldNormalizeSignalingNan", message,
1080 "optional_double: nan");
1081 }
1082
1083 // Special values must be quoted.
1084 ExpectParseFailureForJson(
1085 "DoubleFieldNanNotQuoted",
1086 R"({"optionalDouble": NaN})");
1087 ExpectParseFailureForJson(
1088 "DoubleFieldInfinityNotQuoted",
1089 R"({"optionalDouble": Infinity})");
1090 ExpectParseFailureForJson(
1091 "DoubleFieldNegativeInfinityNotQuoted",
1092 R"({"optionalDouble": -Infinity})");
1093
1094 // Parsers should reject out-of-bound values.
1095 ExpectParseFailureForJson(
1096 "DoubleFieldTooSmall",
1097 R"({"optionalDouble": -1.89769e+308})");
1098 ExpectParseFailureForJson(
1099 "DoubleFieldTooLarge",
1100 R"({"optionalDouble": +1.89769e+308})");
1101
1102 // Enum fields.
1103 RunValidJsonTest(
1104 "EnumField",
1105 R"({"optionalNestedEnum": "FOO"})",
1106 "optional_nested_enum: FOO");
1107 // Enum values must be represented as strings.
1108 ExpectParseFailureForJson(
1109 "EnumFieldNotQuoted",
1110 R"({"optionalNestedEnum": FOO})");
1111 // Numeric values are allowed.
1112 RunValidJsonTest(
1113 "EnumFieldNumericValueZero",
1114 R"({"optionalNestedEnum": 0})",
1115 "optional_nested_enum: FOO");
1116 RunValidJsonTest(
1117 "EnumFieldNumericValueNonZero",
1118 R"({"optionalNestedEnum": 1})",
1119 "optional_nested_enum: BAR");
1120 // Unknown enum values are represented as numeric values.
1121 RunValidJsonTestWithValidator(
1122 "EnumFieldUnknownValue",
1123 R"({"optionalNestedEnum": 123})",
1124 [](const Json::Value& value) {
1125 return value["optionalNestedEnum"].type() == Json::intValue &&
1126 value["optionalNestedEnum"].asInt() == 123;
1127 });
1128
1129 // String fields.
1130 RunValidJsonTest(
1131 "StringField",
1132 R"({"optionalString": "Hello world!"})",
1133 "optional_string: \"Hello world!\"");
1134 RunValidJsonTest(
1135 "StringFieldUnicode",
1136 // Google in Chinese.
1137 R"({"optionalString": "谷歌"})",
1138 R"(optional_string: "谷歌")");
1139 RunValidJsonTest(
1140 "StringFieldEscape",
1141 R"({"optionalString": "\"\\\/\b\f\n\r\t"})",
1142 R"(optional_string: "\"\\/\b\f\n\r\t")");
1143 RunValidJsonTest(
1144 "StringFieldUnicodeEscape",
1145 R"({"optionalString": "\u8C37\u6B4C"})",
1146 R"(optional_string: "谷歌")");
1147 RunValidJsonTest(
1148 "StringFieldUnicodeEscapeWithLowercaseHexLetters",
1149 R"({"optionalString": "\u8c37\u6b4c"})",
1150 R"(optional_string: "谷歌")");
1151 RunValidJsonTest(
1152 "StringFieldSurrogatePair",
1153 // The character is an emoji: grinning face with smiling eyes. 😁
1154 R"({"optionalString": "\uD83D\uDE01"})",
1155 R"(optional_string: "\xF0\x9F\x98\x81")");
1156
1157 // Unicode escapes must start with "\u" (lowercase u).
1158 ExpectParseFailureForJson(
1159 "StringFieldUppercaseEscapeLetter",
1160 R"({"optionalString": "\U8C37\U6b4C"})");
1161 ExpectParseFailureForJson(
1162 "StringFieldInvalidEscape",
1163 R"({"optionalString": "\uXXXX\u6B4C"})");
1164 ExpectParseFailureForJson(
1165 "StringFieldUnterminatedEscape",
1166 R"({"optionalString": "\u8C3"})");
1167 ExpectParseFailureForJson(
1168 "StringFieldUnpairedHighSurrogate",
1169 R"({"optionalString": "\uD800"})");
1170 ExpectParseFailureForJson(
1171 "StringFieldUnpairedLowSurrogate",
1172 R"({"optionalString": "\uDC00"})");
1173 ExpectParseFailureForJson(
1174 "StringFieldSurrogateInWrongOrder",
1175 R"({"optionalString": "\uDE01\uD83D"})");
1176 ExpectParseFailureForJson(
1177 "StringFieldNotAString",
1178 R"({"optionalString": 12345})");
1179
1180 // Bytes fields.
1181 RunValidJsonTest(
1182 "BytesField",
1183 R"({"optionalBytes": "AQI="})",
1184 R"(optional_bytes: "\x01\x02")");
1185 ExpectParseFailureForJson(
1186 "BytesFieldNoPadding",
1187 R"({"optionalBytes": "AQI"})");
1188 ExpectParseFailureForJson(
1189 "BytesFieldInvalidBase64Characters",
1190 R"({"optionalBytes": "-_=="})");
1191
1192 // Message fields.
1193 RunValidJsonTest(
1194 "MessageField",
1195 R"({"optionalNestedMessage": {"a": 1234}})",
1196 "optional_nested_message: {a: 1234}");
1197
1198 // Oneof fields.
1199 ExpectParseFailureForJson(
1200 "OneofFieldDuplicate",
1201 R"({"oneofUint32": 1, "oneofString": "test"})");
1202
1203 // Repeated fields.
1204 RunValidJsonTest(
1205 "PrimitiveRepeatedField",
1206 R"({"repeatedInt32": [1, 2, 3, 4]})",
1207 "repeated_int32: [1, 2, 3, 4]");
1208 RunValidJsonTest(
1209 "EnumRepeatedField",
1210 R"({"repeatedNestedEnum": ["FOO", "BAR", "BAZ"]})",
1211 "repeated_nested_enum: [FOO, BAR, BAZ]");
1212 RunValidJsonTest(
1213 "StringRepeatedField",
1214 R"({"repeatedString": ["Hello", "world"]})",
1215 R"(repeated_string: ["Hello", "world"])");
1216 RunValidJsonTest(
1217 "BytesRepeatedField",
1218 R"({"repeatedBytes": ["AAEC", "AQI="]})",
1219 R"(repeated_bytes: ["\x00\x01\x02", "\x01\x02"])");
1220 RunValidJsonTest(
1221 "MessageRepeatedField",
1222 R"({"repeatedNestedMessage": [{"a": 1234}, {"a": 5678}]})",
1223 "repeated_nested_message: {a: 1234}"
1224 "repeated_nested_message: {a: 5678}");
1225
1226 // Repeated field elements are of incorrect type.
1227 ExpectParseFailureForJson(
1228 "RepeatedFieldWrongElementTypeExpectingIntegersGotBool",
1229 R"({"repeatedInt32": [1, false, 3, 4]})");
1230 ExpectParseFailureForJson(
1231 "RepeatedFieldWrongElementTypeExpectingIntegersGotString",
1232 R"({"repeatedInt32": [1, 2, "name", 4]})");
1233 ExpectParseFailureForJson(
1234 "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage",
1235 R"({"repeatedInt32": [1, 2, 3, {"a": 4}]})");
1236 ExpectParseFailureForJson(
1237 "RepeatedFieldWrongElementTypeExpectingStringsGotInt",
1238 R"({"repeatedString": ["1", 2, "3", "4"]})");
1239 ExpectParseFailureForJson(
1240 "RepeatedFieldWrongElementTypeExpectingStringsGotBool",
1241 R"({"repeatedString": ["1", "2", false, "4"]})");
1242 ExpectParseFailureForJson(
1243 "RepeatedFieldWrongElementTypeExpectingStringsGotMessage",
1244 R"({"repeatedString": ["1", 2, "3", {"a": 4}]})");
1245 ExpectParseFailureForJson(
1246 "RepeatedFieldWrongElementTypeExpectingMessagesGotInt",
1247 R"({"repeatedNestedMessage": [{"a": 1}, 2]})");
1248 ExpectParseFailureForJson(
1249 "RepeatedFieldWrongElementTypeExpectingMessagesGotBool",
1250 R"({"repeatedNestedMessage": [{"a": 1}, false]})");
1251 ExpectParseFailureForJson(
1252 "RepeatedFieldWrongElementTypeExpectingMessagesGotString",
1253 R"({"repeatedNestedMessage": [{"a": 1}, "2"]})");
1254 // Trailing comma in the repeated field is not allowed.
1255 ExpectParseFailureForJson(
1256 "RepeatedFieldTrailingComma",
1257 R"({"repeatedInt32": [1, 2, 3, 4,]})");
1258
1259 // Map fields.
1260 RunValidJsonTest(
1261 "Int32MapField",
1262 R"({"mapInt32Int32": {"1": 2, "3": 4}})",
1263 "map_int32_int32: {key: 1 value: 2}"
1264 "map_int32_int32: {key: 3 value: 4}");
1265 ExpectParseFailureForJson(
1266 "Int32MapFieldKeyNotQuoted",
1267 R"({"mapInt32Int32": {1: 2, 3: 4}})");
1268 RunValidJsonTest(
1269 "Uint32MapField",
1270 R"({"mapUint32Uint32": {"1": 2, "3": 4}})",
1271 "map_uint32_uint32: {key: 1 value: 2}"
1272 "map_uint32_uint32: {key: 3 value: 4}");
1273 ExpectParseFailureForJson(
1274 "Uint32MapFieldKeyNotQuoted",
1275 R"({"mapUint32Uint32": {1: 2, 3: 4}})");
1276 RunValidJsonTest(
1277 "Int64MapField",
1278 R"({"mapInt64Int64": {"1": 2, "3": 4}})",
1279 "map_int64_int64: {key: 1 value: 2}"
1280 "map_int64_int64: {key: 3 value: 4}");
1281 ExpectParseFailureForJson(
1282 "Int64MapFieldKeyNotQuoted",
1283 R"({"mapInt64Int64": {1: 2, 3: 4}})");
1284 RunValidJsonTest(
1285 "Uint64MapField",
1286 R"({"mapUint64Uint64": {"1": 2, "3": 4}})",
1287 "map_uint64_uint64: {key: 1 value: 2}"
1288 "map_uint64_uint64: {key: 3 value: 4}");
1289 ExpectParseFailureForJson(
1290 "Uint64MapFieldKeyNotQuoted",
1291 R"({"mapUint64Uint64": {1: 2, 3: 4}})");
1292 RunValidJsonTest(
1293 "BoolMapField",
1294 R"({"mapBoolBool": {"true": true, "false": false}})",
1295 "map_bool_bool: {key: true value: true}"
1296 "map_bool_bool: {key: false value: false}");
1297 ExpectParseFailureForJson(
1298 "BoolMapFieldKeyNotQuoted",
1299 R"({"mapBoolBool": {true: true, false: false}})");
1300 RunValidJsonTest(
1301 "MessageMapField",
1302 R"({
1303 "mapStringNestedMessage": {
1304 "hello": {"a": 1234},
1305 "world": {"a": 5678}
1306 }
1307 })",
1308 R"(
1309 map_string_nested_message: {
1310 key: "hello"
1311 value: {a: 1234}
1312 }
1313 map_string_nested_message: {
1314 key: "world"
1315 value: {a: 5678}
1316 }
1317 )");
1318 // Since Map keys are represented as JSON strings, escaping should be allowed.
1319 RunValidJsonTest(
1320 "Int32MapEscapedKey",
1321 R"({"mapInt32Int32": {"\u0031": 2}})",
1322 "map_int32_int32: {key: 1 value: 2}");
1323 RunValidJsonTest(
1324 "Int64MapEscapedKey",
1325 R"({"mapInt64Int64": {"\u0031": 2}})",
1326 "map_int64_int64: {key: 1 value: 2}");
1327 RunValidJsonTest(
1328 "BoolMapEscapedKey",
1329 R"({"mapBoolBool": {"tr\u0075e": true}})",
1330 "map_bool_bool: {key: true value: true}");
1331
1332 // "null" is accepted for all fields types.
1333 RunValidJsonTest(
1334 "AllFieldAcceptNull",
1335 R"({
1336 "optionalInt32": null,
1337 "optionalInt64": null,
1338 "optionalUint32": null,
1339 "optionalUint64": null,
1340 "optionalBool": null,
1341 "optionalString": null,
1342 "optionalBytes": null,
1343 "optionalNestedEnum": null,
1344 "optionalNestedMessage": null,
1345 "repeatedInt32": null,
1346 "repeatedInt64": null,
1347 "repeatedUint32": null,
1348 "repeatedUint64": null,
1349 "repeatedBool": null,
1350 "repeatedString": null,
1351 "repeatedBytes": null,
1352 "repeatedNestedEnum": null,
1353 "repeatedNestedMessage": null,
1354 "mapInt32Int32": null,
1355 "mapBoolBool": null,
1356 "mapStringNestedMessage": null
1357 })",
1358 "");
1359
1360 // Repeated field elements cannot be null.
1361 ExpectParseFailureForJson(
1362 "RepeatedFieldPrimitiveElementIsNull",
1363 R"({"repeatedInt32": [1, null, 2]})");
1364 ExpectParseFailureForJson(
1365 "RepeatedFieldMessageElementIsNull",
1366 R"({"repeatedNestedMessage": [{"a":1}, null, {"a":2}]})");
1367 // Map field keys cannot be null.
1368 ExpectParseFailureForJson(
1369 "MapFieldKeyIsNull",
1370 R"({"mapInt32Int32": {null: 1}})");
1371 // Map field values cannot be null.
1372 ExpectParseFailureForJson(
1373 "MapFieldValueIsNull",
1374 R"({"mapInt32Int32": {"0": null}})");
1375
1376 // Wrapper types.
1377 RunValidJsonTest(
1378 "OptionalBoolWrapper",
1379 R"({"optionalBoolWrapper": false})",
1380 "optional_bool_wrapper: {value: false}");
1381 RunValidJsonTest(
1382 "OptionalInt32Wrapper",
1383 R"({"optionalInt32Wrapper": 0})",
1384 "optional_int32_wrapper: {value: 0}");
1385 RunValidJsonTest(
1386 "OptionalUint32Wrapper",
1387 R"({"optionalUint32Wrapper": 0})",
1388 "optional_uint32_wrapper: {value: 0}");
1389 RunValidJsonTest(
1390 "OptionalInt64Wrapper",
1391 R"({"optionalInt64Wrapper": 0})",
1392 "optional_int64_wrapper: {value: 0}");
1393 RunValidJsonTest(
1394 "OptionalUint64Wrapper",
1395 R"({"optionalUint64Wrapper": 0})",
1396 "optional_uint64_wrapper: {value: 0}");
1397 RunValidJsonTest(
1398 "OptionalFloatWrapper",
1399 R"({"optionalFloatWrapper": 0})",
1400 "optional_float_wrapper: {value: 0}");
1401 RunValidJsonTest(
1402 "OptionalDoubleWrapper",
1403 R"({"optionalDoubleWrapper": 0})",
1404 "optional_double_wrapper: {value: 0}");
1405 RunValidJsonTest(
1406 "OptionalStringWrapper",
1407 R"({"optionalStringWrapper": ""})",
1408 R"(optional_string_wrapper: {value: ""})");
1409 RunValidJsonTest(
1410 "OptionalBytesWrapper",
1411 R"({"optionalBytesWrapper": ""})",
1412 R"(optional_bytes_wrapper: {value: ""})");
1413 RunValidJsonTest(
1414 "OptionalWrapperTypesWithNonDefaultValue",
1415 R"({
1416 "optionalBoolWrapper": true,
1417 "optionalInt32Wrapper": 1,
1418 "optionalUint32Wrapper": 1,
1419 "optionalInt64Wrapper": "1",
1420 "optionalUint64Wrapper": "1",
1421 "optionalFloatWrapper": 1,
1422 "optionalDoubleWrapper": 1,
1423 "optionalStringWrapper": "1",
1424 "optionalBytesWrapper": "AQI="
1425 })",
1426 R"(
1427 optional_bool_wrapper: {value: true}
1428 optional_int32_wrapper: {value: 1}
1429 optional_uint32_wrapper: {value: 1}
1430 optional_int64_wrapper: {value: 1}
1431 optional_uint64_wrapper: {value: 1}
1432 optional_float_wrapper: {value: 1}
1433 optional_double_wrapper: {value: 1}
1434 optional_string_wrapper: {value: "1"}
1435 optional_bytes_wrapper: {value: "\x01\x02"}
1436 )");
1437 RunValidJsonTest(
1438 "RepeatedBoolWrapper",
1439 R"({"repeatedBoolWrapper": [true, false]})",
1440 "repeated_bool_wrapper: {value: true}"
1441 "repeated_bool_wrapper: {value: false}");
1442 RunValidJsonTest(
1443 "RepeatedInt32Wrapper",
1444 R"({"repeatedInt32Wrapper": [0, 1]})",
1445 "repeated_int32_wrapper: {value: 0}"
1446 "repeated_int32_wrapper: {value: 1}");
1447 RunValidJsonTest(
1448 "RepeatedUint32Wrapper",
1449 R"({"repeatedUint32Wrapper": [0, 1]})",
1450 "repeated_uint32_wrapper: {value: 0}"
1451 "repeated_uint32_wrapper: {value: 1}");
1452 RunValidJsonTest(
1453 "RepeatedInt64Wrapper",
1454 R"({"repeatedInt64Wrapper": [0, 1]})",
1455 "repeated_int64_wrapper: {value: 0}"
1456 "repeated_int64_wrapper: {value: 1}");
1457 RunValidJsonTest(
1458 "RepeatedUint64Wrapper",
1459 R"({"repeatedUint64Wrapper": [0, 1]})",
1460 "repeated_uint64_wrapper: {value: 0}"
1461 "repeated_uint64_wrapper: {value: 1}");
1462 RunValidJsonTest(
1463 "RepeatedFloatWrapper",
1464 R"({"repeatedFloatWrapper": [0, 1]})",
1465 "repeated_float_wrapper: {value: 0}"
1466 "repeated_float_wrapper: {value: 1}");
1467 RunValidJsonTest(
1468 "RepeatedDoubleWrapper",
1469 R"({"repeatedDoubleWrapper": [0, 1]})",
1470 "repeated_double_wrapper: {value: 0}"
1471 "repeated_double_wrapper: {value: 1}");
1472 RunValidJsonTest(
1473 "RepeatedStringWrapper",
1474 R"({"repeatedStringWrapper": ["", "AQI="]})",
1475 R"(
1476 repeated_string_wrapper: {value: ""}
1477 repeated_string_wrapper: {value: "AQI="}
1478 )");
1479 RunValidJsonTest(
1480 "RepeatedBytesWrapper",
1481 R"({"repeatedBytesWrapper": ["", "AQI="]})",
1482 R"(
1483 repeated_bytes_wrapper: {value: ""}
1484 repeated_bytes_wrapper: {value: "\x01\x02"}
1485 )");
1486 RunValidJsonTest(
1487 "WrapperTypesWithNullValue",
1488 R"({
1489 "optionalBoolWrapper": null,
1490 "optionalInt32Wrapper": null,
1491 "optionalUint32Wrapper": null,
1492 "optionalInt64Wrapper": null,
1493 "optionalUint64Wrapper": null,
1494 "optionalFloatWrapper": null,
1495 "optionalDoubleWrapper": null,
1496 "optionalStringWrapper": null,
1497 "optionalBytesWrapper": null,
1498 "repeatedBoolWrapper": null,
1499 "repeatedInt32Wrapper": null,
1500 "repeatedUint32Wrapper": null,
1501 "repeatedInt64Wrapper": null,
1502 "repeatedUint64Wrapper": null,
1503 "repeatedFloatWrapper": null,
1504 "repeatedDoubleWrapper": null,
1505 "repeatedStringWrapper": null,
1506 "repeatedBytesWrapper": null
1507 })",
1508 "");
1509
1510 // Duration
1511 RunValidJsonTest(
1512 "DurationMinValue",
1513 R"({"optionalDuration": "-315576000000.999999999s"})",
1514 "optional_duration: {seconds: -315576000000 nanos: -999999999}");
1515 RunValidJsonTest(
1516 "DurationMaxValue",
1517 R"({"optionalDuration": "315576000000.999999999s"})",
1518 "optional_duration: {seconds: 315576000000 nanos: 999999999}");
1519 RunValidJsonTest(
1520 "DurationRepeatedValue",
1521 R"({"repeatedDuration": ["1.5s", "-1.5s"]})",
1522 "repeated_duration: {seconds: 1 nanos: 500000000}"
1523 "repeated_duration: {seconds: -1 nanos: -500000000}");
1524
1525 ExpectParseFailureForJson(
1526 "DurationMissingS",
1527 R"({"optionalDuration": "1"})");
1528 ExpectParseFailureForJson(
1529 "DurationJsonInputTooSmall",
1530 R"({"optionalDuration": "-315576000001.000000000s"})");
1531 ExpectParseFailureForJson(
1532 "DurationJsonInputTooLarge",
1533 R"({"optionalDuration": "315576000001.000000000s"})");
1534 ExpectSerializeFailureForJson(
1535 "DurationProtoInputTooSmall",
1536 "optional_duration: {seconds: -315576000001 nanos: 0}");
1537 ExpectSerializeFailureForJson(
1538 "DurationProtoInputTooLarge",
1539 "optional_duration: {seconds: 315576000001 nanos: 0}");
1540
1541 RunValidJsonTestWithValidator(
1542 "DurationHasZeroFractionalDigit",
1543 R"({"optionalDuration": "1.000000000s"})",
1544 [](const Json::Value& value) {
1545 return value["optionalDuration"].asString() == "1s";
1546 });
1547 RunValidJsonTestWithValidator(
1548 "DurationHas3FractionalDigits",
1549 R"({"optionalDuration": "1.010000000s"})",
1550 [](const Json::Value& value) {
1551 return value["optionalDuration"].asString() == "1.010s";
1552 });
1553 RunValidJsonTestWithValidator(
1554 "DurationHas6FractionalDigits",
1555 R"({"optionalDuration": "1.000010000s"})",
1556 [](const Json::Value& value) {
1557 return value["optionalDuration"].asString() == "1.000010s";
1558 });
1559 RunValidJsonTestWithValidator(
1560 "DurationHas9FractionalDigits",
1561 R"({"optionalDuration": "1.000000010s"})",
1562 [](const Json::Value& value) {
1563 return value["optionalDuration"].asString() == "1.000000010s";
1564 });
1565
1566 // Timestamp
1567 RunValidJsonTest(
1568 "TimestampMinValue",
1569 R"({"optionalTimestamp": "0001-01-01T00:00:00Z"})",
1570 "optional_timestamp: {seconds: -62135596800}");
1571 RunValidJsonTest(
1572 "TimestampMaxValue",
1573 R"({"optionalTimestamp": "9999-12-31T23:59:59.999999999Z"})",
1574 "optional_timestamp: {seconds: 253402300799 nanos: 999999999}");
1575 RunValidJsonTest(
1576 "TimestampRepeatedValue",
1577 R"({
1578 "repeatedTimestamp": [
1579 "0001-01-01T00:00:00Z",
1580 "9999-12-31T23:59:59.999999999Z"
1581 ]
1582 })",
1583 "repeated_timestamp: {seconds: -62135596800}"
1584 "repeated_timestamp: {seconds: 253402300799 nanos: 999999999}");
1585 RunValidJsonTest(
1586 "TimestampWithPositiveOffset",
1587 R"({"optionalTimestamp": "1970-01-01T08:00:00+08:00"})",
1588 "optional_timestamp: {seconds: 0}");
1589 RunValidJsonTest(
1590 "TimestampWithNegativeOffset",
1591 R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
1592 "optional_timestamp: {seconds: 0}");
1593
1594 ExpectParseFailureForJson(
1595 "TimestampJsonInputTooSmall",
1596 R"({"optionalTimestamp": "0000-01-01T00:00:00Z"})");
1597 ExpectParseFailureForJson(
1598 "TimestampJsonInputTooLarge",
1599 R"({"optionalTimestamp": "10000-01-01T00:00:00Z"})");
1600 ExpectParseFailureForJson(
1601 "TimestampJsonInputMissingZ",
1602 R"({"optionalTimestamp": "0001-01-01T00:00:00"})");
1603 ExpectParseFailureForJson(
1604 "TimestampJsonInputMissingT",
1605 R"({"optionalTimestamp": "0001-01-01 00:00:00Z"})");
1606 ExpectParseFailureForJson(
1607 "TimestampJsonInputLowercaseZ",
1608 R"({"optionalTimestamp": "0001-01-01T00:00:00z"})");
1609 ExpectParseFailureForJson(
1610 "TimestampJsonInputLowercaseT",
1611 R"({"optionalTimestamp": "0001-01-01t00:00:00Z"})");
1612 ExpectSerializeFailureForJson(
1613 "TimestampProtoInputTooSmall",
1614 "optional_timestamp: {seconds: -62135596801}");
1615 ExpectSerializeFailureForJson(
1616 "TimestampProtoInputTooLarge",
1617 "optional_timestamp: {seconds: 253402300800}");
1618 RunValidJsonTestWithValidator(
1619 "TimestampZeroNormalized",
1620 R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
1621 [](const Json::Value& value) {
1622 return value["optionalTimestamp"].asString() ==
1623 "1970-01-01T00:00:00Z";
1624 });
1625 RunValidJsonTestWithValidator(
1626 "TimestampHasZeroFractionalDigit",
1627 R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})",
1628 [](const Json::Value& value) {
1629 return value["optionalTimestamp"].asString() ==
1630 "1970-01-01T00:00:00Z";
1631 });
1632 RunValidJsonTestWithValidator(
1633 "TimestampHas3FractionalDigits",
1634 R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})",
1635 [](const Json::Value& value) {
1636 return value["optionalTimestamp"].asString() ==
1637 "1970-01-01T00:00:00.010Z";
1638 });
1639 RunValidJsonTestWithValidator(
1640 "TimestampHas6FractionalDigits",
1641 R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})",
1642 [](const Json::Value& value) {
1643 return value["optionalTimestamp"].asString() ==
1644 "1970-01-01T00:00:00.000010Z";
1645 });
1646 RunValidJsonTestWithValidator(
1647 "TimestampHas9FractionalDigits",
1648 R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})",
1649 [](const Json::Value& value) {
1650 return value["optionalTimestamp"].asString() ==
1651 "1970-01-01T00:00:00.000000010Z";
1652 });
1653
1654 // FieldMask
1655 RunValidJsonTest(
1656 "FieldMask",
1657 R"({"optionalFieldMask": "foo,barBaz"})",
1658 R"(optional_field_mask: {paths: "foo" paths: "bar_baz"})");
1659 ExpectParseFailureForJson(
1660 "FieldMaskInvalidCharacter",
1661 R"({"optionalFieldMask": "foo,bar_bar"})");
1662 ExpectSerializeFailureForJson(
1663 "FieldMaskPathsDontRoundTrip",
1664 R"(optional_field_mask: {paths: "fooBar"})");
1665 ExpectSerializeFailureForJson(
1666 "FieldMaskNumbersDontRoundTrip",
1667 R"(optional_field_mask: {paths: "foo_3_bar"})");
1668 ExpectSerializeFailureForJson(
1669 "FieldMaskTooManyUnderscore",
1670 R"(optional_field_mask: {paths: "foo__bar"})");
1671
1672 // Struct
1673 RunValidJsonTest(
1674 "Struct",
1675 R"({
1676 "optionalStruct": {
1677 "nullValue": null,
1678 "intValue": 1234,
1679 "boolValue": true,
1680 "doubleValue": 1234.5678,
1681 "stringValue": "Hello world!",
1682 "listValue": [1234, "5678"],
1683 "objectValue": {
1684 "value": 0
1685 }
1686 }
1687 })",
1688 R"(
1689 optional_struct: {
1690 fields: {
1691 key: "nullValue"
1692 value: {null_value: NULL_VALUE}
1693 }
1694 fields: {
1695 key: "intValue"
1696 value: {number_value: 1234}
1697 }
1698 fields: {
1699 key: "boolValue"
1700 value: {bool_value: true}
1701 }
1702 fields: {
1703 key: "doubleValue"
1704 value: {number_value: 1234.5678}
1705 }
1706 fields: {
1707 key: "stringValue"
1708 value: {string_value: "Hello world!"}
1709 }
1710 fields: {
1711 key: "listValue"
1712 value: {
1713 list_value: {
1714 values: {
1715 number_value: 1234
1716 }
1717 values: {
1718 string_value: "5678"
1719 }
1720 }
1721 }
1722 }
1723 fields: {
1724 key: "objectValue"
1725 value: {
1726 struct_value: {
1727 fields: {
1728 key: "value"
1729 value: {
1730 number_value: 0
1731 }
1732 }
1733 }
1734 }
1735 }
1736 }
1737 )");
1738 // Value
1739 RunValidJsonTest(
1740 "ValueAcceptInteger",
1741 R"({"optionalValue": 1})",
1742 "optional_value: { number_value: 1}");
1743 RunValidJsonTest(
1744 "ValueAcceptFloat",
1745 R"({"optionalValue": 1.5})",
1746 "optional_value: { number_value: 1.5}");
1747 RunValidJsonTest(
1748 "ValueAcceptBool",
1749 R"({"optionalValue": false})",
1750 "optional_value: { bool_value: false}");
1751 RunValidJsonTest(
1752 "ValueAcceptNull",
1753 R"({"optionalValue": null})",
1754 "optional_value: { null_value: NULL_VALUE}");
1755 RunValidJsonTest(
1756 "ValueAcceptString",
1757 R"({"optionalValue": "hello"})",
1758 R"(optional_value: { string_value: "hello"})");
1759 RunValidJsonTest(
1760 "ValueAcceptList",
1761 R"({"optionalValue": [0, "hello"]})",
1762 R"(
1763 optional_value: {
1764 list_value: {
1765 values: {
1766 number_value: 0
1767 }
1768 values: {
1769 string_value: "hello"
1770 }
1771 }
1772 }
1773 )");
1774 RunValidJsonTest(
1775 "ValueAcceptObject",
1776 R"({"optionalValue": {"value": 1}})",
1777 R"(
1778 optional_value: {
1779 struct_value: {
1780 fields: {
1781 key: "value"
1782 value: {
1783 number_value: 1
1784 }
1785 }
1786 }
1787 }
1788 )");
1789
1790 // Any
1791 RunValidJsonTest(
1792 "Any",
1793 R"({
1794 "optionalAny": {
1795 "@type": "type.googleapis.com/conformance.TestAllTypes",
1796 "optionalInt32": 12345
1797 }
1798 })",
1799 R"(
1800 optional_any: {
1801 [type.googleapis.com/conformance.TestAllTypes] {
1802 optional_int32: 12345
1803 }
1804 }
1805 )");
1806 RunValidJsonTest(
1807 "AnyNested",
1808 R"({
1809 "optionalAny": {
1810 "@type": "type.googleapis.com/google.protobuf.Any",
1811 "value": {
1812 "@type": "type.googleapis.com/conformance.TestAllTypes",
1813 "optionalInt32": 12345
1814 }
1815 }
1816 })",
1817 R"(
1818 optional_any: {
1819 [type.googleapis.com/google.protobuf.Any] {
1820 [type.googleapis.com/conformance.TestAllTypes] {
1821 optional_int32: 12345
1822 }
1823 }
1824 }
1825 )");
1826 // The special "@type" tag is not required to appear first.
1827 RunValidJsonTest(
1828 "AnyUnorderedTypeTag",
1829 R"({
1830 "optionalAny": {
1831 "optionalInt32": 12345,
1832 "@type": "type.googleapis.com/conformance.TestAllTypes"
1833 }
1834 })",
1835 R"(
1836 optional_any: {
1837 [type.googleapis.com/conformance.TestAllTypes] {
1838 optional_int32: 12345
1839 }
1840 }
1841 )");
1842 // Well-known types in Any.
1843 RunValidJsonTest(
1844 "AnyWithInt32ValueWrapper",
1845 R"({
1846 "optionalAny": {
1847 "@type": "type.googleapis.com/google.protobuf.Int32Value",
1848 "value": 12345
1849 }
1850 })",
1851 R"(
1852 optional_any: {
1853 [type.googleapis.com/google.protobuf.Int32Value] {
1854 value: 12345
1855 }
1856 }
1857 )");
1858 RunValidJsonTest(
1859 "AnyWithDuration",
1860 R"({
1861 "optionalAny": {
1862 "@type": "type.googleapis.com/google.protobuf.Duration",
1863 "value": "1.5s"
1864 }
1865 })",
1866 R"(
1867 optional_any: {
1868 [type.googleapis.com/google.protobuf.Duration] {
1869 seconds: 1
1870 nanos: 500000000
1871 }
1872 }
1873 )");
1874 RunValidJsonTest(
1875 "AnyWithTimestamp",
1876 R"({
1877 "optionalAny": {
1878 "@type": "type.googleapis.com/google.protobuf.Timestamp",
1879 "value": "1970-01-01T00:00:00Z"
1880 }
1881 })",
1882 R"(
1883 optional_any: {
1884 [type.googleapis.com/google.protobuf.Timestamp] {
1885 seconds: 0
1886 nanos: 0
1887 }
1888 }
1889 )");
1890 RunValidJsonTest(
1891 "AnyWithFieldMask",
1892 R"({
1893 "optionalAny": {
1894 "@type": "type.googleapis.com/google.protobuf.FieldMask",
1895 "value": "foo,barBaz"
1896 }
1897 })",
1898 R"(
1899 optional_any: {
1900 [type.googleapis.com/google.protobuf.FieldMask] {
1901 paths: ["foo", "bar_baz"]
1902 }
1903 }
1904 )");
1905 RunValidJsonTest(
1906 "AnyWithStruct",
1907 R"({
1908 "optionalAny": {
1909 "@type": "type.googleapis.com/google.protobuf.Struct",
1910 "value": {
1911 "foo": 1
1912 }
1913 }
1914 })",
1915 R"(
1916 optional_any: {
1917 [type.googleapis.com/google.protobuf.Struct] {
1918 fields: {
1919 key: "foo"
1920 value: {
1921 number_value: 1
1922 }
1923 }
1924 }
1925 }
1926 )");
1927 RunValidJsonTest(
1928 "AnyWithValueForJsonObject",
1929 R"({
1930 "optionalAny": {
1931 "@type": "type.googleapis.com/google.protobuf.Value",
1932 "value": {
1933 "foo": 1
1934 }
1935 }
1936 })",
1937 R"(
1938 optional_any: {
1939 [type.googleapis.com/google.protobuf.Value] {
1940 struct_value: {
1941 fields: {
1942 key: "foo"
1943 value: {
1944 number_value: 1
1945 }
1946 }
1947 }
1948 }
1949 }
1950 )");
1951 RunValidJsonTest(
1952 "AnyWithValueForInteger",
1953 R"({
1954 "optionalAny": {
1955 "@type": "type.googleapis.com/google.protobuf.Value",
1956 "value": 1
1957 }
1958 })",
1959 R"(
1960 optional_any: {
1961 [type.googleapis.com/google.protobuf.Value] {
1962 number_value: 1
1963 }
1964 }
1965 )");
1966
1967 bool ok = true;
1968 if (!CheckSetEmpty(expected_to_fail_,
1969 "These tests were listed in the failure list, but they "
1970 "don't exist. Remove them from the failure list")) {
1971 ok = false;
1972 }
1973 if (!CheckSetEmpty(unexpected_failing_tests_,
1974 "These tests failed. If they can't be fixed right now, "
1975 "you can add them to the failure list so the overall "
1976 "suite can succeed")) {
1977 ok = false;
1978 }
1979
1980 // Sometimes the testee may be fixed before we update the failure list (e.g.,
1981 // the testee is from a different component). We warn about this case but
1982 // don't consider it an overall test failure.
1983 CheckSetEmpty(unexpected_succeeding_tests_,
1984 "These tests succeeded, even though they were listed in "
1985 "the failure list. Remove them from the failure list");
1986
Josh Haberman325392d2015-08-17 12:30:49 -07001987 if (verbose_) {
1988 CheckSetEmpty(skipped_,
1989 "These tests were skipped (probably because support for some "
1990 "features is not implemented)");
1991 }
Josh Habermanb0500b32015-07-10 16:36:59 -07001992
1993 StringAppendF(&output_,
1994 "CONFORMANCE SUITE %s: %d successes, %d skipped, "
1995 "%d expected failures, %d unexpected failures.\n",
1996 ok ? "PASSED" : "FAILED", successes_, skipped_.size(),
1997 expected_failures_, unexpected_failing_tests_.size());
1998 StringAppendF(&output_, "\n");
1999
Josh Haberman4e63b522015-04-14 13:45:39 -07002000 output->assign(output_);
Josh Habermand2b67382015-06-03 12:04:35 -07002001
2002 return ok;
Josh Haberman35a1cc72015-04-01 17:23:48 -07002003}
Josh Haberman4e63b522015-04-14 13:45:39 -07002004
2005} // namespace protobuf
2006} // namespace google