diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 598ef732..d46fa877 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -272,11 +272,16 @@ void ConformanceTestSuite::RunValidInputTest( TestAllTypes test_message; switch (response.result_case()) { + case ConformanceResponse::RESULT_NOT_SET: + ReportFailure(test_name, request, response, + "Response didn't have any field in the Response."); + return; + case ConformanceResponse::kParseError: case ConformanceResponse::kRuntimeError: case ConformanceResponse::kSerializeError: ReportFailure(test_name, request, response, - "Failed to parse JSON input or produce JSON output."); + "Failed to parse input or produce output."); return; case ConformanceResponse::kSkipped: @@ -400,6 +405,17 @@ void ConformanceTestSuite::RunValidJsonTestWithProtobufInput( equivalent_text_format, conformance::JSON); } +void ConformanceTestSuite::RunValidProtobufTest( + const string& test_name, const TestAllTypes& input, + const string& equivalent_text_format) { + RunValidInputTest("ProtobufInput." + test_name + ".ProtobufOutput", + input.SerializeAsString(), conformance::PROTOBUF, + equivalent_text_format, conformance::PROTOBUF); + RunValidInputTest("ProtobufInput." + test_name + ".JsonOutput", + input.SerializeAsString(), conformance::PROTOBUF, + equivalent_text_format, conformance::JSON); +} + // According to proto3 JSON specification, JSON serializers follow more strict // rules than parsers (e.g., a serializer must serialize int32 values as JSON // numbers while the parser is allowed to accept them as JSON strings). This @@ -1225,6 +1241,34 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, ExpectParseFailureForJson( "OneofFieldDuplicate", R"({"oneofUint32": 1, "oneofString": "test"})"); + // Ensure zero values for oneof make it out/backs. + { + TestAllTypes message; + message.set_oneof_uint32(0); + RunValidProtobufTest( + "OneofZeroUint32", message, "oneof_uint32: 0"); + message.mutable_oneof_nested_message()->set_a(0); + RunValidProtobufTest( + "OneofZeroMessage", message, "oneof_nested_message: {}"); + message.set_oneof_string(""); + RunValidProtobufTest( + "OneofZeroString", message, "oneof_string: \"\""); + message.set_oneof_bytes(""); + RunValidProtobufTest( + "OneofZeroBytes", message, "oneof_bytes: \"\""); + } + RunValidJsonTest( + "OneofZeroUint32", + R"({"oneofUint32": 0})", "oneof_uint32: 0"); + RunValidJsonTest( + "OneofZeroMessage", + R"({"oneofNestedMessage": {}})", "oneof_nested_message: {}"); + RunValidJsonTest( + "OneofZeroString", + R"({"oneofString": ""})", "oneof_string: \"\""); + RunValidJsonTest( + "OneofZeroBytes", + R"({"oneofBytes": ""})", "oneof_bytes: \"\""); // Repeated fields. RunValidJsonTest( diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index c9c5213c..56689318 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -133,6 +133,9 @@ class ConformanceTestSuite { void RunValidJsonTestWithProtobufInput(const string& test_name, const conformance::TestAllTypes& input, const string& equivalent_text_format); + void RunValidProtobufTest(const string& test_name, + const conformance::TestAllTypes& input, + const string& equivalent_text_format); typedef std::function Validator; void RunValidJsonTestWithValidator(const string& test_name, diff --git a/conformance/failure_list_objc.txt b/conformance/failure_list_objc.txt index 5dac3501..ec7898cd 100644 --- a/conformance/failure_list_objc.txt +++ b/conformance/failure_list_objc.txt @@ -1,4 +1,6 @@ -# No tests currently failing. +ProtobufInput.OneofZeroBytes.ProtobufOutput +ProtobufInput.OneofZeroString.ProtobufOutput +ProtobufInput.OneofZeroUint32.ProtobufOutput # # json input or output tests are skipped (in conformance_objc.m) as mobile # platforms don't support json wire format to avoid code bloat. diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index 550a043f..3918703a 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -35,6 +35,8 @@ 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 diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index 1eb916ab..69746d9f 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -44,6 +44,8 @@ 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 diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt index 7c12da06..526c2e75 100644 --- a/conformance/failure_list_ruby.txt +++ b/conformance/failure_list_ruby.txt @@ -103,6 +103,8 @@ JsonInput.MessageMapField.JsonOutput JsonInput.MessageMapField.ProtobufOutput JsonInput.MessageRepeatedField.JsonOutput JsonInput.MessageRepeatedField.ProtobufOutput +JsonInput.OneofZeroUint32.JsonOutput +JsonInput.OneofZeroUint32.ProtobufOutput JsonInput.OptionalBoolWrapper.JsonOutput JsonInput.OptionalBoolWrapper.ProtobufOutput JsonInput.OptionalBytesWrapper.JsonOutput