From cc8ca5b6a5478b40546d4206392eb1471454460d Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Mon, 19 Sep 2016 13:45:07 -0700 Subject: Integrate internal changes --- conformance/Makefile.am | 16 +- conformance/conformance_python.py | 8 +- conformance/conformance_test.cc | 586 +++++++++++++++++--------------- conformance/conformance_test.h | 52 ++- conformance/conformance_test_runner.cc | 12 + conformance/failure_list_cpp.txt | 83 +++-- conformance/failure_list_java.txt | 88 +++-- conformance/failure_list_python.txt | 61 +--- conformance/failure_list_python_cpp.txt | 93 ++--- 9 files changed, 503 insertions(+), 496 deletions(-) (limited to 'conformance') diff --git a/conformance/Makefile.am b/conformance/Makefile.am index 28ac3c8a..bdd23a07 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -251,31 +251,31 @@ conformance-csharp: $(other_language_protoc_outputs) # Targets for actually running tests. test_cpp: protoc_middleman conformance-test-runner conformance-cpp - ./conformance-test-runner --failure_list failure_list_cpp.txt ./conformance-cpp + ./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt ./conformance-cpp test_java: protoc_middleman conformance-test-runner conformance-java - ./conformance-test-runner --failure_list failure_list_java.txt ./conformance-java + ./conformance-test-runner --enforce_recommended --failure_list failure_list_java.txt ./conformance-java test_java_lite: protoc_middleman conformance-test-runner conformance-java-lite - ./conformance-test-runner ./conformance-java-lite + ./conformance-test-runner --enforce_recommended ./conformance-java-lite test_csharp: protoc_middleman conformance-test-runner conformance-csharp - ./conformance-test-runner --failure_list failure_list_csharp.txt ./conformance-csharp + ./conformance-test-runner --enforce_recommended --failure_list failure_list_csharp.txt ./conformance-csharp test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) - RUBYLIB=../ruby/lib:. ./conformance-test-runner --failure_list failure_list_ruby.txt ./conformance_ruby.rb + RUBYLIB=../ruby/lib:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_ruby.txt ./conformance_ruby.rb # These depend on library paths being properly set up. The easiest way to # run them is to just use "tox" from the python dir. test_python: protoc_middleman conformance-test-runner - ./conformance-test-runner --failure_list failure_list_python.txt ./conformance_python.py + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt ./conformance_python.py test_python_cpp: protoc_middleman conformance-test-runner - ./conformance-test-runner --failure_list failure_list_python_cpp.txt ./conformance_python.py + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py if OBJC_CONFORMANCE_TEST test_objc: protoc_middleman conformance-test-runner conformance-objc - ./conformance-test-runner --failure_list failure_list_objc.txt ./conformance-objc + ./conformance-test-runner --enforce_recomemnded --failure_list failure_list_objc.txt ./conformance-objc endif diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py index a490c8e8..2f4a7812 100755 --- a/conformance/conformance_python.py +++ b/conformance/conformance_python.py @@ -67,7 +67,7 @@ def do_test(request): elif request.WhichOneof('payload') == 'json_payload': try: json_format.Parse(request.json_payload, test_message) - except json_format.ParseError as e: + except Exception as e: response.parse_error = str(e) return response @@ -81,7 +81,11 @@ def do_test(request): response.protobuf_payload = test_message.SerializeToString() elif request.requested_output_format == conformance_pb2.JSON: - response.json_payload = json_format.MessageToJson(test_message) + try: + response.json_payload = json_format.MessageToJson(test_message) + except Exception as e: + response.serialize_error = str(e) + return response except Exception as e: response.runtime_error = str(e) diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index fb963f68..a74f2837 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -183,6 +183,7 @@ void ConformanceTestSuite::ReportSuccess(const string& test_name) { } void ConformanceTestSuite::ReportFailure(const string& test_name, + ConformanceLevel level, const ConformanceRequest& request, const ConformanceResponse& response, const char* fmt, ...) { @@ -190,6 +191,8 @@ void ConformanceTestSuite::ReportFailure(const string& test_name, expected_failures_++; if (!verbose_) return; + } else if (level == RECOMMENDED && !enforce_recommended_) { + StringAppendF(&output_, "WARNING, test=%s: ", test_name.c_str()); } else { StringAppendF(&output_, "ERROR, test=%s: ", test_name.c_str()); unexpected_failing_tests_.insert(test_name); @@ -214,6 +217,15 @@ void ConformanceTestSuite::ReportSkip(const string& test_name, skipped_.insert(test_name); } +string ConformanceTestSuite::ConformanceLevelToString(ConformanceLevel level) { + switch (level) { + case REQUIRED: return "Required"; + case RECOMMENDED: return "Recommended"; + } + GOOGLE_LOG(FATAL) << "Unknown value: " << level; + return ""; +} + void ConformanceTestSuite::RunTest(const string& test_name, const ConformanceRequest& request, ConformanceResponse* response) { @@ -241,8 +253,9 @@ void ConformanceTestSuite::RunTest(const string& test_name, } void ConformanceTestSuite::RunValidInputTest( - const string& test_name, const string& input, WireFormat input_format, - const string& equivalent_text_format, WireFormat requested_output) { + const string& test_name, ConformanceLevel level, const string& input, + WireFormat input_format, const string& equivalent_text_format, + WireFormat requested_output) { TestAllTypes reference_message; GOOGLE_CHECK( TextFormat::ParseFromString(equivalent_text_format, &reference_message)) @@ -291,7 +304,7 @@ void ConformanceTestSuite::RunValidInputTest( case ConformanceResponse::kJsonPayload: { if (requested_output != conformance::JSON) { ReportFailure( - test_name, request, response, + test_name, level, request, response, "Test was asked for protobuf output but provided JSON instead."); return; } @@ -300,13 +313,13 @@ void ConformanceTestSuite::RunValidInputTest( JsonToBinaryString(type_resolver_.get(), type_url_, response.json_payload(), &binary_protobuf); if (!status.ok()) { - ReportFailure(test_name, request, response, + ReportFailure(test_name, level, request, response, "JSON output we received from test was unparseable."); return; } if (!test_message.ParseFromString(binary_protobuf)) { - ReportFailure(test_name, request, response, + ReportFailure(test_name, level, request, response, "INTERNAL ERROR: internal JSON->protobuf transcode " "yielded unparseable proto."); return; @@ -318,13 +331,13 @@ void ConformanceTestSuite::RunValidInputTest( case ConformanceResponse::kProtobufPayload: { if (requested_output != conformance::PROTOBUF) { ReportFailure( - test_name, request, response, + test_name, level, request, response, "Test was asked for JSON output but provided protobuf instead."); return; } if (!test_message.ParseFromString(response.protobuf_payload())) { - ReportFailure(test_name, request, response, + ReportFailure(test_name, level, request, response, "Protobuf output we received from test was unparseable."); return; } @@ -347,7 +360,7 @@ void ConformanceTestSuite::RunValidInputTest( if (differencer.Compare(reference_message, test_message)) { ReportSuccess(test_name); } else { - ReportFailure(test_name, request, response, + ReportFailure(test_name, level, request, response, "Output was not equivalent to reference message: %s.", differences.c_str()); } @@ -355,11 +368,12 @@ void ConformanceTestSuite::RunValidInputTest( // Expect that this precise protobuf will cause a parse error. void ConformanceTestSuite::ExpectParseFailureForProto( - const string& proto, const string& test_name) { + const string& proto, const string& test_name, ConformanceLevel level) { ConformanceRequest request; ConformanceResponse response; request.set_protobuf_payload(proto); - string effective_test_name = "ProtobufInput." + test_name; + string effective_test_name = ConformanceLevelToString(level) + + ".ProtobufInput." + test_name; // We don't expect output, but if the program erroneously accepts the protobuf // we let it send its response as this. We must not leave it unspecified. @@ -371,7 +385,7 @@ void ConformanceTestSuite::ExpectParseFailureForProto( } else if (response.result_case() == ConformanceResponse::kSkipped) { ReportSkip(effective_test_name, request, response); } else { - ReportFailure(effective_test_name, request, response, + ReportFailure(effective_test_name, level, request, response, "Should have failed to parse, but didn't."); } } @@ -382,27 +396,30 @@ void ConformanceTestSuite::ExpectParseFailureForProto( // // TODO(haberman): implement the second of these. void ConformanceTestSuite::ExpectHardParseFailureForProto( - const string& proto, const string& test_name) { - return ExpectParseFailureForProto(proto, test_name); + const string& proto, const string& test_name, ConformanceLevel level) { + return ExpectParseFailureForProto(proto, test_name, level); } void ConformanceTestSuite::RunValidJsonTest( - const string& test_name, const string& input_json, + const string& test_name, ConformanceLevel level, const string& input_json, const string& equivalent_text_format) { - RunValidInputTest("JsonInput." + test_name + ".ProtobufOutput", input_json, - conformance::JSON, equivalent_text_format, - conformance::PROTOBUF); - RunValidInputTest("JsonInput." + test_name + ".JsonOutput", input_json, - conformance::JSON, equivalent_text_format, - conformance::JSON); + RunValidInputTest( + ConformanceLevelToString(level) + ".JsonInput." + test_name + + ".ProtobufOutput", level, input_json, conformance::JSON, + equivalent_text_format, conformance::PROTOBUF); + RunValidInputTest( + ConformanceLevelToString(level) + ".JsonInput." + test_name + + ".JsonOutput", level, input_json, conformance::JSON, + equivalent_text_format, conformance::JSON); } void ConformanceTestSuite::RunValidJsonTestWithProtobufInput( - const string& test_name, const TestAllTypes& input, + const string& test_name, ConformanceLevel level, const TestAllTypes& input, const string& equivalent_text_format) { - RunValidInputTest("ProtobufInput." + test_name + ".JsonOutput", - input.SerializeAsString(), conformance::PROTOBUF, - equivalent_text_format, conformance::JSON); + RunValidInputTest( + ConformanceLevelToString(level) + ".ProtobufInput." + test_name + + ".JsonOutput", level, input.SerializeAsString(), conformance::PROTOBUF, + equivalent_text_format, conformance::JSON); } void ConformanceTestSuite::RunValidProtobufTest( @@ -422,14 +439,15 @@ void ConformanceTestSuite::RunValidProtobufTest( // method allows strict checking on a proto3 JSON serializer by inspecting // the JSON output directly. void ConformanceTestSuite::RunValidJsonTestWithValidator( - const string& test_name, const string& input_json, + const string& test_name, ConformanceLevel level, const string& input_json, const Validator& validator) { ConformanceRequest request; ConformanceResponse response; request.set_json_payload(input_json); request.set_requested_output_format(conformance::JSON); - string effective_test_name = "JsonInput." + test_name + ".Validator"; + string effective_test_name = ConformanceLevelToString(level) + + ".JsonInput." + test_name + ".Validator"; RunTest(effective_test_name, request, &response); @@ -439,7 +457,7 @@ void ConformanceTestSuite::RunValidJsonTestWithValidator( } if (response.result_case() != ConformanceResponse::kJsonPayload) { - ReportFailure(effective_test_name, request, response, + ReportFailure(effective_test_name, level, request, response, "Expected JSON payload but got type %d.", response.result_case()); return; @@ -447,13 +465,13 @@ void ConformanceTestSuite::RunValidJsonTestWithValidator( Json::Reader reader; Json::Value value; if (!reader.parse(response.json_payload(), value)) { - ReportFailure(effective_test_name, request, response, + ReportFailure(effective_test_name, level, request, response, "JSON payload cannot be parsed as valid JSON: %s", reader.getFormattedErrorMessages().c_str()); return; } if (!validator(value)) { - ReportFailure(effective_test_name, request, response, + ReportFailure(effective_test_name, level, request, response, "JSON payload validation failed."); return; } @@ -461,11 +479,12 @@ void ConformanceTestSuite::RunValidJsonTestWithValidator( } void ConformanceTestSuite::ExpectParseFailureForJson( - const string& test_name, const string& input_json) { + const string& test_name, ConformanceLevel level, const string& input_json) { ConformanceRequest request; ConformanceResponse response; request.set_json_payload(input_json); - string effective_test_name = "JsonInput." + test_name; + string effective_test_name = + ConformanceLevelToString(level) + ".JsonInput." + test_name; // We don't expect output, but if the program erroneously accepts the protobuf // we let it send its response as this. We must not leave it unspecified. @@ -477,13 +496,13 @@ void ConformanceTestSuite::ExpectParseFailureForJson( } else if (response.result_case() == ConformanceResponse::kSkipped) { ReportSkip(effective_test_name, request, response); } else { - ReportFailure(effective_test_name, request, response, + ReportFailure(effective_test_name, level, request, response, "Should have failed to parse, but didn't."); } } void ConformanceTestSuite::ExpectSerializeFailureForJson( - const string& test_name, const string& text_format) { + const string& test_name, ConformanceLevel level, const string& text_format) { TestAllTypes payload_message; GOOGLE_CHECK( TextFormat::ParseFromString(text_format, &payload_message)) @@ -492,7 +511,8 @@ void ConformanceTestSuite::ExpectSerializeFailureForJson( ConformanceRequest request; ConformanceResponse response; request.set_protobuf_payload(payload_message.SerializeAsString()); - string effective_test_name = test_name + ".JsonOutput"; + string effective_test_name = + ConformanceLevelToString(level) + "." + test_name + ".JsonOutput"; request.set_requested_output_format(conformance::JSON); RunTest(effective_test_name, request, &response); @@ -501,7 +521,7 @@ void ConformanceTestSuite::ExpectSerializeFailureForJson( } else if (response.result_case() == ConformanceResponse::kSkipped) { ReportSkip(effective_test_name, request, response); } else { - ReportFailure(effective_test_name, request, response, + ReportFailure(effective_test_name, level, request, response, "Should have failed to serialize, but didn't."); } } @@ -527,41 +547,43 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) { ExpectParseFailureForProto( tag(fieldnum, wire_type), - "PrematureEofBeforeKnownNonRepeatedValue" + type_name); + "PrematureEofBeforeKnownNonRepeatedValue" + type_name, REQUIRED); ExpectParseFailureForProto( tag(rep_fieldnum, wire_type), - "PrematureEofBeforeKnownRepeatedValue" + type_name); + "PrematureEofBeforeKnownRepeatedValue" + type_name, REQUIRED); ExpectParseFailureForProto( tag(UNKNOWN_FIELD, wire_type), - "PrematureEofBeforeUnknownValue" + type_name); + "PrematureEofBeforeUnknownValue" + type_name, REQUIRED); ExpectParseFailureForProto( cat( tag(fieldnum, wire_type), incomplete ), - "PrematureEofInsideKnownNonRepeatedValue" + type_name); + "PrematureEofInsideKnownNonRepeatedValue" + type_name, REQUIRED); ExpectParseFailureForProto( cat( tag(rep_fieldnum, wire_type), incomplete ), - "PrematureEofInsideKnownRepeatedValue" + type_name); + "PrematureEofInsideKnownRepeatedValue" + type_name, REQUIRED); ExpectParseFailureForProto( cat( tag(UNKNOWN_FIELD, wire_type), incomplete ), - "PrematureEofInsideUnknownValue" + type_name); + "PrematureEofInsideUnknownValue" + type_name, REQUIRED); if (wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { ExpectParseFailureForProto( cat( tag(fieldnum, wire_type), varint(1) ), - "PrematureEofInDelimitedDataForKnownNonRepeatedValue" + type_name); + "PrematureEofInDelimitedDataForKnownNonRepeatedValue" + type_name, + REQUIRED); ExpectParseFailureForProto( cat( tag(rep_fieldnum, wire_type), varint(1) ), - "PrematureEofInDelimitedDataForKnownRepeatedValue" + type_name); + "PrematureEofInDelimitedDataForKnownRepeatedValue" + type_name, + REQUIRED); // EOF in the middle of delimited data for unknown value. ExpectParseFailureForProto( cat( tag(UNKNOWN_FIELD, wire_type), varint(1) ), - "PrematureEofInDelimitedDataForUnknownValue" + type_name); + "PrematureEofInDelimitedDataForUnknownValue" + type_name, REQUIRED); if (type == FieldDescriptor::TYPE_MESSAGE) { // Submessage ends in the middle of a value. @@ -572,7 +594,7 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) { cat( tag(fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), varint(incomplete_submsg.size()), incomplete_submsg ), - "PrematureEofInSubmessageValue" + type_name); + "PrematureEofInSubmessageValue" + type_name, REQUIRED); } } else if (type != FieldDescriptor::TYPE_GROUP) { // Non-delimited, non-group: eligible for packing. @@ -582,13 +604,13 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) { cat( tag(rep_fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), varint(incomplete.size()), incomplete ), - "PrematureEofInPackedFieldValue" + type_name); + "PrematureEofInPackedFieldValue" + type_name, REQUIRED); // EOF in the middle of packed region. ExpectParseFailureForProto( cat( tag(rep_fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), varint(1) ), - "PrematureEofInPackedField" + type_name); + "PrematureEofInPackedField" + type_name, REQUIRED); } } @@ -651,14 +673,15 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, TestPrematureEOFForType(static_cast(i)); } - RunValidJsonTest("HelloWorld", "{\"optionalString\":\"Hello, World!\"}", + RunValidJsonTest("HelloWorld", REQUIRED, + "{\"optionalString\":\"Hello, World!\"}", "optional_string: 'Hello, World!'"); // NOTE: The spec for JSON support is still being sorted out, these may not // all be correct. // Test field name conventions. RunValidJsonTest( - "FieldNameInSnakeCase", + "FieldNameInSnakeCase", REQUIRED, R"({ "fieldname1": 1, "fieldName2": 2, @@ -672,7 +695,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, field__name4_: 4 )"); RunValidJsonTest( - "FieldNameWithNumbers", + "FieldNameWithNumbers", REQUIRED, R"({ "field0name5": 5, "field0Name6": 6 @@ -682,14 +705,14 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, field_0_name6: 6 )"); RunValidJsonTest( - "FieldNameWithMixedCases", + "FieldNameWithMixedCases", REQUIRED, R"({ "fieldName7": 7, - "fieldName8": 8, + "FieldName8": 8, "fieldName9": 9, - "fieldName10": 10, - "fIELDNAME11": 11, - "fIELDName12": 12 + "FieldName10": 10, + "FIELDNAME11": 11, + "FIELDName12": 12 })", R"( fieldName7: 7 @@ -719,7 +742,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, )"); // Using the original proto field name in JSON is also allowed. RunValidJsonTest( - "OriginalProtoFieldName", + "OriginalProtoFieldName", REQUIRED, R"({ "fieldname1": 1, "field_name2": 2, @@ -762,7 +785,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, )"); // Field names can be escaped. RunValidJsonTest( - "FieldNameEscaped", + "FieldNameEscaped", REQUIRED, R"({"fieldn\u0061me1": 1})", "fieldname1: 1"); // String ends with escape character. @@ -771,11 +794,11 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, "{\"optionalString\": \"abc\\"); // Field names must be quoted (or it's not valid JSON). ExpectParseFailureForJson( - "FieldNameNotQuoted", + "FieldNameNotQuoted", RECOMMENDED, "{fieldname1: 1}"); // Trailing comma is not allowed (not valid JSON). ExpectParseFailureForJson( - "TrailingCommaInAnObject", + "TrailingCommaInAnObject", RECOMMENDED, R"({"fieldname1":1,})"); ExpectParseFailureForJson( "TrailingCommaInAnObjectWithSpace", @@ -790,7 +813,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, })"); // JSON doesn't support comments. ExpectParseFailureForJson( - "JsonWithComments", + "JsonWithComments", RECOMMENDED, R"({ // This is a comment. "fieldname1": 1 @@ -833,19 +856,19 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, "{\n \"optionalInt32\": 1\n \"optionalInt64\": 2\n}"); // Duplicated field names are not allowed. ExpectParseFailureForJson( - "FieldNameDuplicate", + "FieldNameDuplicate", RECOMMENDED, R"({ "optionalNestedMessage": {a: 1}, "optionalNestedMessage": {} })"); ExpectParseFailureForJson( - "FieldNameDuplicateDifferentCasing1", + "FieldNameDuplicateDifferentCasing1", RECOMMENDED, R"({ "optional_nested_message": {a: 1}, "optionalNestedMessage": {} })"); ExpectParseFailureForJson( - "FieldNameDuplicateDifferentCasing2", + "FieldNameDuplicateDifferentCasing2", RECOMMENDED, R"({ "optionalNestedMessage": {a: 1}, "optional_nested_message": {} @@ -854,7 +877,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // all be correct. // Serializers should use lowerCamelCase by default. RunValidJsonTestWithValidator( - "FieldNameInLowerCamelCase", + "FieldNameInLowerCamelCase", REQUIRED, R"({ "fieldname1": 1, "fieldName2": 2, @@ -868,7 +891,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, value.isMember("fieldName4"); }); RunValidJsonTestWithValidator( - "FieldNameWithNumbers", + "FieldNameWithNumbers", REQUIRED, R"({ "field0name5": 5, "field0Name6": 6 @@ -878,22 +901,22 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, value.isMember("field0Name6"); }); RunValidJsonTestWithValidator( - "FieldNameWithMixedCases", + "FieldNameWithMixedCases", REQUIRED, R"({ "fieldName7": 7, - "fieldName8": 8, + "FieldName8": 8, "fieldName9": 9, - "fieldName10": 10, - "fIELDNAME11": 11, - "fIELDName12": 12 + "FieldName10": 10, + "FIELDNAME11": 11, + "FIELDName12": 12 })", [](const Json::Value& value) { return value.isMember("fieldName7") && - value.isMember("fieldName8") && + value.isMember("FieldName8") && value.isMember("fieldName9") && - value.isMember("fieldName10") && - value.isMember("fIELDNAME11") && - value.isMember("fIELDName12"); + value.isMember("FieldName10") && + value.isMember("FIELDNAME11") && + value.isMember("FIELDName12"); }); RunValidJsonTestWithValidator( "FieldNameWithDoubleUnderscores", @@ -916,27 +939,27 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Integer fields. RunValidJsonTest( - "Int32FieldMaxValue", + "Int32FieldMaxValue", REQUIRED, R"({"optionalInt32": 2147483647})", "optional_int32: 2147483647"); RunValidJsonTest( - "Int32FieldMinValue", + "Int32FieldMinValue", REQUIRED, R"({"optionalInt32": -2147483648})", "optional_int32: -2147483648"); RunValidJsonTest( - "Uint32FieldMaxValue", + "Uint32FieldMaxValue", REQUIRED, R"({"optionalUint32": 4294967295})", "optional_uint32: 4294967295"); RunValidJsonTest( - "Int64FieldMaxValue", + "Int64FieldMaxValue", REQUIRED, R"({"optionalInt64": "9223372036854775807"})", "optional_int64: 9223372036854775807"); RunValidJsonTest( - "Int64FieldMinValue", + "Int64FieldMinValue", REQUIRED, R"({"optionalInt64": "-9223372036854775808"})", "optional_int64: -9223372036854775808"); RunValidJsonTest( - "Uint64FieldMaxValue", + "Uint64FieldMaxValue", REQUIRED, R"({"optionalUint64": "18446744073709551615"})", "optional_uint64: 18446744073709551615"); // While not the largest Int64, this is the largest @@ -946,127 +969,127 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // work in some implementations, but should not be // relied upon. RunValidJsonTest( - "Int64FieldMaxValueNotQuoted", + "Int64FieldMaxValueNotQuoted", REQUIRED, R"({"optionalInt64": 9223372036854774784})", "optional_int64: 9223372036854774784"); RunValidJsonTest( - "Int64FieldMinValueNotQuoted", + "Int64FieldMinValueNotQuoted", REQUIRED, R"({"optionalInt64": -9223372036854775808})", "optional_int64: -9223372036854775808"); // Largest interoperable Uint64; see comment above // for Int64FieldMaxValueNotQuoted. RunValidJsonTest( - "Uint64FieldMaxValueNotQuoted", + "Uint64FieldMaxValueNotQuoted", REQUIRED, R"({"optionalUint64": 18446744073709549568})", "optional_uint64: 18446744073709549568"); // Values can be represented as JSON strings. RunValidJsonTest( - "Int32FieldStringValue", + "Int32FieldStringValue", REQUIRED, R"({"optionalInt32": "2147483647"})", "optional_int32: 2147483647"); RunValidJsonTest( - "Int32FieldStringValueEscaped", + "Int32FieldStringValueEscaped", REQUIRED, R"({"optionalInt32": "2\u003147483647"})", "optional_int32: 2147483647"); // Parsers reject out-of-bound integer values. ExpectParseFailureForJson( - "Int32FieldTooLarge", + "Int32FieldTooLarge", REQUIRED, R"({"optionalInt32": 2147483648})"); ExpectParseFailureForJson( - "Int32FieldTooSmall", + "Int32FieldTooSmall", REQUIRED, R"({"optionalInt32": -2147483649})"); ExpectParseFailureForJson( - "Uint32FieldTooLarge", + "Uint32FieldTooLarge", REQUIRED, R"({"optionalUint32": 4294967296})"); ExpectParseFailureForJson( - "Int64FieldTooLarge", + "Int64FieldTooLarge", REQUIRED, R"({"optionalInt64": "9223372036854775808"})"); ExpectParseFailureForJson( - "Int64FieldTooSmall", + "Int64FieldTooSmall", REQUIRED, R"({"optionalInt64": "-9223372036854775809"})"); ExpectParseFailureForJson( - "Uint64FieldTooLarge", + "Uint64FieldTooLarge", REQUIRED, R"({"optionalUint64": "18446744073709551616"})"); // Parser reject non-integer numeric values as well. ExpectParseFailureForJson( - "Int32FieldNotInteger", + "Int32FieldNotInteger", REQUIRED, R"({"optionalInt32": 0.5})"); ExpectParseFailureForJson( - "Uint32FieldNotInteger", + "Uint32FieldNotInteger", REQUIRED, R"({"optionalUint32": 0.5})"); ExpectParseFailureForJson( - "Int64FieldNotInteger", + "Int64FieldNotInteger", REQUIRED, R"({"optionalInt64": "0.5"})"); ExpectParseFailureForJson( - "Uint64FieldNotInteger", + "Uint64FieldNotInteger", REQUIRED, R"({"optionalUint64": "0.5"})"); // Integers but represented as float values are accepted. RunValidJsonTest( - "Int32FieldFloatTrailingZero", + "Int32FieldFloatTrailingZero", REQUIRED, R"({"optionalInt32": 100000.000})", "optional_int32: 100000"); RunValidJsonTest( - "Int32FieldExponentialFormat", + "Int32FieldExponentialFormat", REQUIRED, R"({"optionalInt32": 1e5})", "optional_int32: 100000"); RunValidJsonTest( - "Int32FieldMaxFloatValue", + "Int32FieldMaxFloatValue", REQUIRED, R"({"optionalInt32": 2.147483647e9})", "optional_int32: 2147483647"); RunValidJsonTest( - "Int32FieldMinFloatValue", + "Int32FieldMinFloatValue", REQUIRED, R"({"optionalInt32": -2.147483648e9})", "optional_int32: -2147483648"); RunValidJsonTest( - "Uint32FieldMaxFloatValue", + "Uint32FieldMaxFloatValue", REQUIRED, R"({"optionalUint32": 4.294967295e9})", "optional_uint32: 4294967295"); // Parser reject non-numeric values. ExpectParseFailureForJson( - "Int32FieldNotNumber", + "Int32FieldNotNumber", REQUIRED, R"({"optionalInt32": "3x3"})"); ExpectParseFailureForJson( - "Uint32FieldNotNumber", + "Uint32FieldNotNumber", REQUIRED, R"({"optionalUint32": "3x3"})"); ExpectParseFailureForJson( - "Int64FieldNotNumber", + "Int64FieldNotNumber", REQUIRED, R"({"optionalInt64": "3x3"})"); ExpectParseFailureForJson( - "Uint64FieldNotNumber", + "Uint64FieldNotNumber", REQUIRED, R"({"optionalUint64": "3x3"})"); // JSON does not allow "+" on numric values. ExpectParseFailureForJson( - "Int32FieldPlusSign", + "Int32FieldPlusSign", REQUIRED, R"({"optionalInt32": +1})"); // JSON doesn't allow leading 0s. ExpectParseFailureForJson( - "Int32FieldLeadingZero", + "Int32FieldLeadingZero", REQUIRED, R"({"optionalInt32": 01})"); ExpectParseFailureForJson( - "Int32FieldNegativeWithLeadingZero", + "Int32FieldNegativeWithLeadingZero", REQUIRED, R"({"optionalInt32": -01})"); // String values must follow the same syntax rule. Specifically leading // or traling spaces are not allowed. ExpectParseFailureForJson( - "Int32FieldLeadingSpace", + "Int32FieldLeadingSpace", REQUIRED, R"({"optionalInt32": " 1"})"); ExpectParseFailureForJson( - "Int32FieldTrailingSpace", + "Int32FieldTrailingSpace", REQUIRED, R"({"optionalInt32": "1 "})"); // 64-bit values are serialized as strings. RunValidJsonTestWithValidator( - "Int64FieldBeString", + "Int64FieldBeString", RECOMMENDED, R"({"optionalInt64": 1})", [](const Json::Value& value) { return value["optionalInt64"].type() == Json::stringValue && value["optionalInt64"].asString() == "1"; }); RunValidJsonTestWithValidator( - "Uint64FieldBeString", + "Uint64FieldBeString", RECOMMENDED, R"({"optionalUint64": 1})", [](const Json::Value& value) { return value["optionalUint64"].type() == Json::stringValue && @@ -1075,73 +1098,73 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Bool fields. RunValidJsonTest( - "BoolFieldTrue", + "BoolFieldTrue", REQUIRED, R"({"optionalBool":true})", "optional_bool: true"); RunValidJsonTest( - "BoolFieldFalse", + "BoolFieldFalse", REQUIRED, R"({"optionalBool":false})", "optional_bool: false"); // Other forms are not allowed. ExpectParseFailureForJson( - "BoolFieldIntegerZero", + "BoolFieldIntegerZero", RECOMMENDED, R"({"optionalBool":0})"); ExpectParseFailureForJson( - "BoolFieldIntegerOne", + "BoolFieldIntegerOne", RECOMMENDED, R"({"optionalBool":1})"); ExpectParseFailureForJson( - "BoolFieldCamelCaseTrue", + "BoolFieldCamelCaseTrue", RECOMMENDED, R"({"optionalBool":True})"); ExpectParseFailureForJson( - "BoolFieldCamelCaseFalse", + "BoolFieldCamelCaseFalse", RECOMMENDED, R"({"optionalBool":False})"); ExpectParseFailureForJson( - "BoolFieldAllCapitalTrue", + "BoolFieldAllCapitalTrue", RECOMMENDED, R"({"optionalBool":TRUE})"); ExpectParseFailureForJson( - "BoolFieldAllCapitalFalse", + "BoolFieldAllCapitalFalse", RECOMMENDED, R"({"optionalBool":FALSE})"); ExpectParseFailureForJson( - "BoolFieldDoubleQuotedTrue", + "BoolFieldDoubleQuotedTrue", RECOMMENDED, R"({"optionalBool":"true"})"); ExpectParseFailureForJson( - "BoolFieldDoubleQuotedFalse", + "BoolFieldDoubleQuotedFalse", RECOMMENDED, R"({"optionalBool":"false"})"); // Float fields. RunValidJsonTest( - "FloatFieldMinPositiveValue", + "FloatFieldMinPositiveValue", REQUIRED, R"({"optionalFloat": 1.175494e-38})", "optional_float: 1.175494e-38"); RunValidJsonTest( - "FloatFieldMaxNegativeValue", + "FloatFieldMaxNegativeValue", REQUIRED, R"({"optionalFloat": -1.175494e-38})", "optional_float: -1.175494e-38"); RunValidJsonTest( - "FloatFieldMaxPositiveValue", + "FloatFieldMaxPositiveValue", REQUIRED, R"({"optionalFloat": 3.402823e+38})", "optional_float: 3.402823e+38"); RunValidJsonTest( - "FloatFieldMinNegativeValue", + "FloatFieldMinNegativeValue", REQUIRED, R"({"optionalFloat": 3.402823e+38})", "optional_float: 3.402823e+38"); // Values can be quoted. RunValidJsonTest( - "FloatFieldQuotedValue", + "FloatFieldQuotedValue", REQUIRED, R"({"optionalFloat": "1"})", "optional_float: 1"); // Special values. RunValidJsonTest( - "FloatFieldNan", + "FloatFieldNan", REQUIRED, R"({"optionalFloat": "NaN"})", "optional_float: nan"); RunValidJsonTest( - "FloatFieldInfinity", + "FloatFieldInfinity", REQUIRED, R"({"optionalFloat": "Infinity"})", "optional_float: inf"); RunValidJsonTest( - "FloatFieldNegativeInfinity", + "FloatFieldNegativeInfinity", REQUIRED, R"({"optionalFloat": "-Infinity"})", "optional_float: -inf"); // Non-cannonical Nan will be correctly normalized. @@ -1152,68 +1175,68 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, message.set_optional_float( WireFormatLite::DecodeFloat(0x7FA12345)); RunValidJsonTestWithProtobufInput( - "FloatFieldNormalizeQuietNan", message, + "FloatFieldNormalizeQuietNan", REQUIRED, message, "optional_float: nan"); // IEEE floating-point standard 64-bit signaling NaN: // 1111 1111 1xxx xxxx xxxx xxxx xxxx xxxx message.set_optional_float( WireFormatLite::DecodeFloat(0xFFB54321)); RunValidJsonTestWithProtobufInput( - "FloatFieldNormalizeSignalingNan", message, + "FloatFieldNormalizeSignalingNan", REQUIRED, message, "optional_float: nan"); } // Special values must be quoted. ExpectParseFailureForJson( - "FloatFieldNanNotQuoted", + "FloatFieldNanNotQuoted", RECOMMENDED, R"({"optionalFloat": NaN})"); ExpectParseFailureForJson( - "FloatFieldInfinityNotQuoted", + "FloatFieldInfinityNotQuoted", RECOMMENDED, R"({"optionalFloat": Infinity})"); ExpectParseFailureForJson( - "FloatFieldNegativeInfinityNotQuoted", + "FloatFieldNegativeInfinityNotQuoted", RECOMMENDED, R"({"optionalFloat": -Infinity})"); // Parsers should reject out-of-bound values. ExpectParseFailureForJson( - "FloatFieldTooSmall", + "FloatFieldTooSmall", REQUIRED, R"({"optionalFloat": -3.502823e+38})"); ExpectParseFailureForJson( - "FloatFieldTooLarge", + "FloatFieldTooLarge", REQUIRED, R"({"optionalFloat": 3.502823e+38})"); // Double fields. RunValidJsonTest( - "DoubleFieldMinPositiveValue", + "DoubleFieldMinPositiveValue", REQUIRED, R"({"optionalDouble": 2.22507e-308})", "optional_double: 2.22507e-308"); RunValidJsonTest( - "DoubleFieldMaxNegativeValue", + "DoubleFieldMaxNegativeValue", REQUIRED, R"({"optionalDouble": -2.22507e-308})", "optional_double: -2.22507e-308"); RunValidJsonTest( - "DoubleFieldMaxPositiveValue", + "DoubleFieldMaxPositiveValue", REQUIRED, R"({"optionalDouble": 1.79769e+308})", "optional_double: 1.79769e+308"); RunValidJsonTest( - "DoubleFieldMinNegativeValue", + "DoubleFieldMinNegativeValue", REQUIRED, R"({"optionalDouble": -1.79769e+308})", "optional_double: -1.79769e+308"); // Values can be quoted. RunValidJsonTest( - "DoubleFieldQuotedValue", + "DoubleFieldQuotedValue", REQUIRED, R"({"optionalDouble": "1"})", "optional_double: 1"); // Speical values. RunValidJsonTest( - "DoubleFieldNan", + "DoubleFieldNan", REQUIRED, R"({"optionalDouble": "NaN"})", "optional_double: nan"); RunValidJsonTest( - "DoubleFieldInfinity", + "DoubleFieldInfinity", REQUIRED, R"({"optionalDouble": "Infinity"})", "optional_double: inf"); RunValidJsonTest( - "DoubleFieldNegativeInfinity", + "DoubleFieldNegativeInfinity", REQUIRED, R"({"optionalDouble": "-Infinity"})", "optional_double: -inf"); // Non-cannonical Nan will be correctly normalized. @@ -1222,55 +1245,55 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, message.set_optional_double( WireFormatLite::DecodeDouble(0x7FFA123456789ABCLL)); RunValidJsonTestWithProtobufInput( - "DoubleFieldNormalizeQuietNan", message, + "DoubleFieldNormalizeQuietNan", REQUIRED, message, "optional_double: nan"); message.set_optional_double( WireFormatLite::DecodeDouble(0xFFFBCBA987654321LL)); RunValidJsonTestWithProtobufInput( - "DoubleFieldNormalizeSignalingNan", message, + "DoubleFieldNormalizeSignalingNan", REQUIRED, message, "optional_double: nan"); } // Special values must be quoted. ExpectParseFailureForJson( - "DoubleFieldNanNotQuoted", + "DoubleFieldNanNotQuoted", RECOMMENDED, R"({"optionalDouble": NaN})"); ExpectParseFailureForJson( - "DoubleFieldInfinityNotQuoted", + "DoubleFieldInfinityNotQuoted", RECOMMENDED, R"({"optionalDouble": Infinity})"); ExpectParseFailureForJson( - "DoubleFieldNegativeInfinityNotQuoted", + "DoubleFieldNegativeInfinityNotQuoted", RECOMMENDED, R"({"optionalDouble": -Infinity})"); // Parsers should reject out-of-bound values. ExpectParseFailureForJson( - "DoubleFieldTooSmall", + "DoubleFieldTooSmall", REQUIRED, R"({"optionalDouble": -1.89769e+308})"); ExpectParseFailureForJson( - "DoubleFieldTooLarge", + "DoubleFieldTooLarge", REQUIRED, R"({"optionalDouble": +1.89769e+308})"); // Enum fields. RunValidJsonTest( - "EnumField", + "EnumField", REQUIRED, R"({"optionalNestedEnum": "FOO"})", "optional_nested_enum: FOO"); // Enum values must be represented as strings. ExpectParseFailureForJson( - "EnumFieldNotQuoted", + "EnumFieldNotQuoted", REQUIRED, R"({"optionalNestedEnum": FOO})"); // Numeric values are allowed. RunValidJsonTest( - "EnumFieldNumericValueZero", + "EnumFieldNumericValueZero", REQUIRED, R"({"optionalNestedEnum": 0})", "optional_nested_enum: FOO"); RunValidJsonTest( - "EnumFieldNumericValueNonZero", + "EnumFieldNumericValueNonZero", REQUIRED, R"({"optionalNestedEnum": 1})", "optional_nested_enum: BAR"); // Unknown enum values are represented as numeric values. RunValidJsonTestWithValidator( - "EnumFieldUnknownValue", + "EnumFieldUnknownValue", REQUIRED, R"({"optionalNestedEnum": 123})", [](const Json::Value& value) { return value["optionalNestedEnum"].type() == Json::intValue && @@ -1279,76 +1302,73 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // String fields. RunValidJsonTest( - "StringField", + "StringField", REQUIRED, R"({"optionalString": "Hello world!"})", "optional_string: \"Hello world!\""); RunValidJsonTest( - "StringFieldUnicode", + "StringFieldUnicode", REQUIRED, // Google in Chinese. R"({"optionalString": "谷歌"})", R"(optional_string: "谷歌")"); RunValidJsonTest( - "StringFieldEscape", + "StringFieldEscape", REQUIRED, R"({"optionalString": "\"\\\/\b\f\n\r\t"})", R"(optional_string: "\"\\/\b\f\n\r\t")"); RunValidJsonTest( - "StringFieldUnicodeEscape", + "StringFieldUnicodeEscape", REQUIRED, R"({"optionalString": "\u8C37\u6B4C"})", R"(optional_string: "谷歌")"); RunValidJsonTest( - "StringFieldUnicodeEscapeWithLowercaseHexLetters", + "StringFieldUnicodeEscapeWithLowercaseHexLetters", REQUIRED, R"({"optionalString": "\u8c37\u6b4c"})", R"(optional_string: "谷歌")"); RunValidJsonTest( - "StringFieldSurrogatePair", + "StringFieldSurrogatePair", REQUIRED, // The character is an emoji: grinning face with smiling eyes. 😁 R"({"optionalString": "\uD83D\uDE01"})", R"(optional_string: "\xF0\x9F\x98\x81")"); // Unicode escapes must start with "\u" (lowercase u). ExpectParseFailureForJson( - "StringFieldUppercaseEscapeLetter", + "StringFieldUppercaseEscapeLetter", RECOMMENDED, R"({"optionalString": "\U8C37\U6b4C"})"); ExpectParseFailureForJson( - "StringFieldInvalidEscape", + "StringFieldInvalidEscape", RECOMMENDED, R"({"optionalString": "\uXXXX\u6B4C"})"); ExpectParseFailureForJson( - "StringFieldUnterminatedEscape", + "StringFieldUnterminatedEscape", RECOMMENDED, R"({"optionalString": "\u8C3"})"); ExpectParseFailureForJson( - "StringFieldUnpairedHighSurrogate", + "StringFieldUnpairedHighSurrogate", RECOMMENDED, R"({"optionalString": "\uD800"})"); ExpectParseFailureForJson( - "StringFieldUnpairedLowSurrogate", + "StringFieldUnpairedLowSurrogate", RECOMMENDED, R"({"optionalString": "\uDC00"})"); ExpectParseFailureForJson( - "StringFieldSurrogateInWrongOrder", + "StringFieldSurrogateInWrongOrder", RECOMMENDED, R"({"optionalString": "\uDE01\uD83D"})"); ExpectParseFailureForJson( - "StringFieldNotAString", + "StringFieldNotAString", REQUIRED, R"({"optionalString": 12345})"); // Bytes fields. RunValidJsonTest( - "BytesField", + "BytesField", REQUIRED, R"({"optionalBytes": "AQI="})", R"(optional_bytes: "\x01\x02")"); ExpectParseFailureForJson( - "BytesFieldNoPadding", - R"({"optionalBytes": "AQI"})"); - ExpectParseFailureForJson( - "BytesFieldInvalidBase64Characters", + "BytesFieldInvalidBase64Characters", REQUIRED, R"({"optionalBytes": "-_=="})"); // Message fields. RunValidJsonTest( - "MessageField", + "MessageField", REQUIRED, R"({"optionalNestedMessage": {"a": 1234}})", "optional_nested_message: {a: 1234}"); // Oneof fields. ExpectParseFailureForJson( - "OneofFieldDuplicate", + "OneofFieldDuplicate", REQUIRED, R"({"oneofUint32": 1, "oneofString": "test"})"); // Ensure zero values for oneof make it out/backs. { @@ -1411,58 +1431,58 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Repeated fields. RunValidJsonTest( - "PrimitiveRepeatedField", + "PrimitiveRepeatedField", REQUIRED, R"({"repeatedInt32": [1, 2, 3, 4]})", "repeated_int32: [1, 2, 3, 4]"); RunValidJsonTest( - "EnumRepeatedField", + "EnumRepeatedField", REQUIRED, R"({"repeatedNestedEnum": ["FOO", "BAR", "BAZ"]})", "repeated_nested_enum: [FOO, BAR, BAZ]"); RunValidJsonTest( - "StringRepeatedField", + "StringRepeatedField", REQUIRED, R"({"repeatedString": ["Hello", "world"]})", R"(repeated_string: ["Hello", "world"])"); RunValidJsonTest( - "BytesRepeatedField", + "BytesRepeatedField", REQUIRED, R"({"repeatedBytes": ["AAEC", "AQI="]})", R"(repeated_bytes: ["\x00\x01\x02", "\x01\x02"])"); RunValidJsonTest( - "MessageRepeatedField", + "MessageRepeatedField", REQUIRED, R"({"repeatedNestedMessage": [{"a": 1234}, {"a": 5678}]})", "repeated_nested_message: {a: 1234}" "repeated_nested_message: {a: 5678}"); // Repeated field elements are of incorrect type. ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingIntegersGotBool", + "RepeatedFieldWrongElementTypeExpectingIntegersGotBool", REQUIRED, R"({"repeatedInt32": [1, false, 3, 4]})"); ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingIntegersGotString", + "RepeatedFieldWrongElementTypeExpectingIntegersGotString", REQUIRED, R"({"repeatedInt32": [1, 2, "name", 4]})"); ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage", + "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage", REQUIRED, R"({"repeatedInt32": [1, 2, 3, {"a": 4}]})"); ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingStringsGotInt", + "RepeatedFieldWrongElementTypeExpectingStringsGotInt", REQUIRED, R"({"repeatedString": ["1", 2, "3", "4"]})"); ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingStringsGotBool", + "RepeatedFieldWrongElementTypeExpectingStringsGotBool", REQUIRED, R"({"repeatedString": ["1", "2", false, "4"]})"); ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingStringsGotMessage", + "RepeatedFieldWrongElementTypeExpectingStringsGotMessage", REQUIRED, R"({"repeatedString": ["1", 2, "3", {"a": 4}]})"); ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingMessagesGotInt", + "RepeatedFieldWrongElementTypeExpectingMessagesGotInt", REQUIRED, R"({"repeatedNestedMessage": [{"a": 1}, 2]})"); ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingMessagesGotBool", + "RepeatedFieldWrongElementTypeExpectingMessagesGotBool", REQUIRED, R"({"repeatedNestedMessage": [{"a": 1}, false]})"); ExpectParseFailureForJson( - "RepeatedFieldWrongElementTypeExpectingMessagesGotString", + "RepeatedFieldWrongElementTypeExpectingMessagesGotString", REQUIRED, R"({"repeatedNestedMessage": [{"a": 1}, "2"]})"); // Trailing comma in the repeated field is not allowed. ExpectParseFailureForJson( - "RepeatedFieldTrailingComma", + "RepeatedFieldTrailingComma", RECOMMENDED, R"({"repeatedInt32": [1, 2, 3, 4,]})"); ExpectParseFailureForJson( "RepeatedFieldTrailingCommaWithSpace", @@ -1476,47 +1496,47 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Map fields. RunValidJsonTest( - "Int32MapField", + "Int32MapField", REQUIRED, R"({"mapInt32Int32": {"1": 2, "3": 4}})", "map_int32_int32: {key: 1 value: 2}" "map_int32_int32: {key: 3 value: 4}"); ExpectParseFailureForJson( - "Int32MapFieldKeyNotQuoted", + "Int32MapFieldKeyNotQuoted", RECOMMENDED, R"({"mapInt32Int32": {1: 2, 3: 4}})"); RunValidJsonTest( - "Uint32MapField", + "Uint32MapField", REQUIRED, R"({"mapUint32Uint32": {"1": 2, "3": 4}})", "map_uint32_uint32: {key: 1 value: 2}" "map_uint32_uint32: {key: 3 value: 4}"); ExpectParseFailureForJson( - "Uint32MapFieldKeyNotQuoted", + "Uint32MapFieldKeyNotQuoted", RECOMMENDED, R"({"mapUint32Uint32": {1: 2, 3: 4}})"); RunValidJsonTest( - "Int64MapField", + "Int64MapField", REQUIRED, R"({"mapInt64Int64": {"1": 2, "3": 4}})", "map_int64_int64: {key: 1 value: 2}" "map_int64_int64: {key: 3 value: 4}"); ExpectParseFailureForJson( - "Int64MapFieldKeyNotQuoted", + "Int64MapFieldKeyNotQuoted", RECOMMENDED, R"({"mapInt64Int64": {1: 2, 3: 4}})"); RunValidJsonTest( - "Uint64MapField", + "Uint64MapField", REQUIRED, R"({"mapUint64Uint64": {"1": 2, "3": 4}})", "map_uint64_uint64: {key: 1 value: 2}" "map_uint64_uint64: {key: 3 value: 4}"); ExpectParseFailureForJson( - "Uint64MapFieldKeyNotQuoted", + "Uint64MapFieldKeyNotQuoted", RECOMMENDED, R"({"mapUint64Uint64": {1: 2, 3: 4}})"); RunValidJsonTest( - "BoolMapField", + "BoolMapField", REQUIRED, R"({"mapBoolBool": {"true": true, "false": false}})", "map_bool_bool: {key: true value: true}" "map_bool_bool: {key: false value: false}"); ExpectParseFailureForJson( - "BoolMapFieldKeyNotQuoted", + "BoolMapFieldKeyNotQuoted", RECOMMENDED, R"({"mapBoolBool": {true: true, false: false}})"); RunValidJsonTest( - "MessageMapField", + "MessageMapField", REQUIRED, R"({ "mapStringNestedMessage": { "hello": {"a": 1234}, @@ -1535,21 +1555,21 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, )"); // Since Map keys are represented as JSON strings, escaping should be allowed. RunValidJsonTest( - "Int32MapEscapedKey", + "Int32MapEscapedKey", REQUIRED, R"({"mapInt32Int32": {"\u0031": 2}})", "map_int32_int32: {key: 1 value: 2}"); RunValidJsonTest( - "Int64MapEscapedKey", + "Int64MapEscapedKey", REQUIRED, R"({"mapInt64Int64": {"\u0031": 2}})", "map_int64_int64: {key: 1 value: 2}"); RunValidJsonTest( - "BoolMapEscapedKey", + "BoolMapEscapedKey", REQUIRED, R"({"mapBoolBool": {"tr\u0075e": true}})", "map_bool_bool: {key: true value: true}"); // "null" is accepted for all fields types. RunValidJsonTest( - "AllFieldAcceptNull", + "AllFieldAcceptNull", REQUIRED, R"({ "optionalInt32": null, "optionalInt64": null, @@ -1577,18 +1597,18 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Repeated field elements cannot be null. ExpectParseFailureForJson( - "RepeatedFieldPrimitiveElementIsNull", + "RepeatedFieldPrimitiveElementIsNull", RECOMMENDED, R"({"repeatedInt32": [1, null, 2]})"); ExpectParseFailureForJson( - "RepeatedFieldMessageElementIsNull", + "RepeatedFieldMessageElementIsNull", RECOMMENDED, R"({"repeatedNestedMessage": [{"a":1}, null, {"a":2}]})"); // Map field keys cannot be null. ExpectParseFailureForJson( - "MapFieldKeyIsNull", + "MapFieldKeyIsNull", RECOMMENDED, R"({"mapInt32Int32": {null: 1}})"); // Map field values cannot be null. ExpectParseFailureForJson( - "MapFieldValueIsNull", + "MapFieldValueIsNull", RECOMMENDED, R"({"mapInt32Int32": {"0": null}})"); // http://www.rfc-editor.org/rfc/rfc7159.txt says strings have to use double @@ -1605,43 +1625,43 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Wrapper types. RunValidJsonTest( - "OptionalBoolWrapper", + "OptionalBoolWrapper", REQUIRED, R"({"optionalBoolWrapper": false})", "optional_bool_wrapper: {value: false}"); RunValidJsonTest( - "OptionalInt32Wrapper", + "OptionalInt32Wrapper", REQUIRED, R"({"optionalInt32Wrapper": 0})", "optional_int32_wrapper: {value: 0}"); RunValidJsonTest( - "OptionalUint32Wrapper", + "OptionalUint32Wrapper", REQUIRED, R"({"optionalUint32Wrapper": 0})", "optional_uint32_wrapper: {value: 0}"); RunValidJsonTest( - "OptionalInt64Wrapper", + "OptionalInt64Wrapper", REQUIRED, R"({"optionalInt64Wrapper": 0})", "optional_int64_wrapper: {value: 0}"); RunValidJsonTest( - "OptionalUint64Wrapper", + "OptionalUint64Wrapper", REQUIRED, R"({"optionalUint64Wrapper": 0})", "optional_uint64_wrapper: {value: 0}"); RunValidJsonTest( - "OptionalFloatWrapper", + "OptionalFloatWrapper", REQUIRED, R"({"optionalFloatWrapper": 0})", "optional_float_wrapper: {value: 0}"); RunValidJsonTest( - "OptionalDoubleWrapper", + "OptionalDoubleWrapper", REQUIRED, R"({"optionalDoubleWrapper": 0})", "optional_double_wrapper: {value: 0}"); RunValidJsonTest( - "OptionalStringWrapper", + "OptionalStringWrapper", REQUIRED, R"({"optionalStringWrapper": ""})", R"(optional_string_wrapper: {value: ""})"); RunValidJsonTest( - "OptionalBytesWrapper", + "OptionalBytesWrapper", REQUIRED, R"({"optionalBytesWrapper": ""})", R"(optional_bytes_wrapper: {value: ""})"); RunValidJsonTest( - "OptionalWrapperTypesWithNonDefaultValue", + "OptionalWrapperTypesWithNonDefaultValue", REQUIRED, R"({ "optionalBoolWrapper": true, "optionalInt32Wrapper": 1, @@ -1665,56 +1685,56 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, optional_bytes_wrapper: {value: "\x01\x02"} )"); RunValidJsonTest( - "RepeatedBoolWrapper", + "RepeatedBoolWrapper", REQUIRED, R"({"repeatedBoolWrapper": [true, false]})", "repeated_bool_wrapper: {value: true}" "repeated_bool_wrapper: {value: false}"); RunValidJsonTest( - "RepeatedInt32Wrapper", + "RepeatedInt32Wrapper", REQUIRED, R"({"repeatedInt32Wrapper": [0, 1]})", "repeated_int32_wrapper: {value: 0}" "repeated_int32_wrapper: {value: 1}"); RunValidJsonTest( - "RepeatedUint32Wrapper", + "RepeatedUint32Wrapper", REQUIRED, R"({"repeatedUint32Wrapper": [0, 1]})", "repeated_uint32_wrapper: {value: 0}" "repeated_uint32_wrapper: {value: 1}"); RunValidJsonTest( - "RepeatedInt64Wrapper", + "RepeatedInt64Wrapper", REQUIRED, R"({"repeatedInt64Wrapper": [0, 1]})", "repeated_int64_wrapper: {value: 0}" "repeated_int64_wrapper: {value: 1}"); RunValidJsonTest( - "RepeatedUint64Wrapper", + "RepeatedUint64Wrapper", REQUIRED, R"({"repeatedUint64Wrapper": [0, 1]})", "repeated_uint64_wrapper: {value: 0}" "repeated_uint64_wrapper: {value: 1}"); RunValidJsonTest( - "RepeatedFloatWrapper", + "RepeatedFloatWrapper", REQUIRED, R"({"repeatedFloatWrapper": [0, 1]})", "repeated_float_wrapper: {value: 0}" "repeated_float_wrapper: {value: 1}"); RunValidJsonTest( - "RepeatedDoubleWrapper", + "RepeatedDoubleWrapper", REQUIRED, R"({"repeatedDoubleWrapper": [0, 1]})", "repeated_double_wrapper: {value: 0}" "repeated_double_wrapper: {value: 1}"); RunValidJsonTest( - "RepeatedStringWrapper", + "RepeatedStringWrapper", REQUIRED, R"({"repeatedStringWrapper": ["", "AQI="]})", R"( repeated_string_wrapper: {value: ""} repeated_string_wrapper: {value: "AQI="} )"); RunValidJsonTest( - "RepeatedBytesWrapper", + "RepeatedBytesWrapper", REQUIRED, R"({"repeatedBytesWrapper": ["", "AQI="]})", R"( repeated_bytes_wrapper: {value: ""} repeated_bytes_wrapper: {value: "\x01\x02"} )"); RunValidJsonTest( - "WrapperTypesWithNullValue", + "WrapperTypesWithNullValue", REQUIRED, R"({ "optionalBoolWrapper": null, "optionalInt32Wrapper": null, @@ -1739,55 +1759,55 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Duration RunValidJsonTest( - "DurationMinValue", + "DurationMinValue", REQUIRED, R"({"optionalDuration": "-315576000000.999999999s"})", "optional_duration: {seconds: -315576000000 nanos: -999999999}"); RunValidJsonTest( - "DurationMaxValue", + "DurationMaxValue", REQUIRED, R"({"optionalDuration": "315576000000.999999999s"})", "optional_duration: {seconds: 315576000000 nanos: 999999999}"); RunValidJsonTest( - "DurationRepeatedValue", + "DurationRepeatedValue", REQUIRED, R"({"repeatedDuration": ["1.5s", "-1.5s"]})", "repeated_duration: {seconds: 1 nanos: 500000000}" "repeated_duration: {seconds: -1 nanos: -500000000}"); ExpectParseFailureForJson( - "DurationMissingS", + "DurationMissingS", REQUIRED, R"({"optionalDuration": "1"})"); ExpectParseFailureForJson( - "DurationJsonInputTooSmall", + "DurationJsonInputTooSmall", REQUIRED, R"({"optionalDuration": "-315576000001.000000000s"})"); ExpectParseFailureForJson( - "DurationJsonInputTooLarge", + "DurationJsonInputTooLarge", REQUIRED, R"({"optionalDuration": "315576000001.000000000s"})"); ExpectSerializeFailureForJson( - "DurationProtoInputTooSmall", + "DurationProtoInputTooSmall", REQUIRED, "optional_duration: {seconds: -315576000001 nanos: 0}"); ExpectSerializeFailureForJson( - "DurationProtoInputTooLarge", + "DurationProtoInputTooLarge", REQUIRED, "optional_duration: {seconds: 315576000001 nanos: 0}"); RunValidJsonTestWithValidator( - "DurationHasZeroFractionalDigit", + "DurationHasZeroFractionalDigit", RECOMMENDED, R"({"optionalDuration": "1.000000000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1s"; }); RunValidJsonTestWithValidator( - "DurationHas3FractionalDigits", + "DurationHas3FractionalDigits", RECOMMENDED, R"({"optionalDuration": "1.010000000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.010s"; }); RunValidJsonTestWithValidator( - "DurationHas6FractionalDigits", + "DurationHas6FractionalDigits", RECOMMENDED, R"({"optionalDuration": "1.000010000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.000010s"; }); RunValidJsonTestWithValidator( - "DurationHas9FractionalDigits", + "DurationHas9FractionalDigits", RECOMMENDED, R"({"optionalDuration": "1.000000010s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.000000010s"; @@ -1795,15 +1815,15 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Timestamp RunValidJsonTest( - "TimestampMinValue", + "TimestampMinValue", REQUIRED, R"({"optionalTimestamp": "0001-01-01T00:00:00Z"})", "optional_timestamp: {seconds: -62135596800}"); RunValidJsonTest( - "TimestampMaxValue", + "TimestampMaxValue", REQUIRED, R"({"optionalTimestamp": "9999-12-31T23:59:59.999999999Z"})", "optional_timestamp: {seconds: 253402300799 nanos: 999999999}"); RunValidJsonTest( - "TimestampRepeatedValue", + "TimestampRepeatedValue", REQUIRED, R"({ "repeatedTimestamp": [ "0001-01-01T00:00:00Z", @@ -1813,68 +1833,68 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, "repeated_timestamp: {seconds: -62135596800}" "repeated_timestamp: {seconds: 253402300799 nanos: 999999999}"); RunValidJsonTest( - "TimestampWithPositiveOffset", + "TimestampWithPositiveOffset", REQUIRED, R"({"optionalTimestamp": "1970-01-01T08:00:00+08:00"})", "optional_timestamp: {seconds: 0}"); RunValidJsonTest( - "TimestampWithNegativeOffset", + "TimestampWithNegativeOffset", REQUIRED, R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})", "optional_timestamp: {seconds: 0}"); ExpectParseFailureForJson( - "TimestampJsonInputTooSmall", + "TimestampJsonInputTooSmall", REQUIRED, R"({"optionalTimestamp": "0000-01-01T00:00:00Z"})"); ExpectParseFailureForJson( - "TimestampJsonInputTooLarge", + "TimestampJsonInputTooLarge", REQUIRED, R"({"optionalTimestamp": "10000-01-01T00:00:00Z"})"); ExpectParseFailureForJson( - "TimestampJsonInputMissingZ", + "TimestampJsonInputMissingZ", REQUIRED, R"({"optionalTimestamp": "0001-01-01T00:00:00"})"); ExpectParseFailureForJson( - "TimestampJsonInputMissingT", + "TimestampJsonInputMissingT", REQUIRED, R"({"optionalTimestamp": "0001-01-01 00:00:00Z"})"); ExpectParseFailureForJson( - "TimestampJsonInputLowercaseZ", + "TimestampJsonInputLowercaseZ", REQUIRED, R"({"optionalTimestamp": "0001-01-01T00:00:00z"})"); ExpectParseFailureForJson( - "TimestampJsonInputLowercaseT", + "TimestampJsonInputLowercaseT", REQUIRED, R"({"optionalTimestamp": "0001-01-01t00:00:00Z"})"); ExpectSerializeFailureForJson( - "TimestampProtoInputTooSmall", + "TimestampProtoInputTooSmall", REQUIRED, "optional_timestamp: {seconds: -62135596801}"); ExpectSerializeFailureForJson( - "TimestampProtoInputTooLarge", + "TimestampProtoInputTooLarge", REQUIRED, "optional_timestamp: {seconds: 253402300800}"); RunValidJsonTestWithValidator( - "TimestampZeroNormalized", + "TimestampZeroNormalized", RECOMMENDED, R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00Z"; }); RunValidJsonTestWithValidator( - "TimestampHasZeroFractionalDigit", + "TimestampHasZeroFractionalDigit", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00Z"; }); RunValidJsonTestWithValidator( - "TimestampHas3FractionalDigits", + "TimestampHas3FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.010Z"; }); RunValidJsonTestWithValidator( - "TimestampHas6FractionalDigits", + "TimestampHas6FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.000010Z"; }); RunValidJsonTestWithValidator( - "TimestampHas9FractionalDigits", + "TimestampHas9FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == @@ -1883,25 +1903,25 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // FieldMask RunValidJsonTest( - "FieldMask", + "FieldMask", REQUIRED, R"({"optionalFieldMask": "foo,barBaz"})", R"(optional_field_mask: {paths: "foo" paths: "bar_baz"})"); ExpectParseFailureForJson( - "FieldMaskInvalidCharacter", + "FieldMaskInvalidCharacter", RECOMMENDED, R"({"optionalFieldMask": "foo,bar_bar"})"); ExpectSerializeFailureForJson( - "FieldMaskPathsDontRoundTrip", + "FieldMaskPathsDontRoundTrip", RECOMMENDED, R"(optional_field_mask: {paths: "fooBar"})"); ExpectSerializeFailureForJson( - "FieldMaskNumbersDontRoundTrip", + "FieldMaskNumbersDontRoundTrip", RECOMMENDED, R"(optional_field_mask: {paths: "foo_3_bar"})"); ExpectSerializeFailureForJson( - "FieldMaskTooManyUnderscore", + "FieldMaskTooManyUnderscore", RECOMMENDED, R"(optional_field_mask: {paths: "foo__bar"})"); // Struct RunValidJsonTest( - "Struct", + "Struct", REQUIRED, R"({ "optionalStruct": { "nullValue": null, @@ -1967,27 +1987,27 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, )"); // Value RunValidJsonTest( - "ValueAcceptInteger", + "ValueAcceptInteger", REQUIRED, R"({"optionalValue": 1})", "optional_value: { number_value: 1}"); RunValidJsonTest( - "ValueAcceptFloat", + "ValueAcceptFloat", REQUIRED, R"({"optionalValue": 1.5})", "optional_value: { number_value: 1.5}"); RunValidJsonTest( - "ValueAcceptBool", + "ValueAcceptBool", REQUIRED, R"({"optionalValue": false})", "optional_value: { bool_value: false}"); RunValidJsonTest( - "ValueAcceptNull", + "ValueAcceptNull", REQUIRED, R"({"optionalValue": null})", "optional_value: { null_value: NULL_VALUE}"); RunValidJsonTest( - "ValueAcceptString", + "ValueAcceptString", REQUIRED, R"({"optionalValue": "hello"})", R"(optional_value: { string_value: "hello"})"); RunValidJsonTest( - "ValueAcceptList", + "ValueAcceptList", REQUIRED, R"({"optionalValue": [0, "hello"]})", R"( optional_value: { @@ -2002,7 +2022,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); RunValidJsonTest( - "ValueAcceptObject", + "ValueAcceptObject", REQUIRED, R"({"optionalValue": {"value": 1}})", R"( optional_value: { @@ -2019,7 +2039,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, // Any RunValidJsonTest( - "Any", + "Any", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/conformance.TestAllTypes", @@ -2034,7 +2054,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); RunValidJsonTest( - "AnyNested", + "AnyNested", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Any", @@ -2055,7 +2075,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, )"); // The special "@type" tag is not required to appear first. RunValidJsonTest( - "AnyUnorderedTypeTag", + "AnyUnorderedTypeTag", REQUIRED, R"({ "optionalAny": { "optionalInt32": 12345, @@ -2071,7 +2091,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, )"); // Well-known types in Any. RunValidJsonTest( - "AnyWithInt32ValueWrapper", + "AnyWithInt32ValueWrapper", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Int32Value", @@ -2086,7 +2106,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); RunValidJsonTest( - "AnyWithDuration", + "AnyWithDuration", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Duration", @@ -2102,7 +2122,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); RunValidJsonTest( - "AnyWithTimestamp", + "AnyWithTimestamp", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Timestamp", @@ -2118,7 +2138,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); RunValidJsonTest( - "AnyWithFieldMask", + "AnyWithFieldMask", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.FieldMask", @@ -2133,7 +2153,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); RunValidJsonTest( - "AnyWithStruct", + "AnyWithStruct", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Struct", @@ -2155,7 +2175,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); RunValidJsonTest( - "AnyWithValueForJsonObject", + "AnyWithValueForJsonObject", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Value", @@ -2179,7 +2199,7 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); RunValidJsonTest( - "AnyWithValueForInteger", + "AnyWithValueForInteger", REQUIRED, R"({ "optionalAny": { "@type": "type.googleapis.com/google.protobuf.Value", diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index 56689318..2e6fc5d7 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -91,7 +91,7 @@ class ConformanceTestRunner { // class ConformanceTestSuite { public: - ConformanceTestSuite() : verbose_(false) {} + ConformanceTestSuite() : verbose_(false), enforce_recommended_(false) {} void SetVerbose(bool verbose) { verbose_ = verbose; } @@ -104,6 +104,18 @@ class ConformanceTestSuite { void SetFailureList(const std::string& filename, const std::vector& failure_list); + // Whether to require the testee to pass RECOMMENDED tests. By default failing + // a RECOMMENDED test case will not fail the entire suite but will only + // generated a warning. If this flag is set to true, RECOMMENDED tests will + // be treated the same way as REQUIRED tests and failing a RECOMMENDED test + // case will cause the entire test suite to fail as well. An implementation + // can enable this if it wants to be strictly conforming to protobuf spec. + // See the comments about ConformanceLevel below to learn more about the + // difference between REQUIRED and RECOMMENDED test cases. + void SetEnforceRecommended(bool value) { + enforce_recommended_ = value; + } + // Run all the conformance tests against the given test runner. // Test output will be stored in "output". // @@ -113,8 +125,27 @@ class ConformanceTestSuite { bool RunSuite(ConformanceTestRunner* runner, std::string* output); private: + // Test cases are classified into a few categories: + // REQUIRED: the test case must be passed for an implementation to be + // interoperable with other implementations. For example, a + // parser implementaiton must accept both packed and unpacked + // form of repeated primitive fields. + // RECOMMENDED: the test case is not required for the implementation to + // be interoperable with other implementations, but is + // recommended for best performance and compatibility. For + // example, a proto3 serializer should serialize repeated + // primitive fields in packed form, but an implementation + // failing to do so will still be able to communicate with + // other implementations. + enum ConformanceLevel { + REQUIRED = 0, + RECOMMENDED = 1, + }; + string ConformanceLevelToString(ConformanceLevel level); + void ReportSuccess(const std::string& test_name); void ReportFailure(const string& test_name, + ConformanceLevel level, const conformance::ConformanceRequest& request, const conformance::ConformanceResponse& response, const char* fmt, ...); @@ -124,13 +155,18 @@ class ConformanceTestSuite { void RunTest(const std::string& test_name, const conformance::ConformanceRequest& request, conformance::ConformanceResponse* response); - void RunValidInputTest(const string& test_name, const string& input, + void RunValidInputTest(const string& test_name, + ConformanceLevel level, + const string& input, conformance::WireFormat input_format, const string& equivalent_text_format, conformance::WireFormat requested_output); - void RunValidJsonTest(const string& test_name, const string& input_json, + void RunValidJsonTest(const string& test_name, + ConformanceLevel level, + const string& input_json, const string& equivalent_text_format); void RunValidJsonTestWithProtobufInput(const string& test_name, + ConformanceLevel level, const conformance::TestAllTypes& input, const string& equivalent_text_format); void RunValidProtobufTest(const string& test_name, @@ -139,16 +175,21 @@ class ConformanceTestSuite { typedef std::function Validator; void RunValidJsonTestWithValidator(const string& test_name, + ConformanceLevel level, const string& input_json, const Validator& validator); void ExpectParseFailureForJson(const string& test_name, + ConformanceLevel level, const string& input_json); void ExpectSerializeFailureForJson(const string& test_name, + ConformanceLevel level, const string& text_format); void ExpectParseFailureForProto(const std::string& proto, - const std::string& test_name); + const std::string& test_name, + ConformanceLevel level); void ExpectHardParseFailureForProto(const std::string& proto, - const std::string& test_name); + const std::string& test_name, + ConformanceLevel level); void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type); bool CheckSetEmpty(const set& set_to_check, const std::string& write_to_file, const std::string& msg); @@ -156,6 +197,7 @@ class ConformanceTestSuite { int successes_; int expected_failures_; bool verbose_; + bool enforce_recommended_; std::string output_; std::string failure_list_filename_; diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc index d6b1175c..7e91d388 100644 --- a/conformance/conformance_test_runner.cc +++ b/conformance/conformance_test_runner.cc @@ -251,6 +251,16 @@ void UsageError() { " should contain one test name per\n"); fprintf(stderr, " line. Use '#' for comments.\n"); + fprintf(stderr, + " --enforce_recommended Enforce that recommended test\n"); + fprintf(stderr, + " cases are also passing. Specify\n"); + fprintf(stderr, + " this flag if you want to be\n"); + fprintf(stderr, + " strictly conforming to protobuf\n"); + fprintf(stderr, + " spec.\n"); exit(1); } @@ -290,6 +300,8 @@ int main(int argc, char *argv[]) { ParseFailureList(argv[arg], &failure_list); } else if (strcmp(argv[arg], "--verbose") == 0) { suite.SetVerbose(true); + } else if (strcmp(argv[arg], "--enforce_recommended") == 0) { + suite.SetEnforceRecommended(true); } else if (argv[arg][0] == '-') { fprintf(stderr, "Unknown option: %s\n", argv[arg]); UsageError(); diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt index 5e17176e..fcaa08bd 100644 --- a/conformance/failure_list_cpp.txt +++ b/conformance/failure_list_cpp.txt @@ -7,48 +7,41 @@ # TODO(haberman): insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? -FieldMaskNumbersDontRoundTrip.JsonOutput -FieldMaskPathsDontRoundTrip.JsonOutput -FieldMaskTooManyUnderscore.JsonOutput -JsonInput.AnyUnorderedTypeTag.JsonOutput -JsonInput.AnyUnorderedTypeTag.ProtobufOutput -JsonInput.BoolFieldDoubleQuotedFalse -JsonInput.BoolFieldDoubleQuotedTrue -JsonInput.BytesFieldNoPadding -JsonInput.DoubleFieldTooSmall -JsonInput.DurationHasZeroFractionalDigit.Validator -JsonInput.EnumFieldUnknownValue.Validator -JsonInput.FieldMaskInvalidCharacter -JsonInput.FieldNameDuplicate -JsonInput.FieldNameDuplicateDifferentCasing1 -JsonInput.FieldNameDuplicateDifferentCasing2 -JsonInput.FieldNameNotQuoted -JsonInput.MapFieldValueIsNull -JsonInput.RepeatedFieldMessageElementIsNull -JsonInput.RepeatedFieldPrimitiveElementIsNull -JsonInput.RepeatedFieldTrailingComma -JsonInput.RepeatedFieldTrailingCommaWithNewlines -JsonInput.RepeatedFieldTrailingCommaWithSpace -JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace -JsonInput.StringFieldSingleQuoteBoth -JsonInput.StringFieldSingleQuoteKey -JsonInput.StringFieldSingleQuoteValue -JsonInput.StringFieldUppercaseEscapeLetter -JsonInput.TrailingCommaInAnObject -JsonInput.TrailingCommaInAnObjectWithNewlines -JsonInput.TrailingCommaInAnObjectWithSpace -JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace -JsonInput.WrapperTypesWithNullValue.JsonOutput -JsonInput.WrapperTypesWithNullValue.ProtobufOutput -ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE -ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE -ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE -ProtobufInput.PrematureEofInPackedField.BOOL -ProtobufInput.PrematureEofInPackedField.ENUM -ProtobufInput.PrematureEofInPackedField.INT32 -ProtobufInput.PrematureEofInPackedField.INT64 -ProtobufInput.PrematureEofInPackedField.SINT32 -ProtobufInput.PrematureEofInPackedField.SINT64 -ProtobufInput.PrematureEofInPackedField.UINT32 -ProtobufInput.PrematureEofInPackedField.UINT64 -ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE +Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput +Recommended.FieldMaskPathsDontRoundTrip.JsonOutput +Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.JsonInput.BoolFieldDoubleQuotedFalse +Recommended.JsonInput.BoolFieldDoubleQuotedTrue +Recommended.JsonInput.FieldMaskInvalidCharacter +Recommended.JsonInput.FieldNameDuplicate +Recommended.JsonInput.FieldNameDuplicateDifferentCasing1 +Recommended.JsonInput.FieldNameDuplicateDifferentCasing2 +Recommended.JsonInput.FieldNameNotQuoted +Recommended.JsonInput.MapFieldValueIsNull +Recommended.JsonInput.RepeatedFieldMessageElementIsNull +Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull +Recommended.JsonInput.RepeatedFieldTrailingComma +Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines +Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace +Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace +Recommended.JsonInput.StringFieldSingleQuoteBoth +Recommended.JsonInput.StringFieldSingleQuoteKey +Recommended.JsonInput.StringFieldSingleQuoteValue +Recommended.JsonInput.StringFieldUppercaseEscapeLetter +Recommended.JsonInput.TrailingCommaInAnObject +Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines +Recommended.JsonInput.TrailingCommaInAnObjectWithSpace +Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace +Required.JsonInput.DoubleFieldTooSmall +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInPackedField.BOOL +Required.ProtobufInput.PrematureEofInPackedField.ENUM +Required.ProtobufInput.PrematureEofInPackedField.INT32 +Required.ProtobufInput.PrematureEofInPackedField.INT64 +Required.ProtobufInput.PrematureEofInPackedField.SINT32 +Required.ProtobufInput.PrematureEofInPackedField.SINT64 +Required.ProtobufInput.PrematureEofInPackedField.UINT32 +Required.ProtobufInput.PrematureEofInPackedField.UINT64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt index b2122c8b..440696db 100644 --- a/conformance/failure_list_java.txt +++ b/conformance/failure_list_java.txt @@ -4,48 +4,46 @@ # By listing them here we can keep tabs on which ones are failing and be sure # that we don't introduce regressions in other tests. -FieldMaskNumbersDontRoundTrip.JsonOutput -FieldMaskPathsDontRoundTrip.JsonOutput -FieldMaskTooManyUnderscore.JsonOutput -JsonInput.BoolFieldAllCapitalFalse -JsonInput.BoolFieldAllCapitalTrue -JsonInput.BoolFieldCamelCaseFalse -JsonInput.BoolFieldCamelCaseTrue -JsonInput.BoolFieldDoubleQuotedFalse -JsonInput.BoolFieldDoubleQuotedTrue -JsonInput.BoolMapFieldKeyNotQuoted -JsonInput.DoubleFieldInfinityNotQuoted -JsonInput.DoubleFieldNanNotQuoted -JsonInput.DoubleFieldNegativeInfinityNotQuoted -JsonInput.EnumFieldNotQuoted -JsonInput.FieldMaskInvalidCharacter -JsonInput.FieldNameDuplicate -JsonInput.FieldNameInLowerCamelCase.Validator -JsonInput.FieldNameInSnakeCase.JsonOutput -JsonInput.FieldNameInSnakeCase.ProtobufOutput -JsonInput.FieldNameNotQuoted -JsonInput.FieldNameWithDoubleUnderscores.JsonOutput -JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput -JsonInput.FieldNameWithDoubleUnderscores.Validator -JsonInput.FloatFieldInfinityNotQuoted -JsonInput.FloatFieldNanNotQuoted -JsonInput.FloatFieldNegativeInfinityNotQuoted -JsonInput.Int32FieldLeadingZero -JsonInput.Int32FieldNegativeWithLeadingZero -JsonInput.Int32FieldPlusSign -JsonInput.Int32MapFieldKeyNotQuoted -JsonInput.Int64MapFieldKeyNotQuoted -JsonInput.JsonWithComments -JsonInput.OriginalProtoFieldName.JsonOutput -JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool -JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt -JsonInput.StringFieldNotAString -JsonInput.StringFieldSingleQuoteBoth -JsonInput.StringFieldSingleQuoteKey -JsonInput.StringFieldSingleQuoteValue -JsonInput.StringFieldSurrogateInWrongOrder -JsonInput.StringFieldUnpairedHighSurrogate -JsonInput.StringFieldUnpairedLowSurrogate -JsonInput.StringFieldUppercaseEscapeLetter -JsonInput.Uint32MapFieldKeyNotQuoted -JsonInput.Uint64MapFieldKeyNotQuoted +Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput +Recommended.FieldMaskPathsDontRoundTrip.JsonOutput +Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.JsonInput.BoolFieldAllCapitalFalse +Recommended.JsonInput.BoolFieldAllCapitalTrue +Recommended.JsonInput.BoolFieldCamelCaseFalse +Recommended.JsonInput.BoolFieldCamelCaseTrue +Recommended.JsonInput.BoolFieldDoubleQuotedFalse +Recommended.JsonInput.BoolFieldDoubleQuotedTrue +Recommended.JsonInput.BoolMapFieldKeyNotQuoted +Recommended.JsonInput.DoubleFieldInfinityNotQuoted +Recommended.JsonInput.DoubleFieldNanNotQuoted +Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted +Recommended.JsonInput.FieldMaskInvalidCharacter +Recommended.JsonInput.FieldNameDuplicate +Recommended.JsonInput.FieldNameInLowerCamelCase.Validator +Recommended.JsonInput.FieldNameInSnakeCase.ProtobufOutput +Recommended.JsonInput.FieldNameNotQuoted +Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput +Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput +Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator +Recommended.JsonInput.FloatFieldInfinityNotQuoted +Recommended.JsonInput.FloatFieldNanNotQuoted +Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted +Recommended.JsonInput.Int32MapFieldKeyNotQuoted +Recommended.JsonInput.Int64MapFieldKeyNotQuoted +Recommended.JsonInput.JsonWithComments +Recommended.JsonInput.StringFieldSingleQuoteBoth +Recommended.JsonInput.StringFieldSingleQuoteKey +Recommended.JsonInput.StringFieldSingleQuoteValue +Recommended.JsonInput.StringFieldSurrogateInWrongOrder +Recommended.JsonInput.StringFieldUnpairedHighSurrogate +Recommended.JsonInput.StringFieldUnpairedLowSurrogate +Recommended.JsonInput.StringFieldUppercaseEscapeLetter +Recommended.JsonInput.Uint32MapFieldKeyNotQuoted +Recommended.JsonInput.Uint64MapFieldKeyNotQuoted +Required.JsonInput.EnumFieldNotQuoted +Required.JsonInput.Int32FieldLeadingZero +Required.JsonInput.Int32FieldNegativeWithLeadingZero +Required.JsonInput.Int32FieldPlusSign +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt +Required.JsonInput.StringFieldNotAString diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index d38b7828..84635670 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -1,46 +1,15 @@ -DurationProtoInputTooLarge.JsonOutput -DurationProtoInputTooSmall.JsonOutput -FieldMaskNumbersDontRoundTrip.JsonOutput -FieldMaskPathsDontRoundTrip.JsonOutput -FieldMaskTooManyUnderscore.JsonOutput -JsonInput.AnyWithFieldMask.ProtobufOutput -JsonInput.BytesFieldInvalidBase64Characters -JsonInput.DoubleFieldInfinityNotQuoted -JsonInput.DoubleFieldNanNotQuoted -JsonInput.DoubleFieldNegativeInfinityNotQuoted -JsonInput.DoubleFieldTooSmall -JsonInput.DurationJsonInputTooLarge -JsonInput.DurationJsonInputTooSmall -JsonInput.DurationMissingS -JsonInput.EnumFieldNumericValueNonZero.JsonOutput -JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput -JsonInput.EnumFieldNumericValueZero.JsonOutput -JsonInput.EnumFieldNumericValueZero.ProtobufOutput -JsonInput.EnumFieldUnknownValue.Validator -JsonInput.FieldMask.ProtobufOutput -JsonInput.FieldMaskInvalidCharacter -JsonInput.FloatFieldInfinityNotQuoted -JsonInput.FloatFieldNanNotQuoted -JsonInput.FloatFieldNegativeInfinityNotQuoted -JsonInput.FloatFieldTooLarge -JsonInput.FloatFieldTooSmall -JsonInput.Int32FieldExponentialFormat.JsonOutput -JsonInput.Int32FieldExponentialFormat.ProtobufOutput -JsonInput.Int32FieldFloatTrailingZero.JsonOutput -JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput -JsonInput.Int32FieldMaxFloatValue.JsonOutput -JsonInput.Int32FieldMaxFloatValue.ProtobufOutput -JsonInput.Int32FieldMinFloatValue.JsonOutput -JsonInput.Int32FieldMinFloatValue.ProtobufOutput -JsonInput.OneofZeroMessage.JsonOutput -JsonInput.OneofZeroMessage.ProtobufOutput -JsonInput.OriginalProtoFieldName.JsonOutput -JsonInput.OriginalProtoFieldName.ProtobufOutput -JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool -JsonInput.TimestampJsonInputLowercaseT -JsonInput.Uint32FieldMaxFloatValue.JsonOutput -JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput -JsonInput.ValueAcceptNull.JsonOutput -JsonInput.ValueAcceptNull.ProtobufOutput -TimestampProtoInputTooLarge.JsonOutput -TimestampProtoInputTooSmall.JsonOutput +Recommended.JsonInput.DoubleFieldInfinityNotQuoted +Recommended.JsonInput.DoubleFieldNanNotQuoted +Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted +Recommended.JsonInput.FloatFieldInfinityNotQuoted +Recommended.JsonInput.FloatFieldNanNotQuoted +Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted +Recommended.JsonInput.OneofZeroMessage.JsonOutput +Recommended.JsonInput.OneofZeroMessage.ProtobufOutput +Required.JsonInput.BytesFieldInvalidBase64Characters +Required.JsonInput.DoubleFieldTooSmall +Required.JsonInput.EnumFieldUnknownValue.Validator +Required.JsonInput.FloatFieldTooLarge +Required.JsonInput.FloatFieldTooSmall +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool +Required.JsonInput.TimestampJsonInputLowercaseT diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index 84d9fccd..d77e2afb 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -7,65 +7,34 @@ # TODO(haberman): insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? -DurationProtoInputTooLarge.JsonOutput -DurationProtoInputTooSmall.JsonOutput -FieldMaskNumbersDontRoundTrip.JsonOutput -FieldMaskPathsDontRoundTrip.JsonOutput -FieldMaskTooManyUnderscore.JsonOutput -JsonInput.AnyWithFieldMask.ProtobufOutput -JsonInput.BytesFieldInvalidBase64Characters -JsonInput.DoubleFieldInfinityNotQuoted -JsonInput.DoubleFieldNanNotQuoted -JsonInput.DoubleFieldNegativeInfinityNotQuoted -JsonInput.DoubleFieldTooSmall -JsonInput.DurationJsonInputTooLarge -JsonInput.DurationJsonInputTooSmall -JsonInput.DurationMissingS -JsonInput.EnumFieldNumericValueNonZero.JsonOutput -JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput -JsonInput.EnumFieldNumericValueZero.JsonOutput -JsonInput.EnumFieldNumericValueZero.ProtobufOutput -JsonInput.EnumFieldUnknownValue.Validator -JsonInput.FieldMask.ProtobufOutput -JsonInput.FieldMaskInvalidCharacter -JsonInput.FloatFieldInfinityNotQuoted -JsonInput.FloatFieldNanNotQuoted -JsonInput.FloatFieldNegativeInfinityNotQuoted -JsonInput.FloatFieldTooLarge -JsonInput.FloatFieldTooSmall -JsonInput.Int32FieldExponentialFormat.JsonOutput -JsonInput.Int32FieldExponentialFormat.ProtobufOutput -JsonInput.Int32FieldFloatTrailingZero.JsonOutput -JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput -JsonInput.Int32FieldMaxFloatValue.JsonOutput -JsonInput.Int32FieldMaxFloatValue.ProtobufOutput -JsonInput.Int32FieldMinFloatValue.JsonOutput -JsonInput.Int32FieldMinFloatValue.ProtobufOutput -JsonInput.OneofZeroMessage.JsonOutput -JsonInput.OneofZeroMessage.ProtobufOutput -JsonInput.OriginalProtoFieldName.JsonOutput -JsonInput.OriginalProtoFieldName.ProtobufOutput -JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool -JsonInput.TimestampJsonInputLowercaseT -JsonInput.Uint32FieldMaxFloatValue.JsonOutput -JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput -JsonInput.ValueAcceptNull.JsonOutput -JsonInput.ValueAcceptNull.ProtobufOutput -ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE -ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE -ProtobufInput.PrematureEofInPackedField.BOOL -ProtobufInput.PrematureEofInPackedField.DOUBLE -ProtobufInput.PrematureEofInPackedField.ENUM -ProtobufInput.PrematureEofInPackedField.FIXED32 -ProtobufInput.PrematureEofInPackedField.FIXED64 -ProtobufInput.PrematureEofInPackedField.FLOAT -ProtobufInput.PrematureEofInPackedField.INT32 -ProtobufInput.PrematureEofInPackedField.INT64 -ProtobufInput.PrematureEofInPackedField.SFIXED32 -ProtobufInput.PrematureEofInPackedField.SFIXED64 -ProtobufInput.PrematureEofInPackedField.SINT32 -ProtobufInput.PrematureEofInPackedField.SINT64 -ProtobufInput.PrematureEofInPackedField.UINT32 -ProtobufInput.PrematureEofInPackedField.UINT64 -TimestampProtoInputTooLarge.JsonOutput -TimestampProtoInputTooSmall.JsonOutput +Recommended.JsonInput.DoubleFieldInfinityNotQuoted +Recommended.JsonInput.DoubleFieldNanNotQuoted +Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted +Recommended.JsonInput.FloatFieldInfinityNotQuoted +Recommended.JsonInput.FloatFieldNanNotQuoted +Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted +Recommended.JsonInput.OneofZeroMessage.JsonOutput +Recommended.JsonInput.OneofZeroMessage.ProtobufOutput +Required.JsonInput.BytesFieldInvalidBase64Characters +Required.JsonInput.DoubleFieldTooSmall +Required.JsonInput.EnumFieldUnknownValue.Validator +Required.JsonInput.FloatFieldTooLarge +Required.JsonInput.FloatFieldTooSmall +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool +Required.JsonInput.TimestampJsonInputLowercaseT +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInPackedField.BOOL +Required.ProtobufInput.PrematureEofInPackedField.DOUBLE +Required.ProtobufInput.PrematureEofInPackedField.ENUM +Required.ProtobufInput.PrematureEofInPackedField.FIXED32 +Required.ProtobufInput.PrematureEofInPackedField.FIXED64 +Required.ProtobufInput.PrematureEofInPackedField.FLOAT +Required.ProtobufInput.PrematureEofInPackedField.INT32 +Required.ProtobufInput.PrematureEofInPackedField.INT64 +Required.ProtobufInput.PrematureEofInPackedField.SFIXED32 +Required.ProtobufInput.PrematureEofInPackedField.SFIXED64 +Required.ProtobufInput.PrematureEofInPackedField.SINT32 +Required.ProtobufInput.PrematureEofInPackedField.SINT64 +Required.ProtobufInput.PrematureEofInPackedField.UINT32 +Required.ProtobufInput.PrematureEofInPackedField.UINT64 -- cgit v1.2.3