瀏覽代碼

Add binary conformance test for message type. (#6435)

* Add binary conformance test for message type.

* Add test case for merge repeated scalar message field

* Add failed tests to failure list

* Add failed test to php's failure list

* Remove successful tests from php c's failure list
Paul Yang 6 年之前
父節點
當前提交
2849a79990

+ 60 - 10
conformance/binary_json_conformance_suite.cc

@@ -149,10 +149,6 @@ string tag(uint32_t fieldnum, char wire_type) {
   return varint((fieldnum << 3) | wire_type);
 }
 
-string submsg(uint32_t fn, const string& buf) {
-  return cat( tag(fn, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(buf) );
-}
-
 #define UNKNOWN_FIELD 666
 
 const FieldDescriptor* GetFieldForType(FieldDescriptor::Type type,
@@ -594,17 +590,24 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
     const FieldDescriptor* field = GetFieldForType(type, false, is_proto3);
     const FieldDescriptor* rep_field = GetFieldForType(type, true, is_proto3);
 
-    RunValidProtobufTest("ValidDataScalar" + type_name, REQUIRED,
-                         cat(tag(field->number(), wire_type), values[0].first),
-                         field->name() + ": " + values[0].second, is_proto3);
+    for (size_t i = 0; i < values.size(); i++) {
+      RunValidProtobufTest(StrCat("ValidDataScalar", type_name, "[", i, "]"),
+                           REQUIRED,
+                           cat(tag(field->number(), wire_type), values[0].first),
+                           field->name() + ": " + values[0].second, is_proto3);
+    }
 
     string proto;
     string text = field->name() + ": " + values.back().second;
     for (size_t i = 0; i < values.size(); i++) {
       proto += cat(tag(field->number(), wire_type), values[i].first);
     }
-    RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED,
-                         proto, text, is_proto3);
+    // For scalar message fields, repeated values are merged, which is tested
+    // separately.
+    if (type != FieldDescriptor::TYPE_MESSAGE) {
+      RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED,
+                           proto, text, is_proto3);
+    }
 
     proto.clear();
     text.clear();
@@ -618,6 +621,48 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
   }
 }
 
+void BinaryAndJsonConformanceSuite::TestValidDataForRepeatedScalarMessage() {
+  std::vector<std::string> values = {
+      delim(cat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+                delim(cat(
+                    tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1234),
+                    tag(2, WireFormatLite::WIRETYPE_VARINT), varint(1234),
+                    tag(31, WireFormatLite::WIRETYPE_VARINT), varint(1234)
+                )))),
+      delim(cat(tag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+                delim(cat(
+                    tag(1, WireFormatLite::WIRETYPE_VARINT), varint(4321),
+                    tag(3, WireFormatLite::WIRETYPE_VARINT), varint(4321),
+                    tag(31, WireFormatLite::WIRETYPE_VARINT), varint(4321)
+                )))),
+  };
+
+  const std::string expected =
+      R"({
+        corecursive: {
+          optional_int32: 4321,
+          optional_int64: 1234,
+          optional_uint32: 4321,
+          repeated_int32: [1234, 4321],
+        }
+      })";
+
+  for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) {
+    string proto;
+    const FieldDescriptor* field =
+        GetFieldForType(FieldDescriptor::TYPE_MESSAGE, false, is_proto3);
+    for (size_t i = 0; i < values.size(); i++) {
+      proto +=
+          cat(tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+              values[i]);
+    }
+
+    RunValidProtobufTest(
+        "RepeatedScalarMessageMerge", REQUIRED, proto,
+        field->name() + ": " + expected, is_proto3);
+  }
+}
+
 // TODO: proto2?
 void BinaryAndJsonConformanceSuite::TestIllegalTags() {
   // field num 0 is illegal
@@ -810,10 +855,15 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
     {varint(2), "BAZ"},
     {varint(-1), "NEG"},
   });
+  TestValidDataForRepeatedScalarMessage();
+  TestValidDataForType(FieldDescriptor::TYPE_MESSAGE, {
+    {delim(cat(tag(1, WireFormatLite::WIRETYPE_VARINT), varint(1234))),
+     "{a: 1234}"},
+    {delim(""), "{}"},
+  });
 
   // TODO(haberman):
   // TestValidDataForType(FieldDescriptor::TYPE_GROUP
-  // TestValidDataForType(FieldDescriptor::TYPE_MESSAGE
 
   RunValidJsonTest("HelloWorld", REQUIRED,
                    "{\"optionalString\":\"Hello, World!\"}",

+ 1 - 0
conformance/binary_json_conformance_suite.h

@@ -109,6 +109,7 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
   void TestValidDataForType(
       google::protobuf::FieldDescriptor::Type,
       std::vector<std::pair<std::string, std::string>> values);
+  void TestValidDataForRepeatedScalarMessage();
 
   std::unique_ptr<google::protobuf::util::TypeResolver>
       type_resolver_;

+ 1 - 0
conformance/failure_list_js.txt

@@ -12,3 +12,4 @@ Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput
 Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput
 Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput
 Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.ProtobufOutput
+Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput

+ 2 - 0
conformance/failure_list_php.txt

@@ -18,3 +18,5 @@ Required.Proto3.JsonInput.Uint64FieldNotInteger
 Required.Proto3.JsonInput.Int32FieldLeadingSpace
 Required.Proto3.JsonInput.OneofFieldDuplicate
 Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
+Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.JsonOutput
+Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput