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