Beispiel #1
0
 def test_service_change(self):
     input_message = make_message(name="request",
                                  full_name=".example.v1.request")
     output_message = make_message(name="response",
                                   full_name=".example.v1.response")
     service_original = make_service(methods=[
         make_method(
             name="DoThing",
             input_message=input_message,
             output_message=output_message,
         )
     ])
     service_update = make_service()
     FileSetComparator(
         make_file_set(files=[
             make_file_pb2(
                 services=[service_original],
                 messages=[input_message, output_message],
             )
         ]),
         make_file_set(files=[make_file_pb2(services=[service_update])]),
         self.finding_container,
     ).compare()
     finding = self.finding_container.getAllFindings()[0]
     self.assertEqual(finding.message,
                      "An existing rpc method `DoThing` is removed.")
     self.assertEqual(finding.category.name, "METHOD_REMOVAL")
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.location.proto_file_name, "my_proto.proto")
 def test_nested_enum_change(self):
     nested_enum1 = make_enum(
         name="Foo",
         values=(
             ("RED", 1),
             ("GREEN", 2),
         ),
     )
     nested_enum2 = make_enum(
         name="Foo",
         values=(
             ("RED", 1),
             ("GREEN", 2),
             ("BLUE", 3),
         ),
     )
     message1 = make_message(nested_enums=[nested_enum1])
     message2 = make_message(nested_enums=[nested_enum2])
     DescriptorComparator(message1, message2,
                          self.finding_container).compare()
     findings_map = {
         f.message: f
         for f in self.finding_container.getAllFindings()
     }
     finding = findings_map["A new EnumValue `BLUE` is added."]
     self.assertEqual(finding.category.name, "ENUM_VALUE_ADDITION")
     self.assertEqual(finding.change_type.name, "MINOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
 def test_nested_enum_change(self):
     nested_enum1 = make_enum(
         name="Foo",
         values=(
             ("RED", 1),
             ("GREEN", 2),
         ),
     )
     nested_enum2 = make_enum(
         name="Foo",
         values=(
             ("RED", 1),
             ("GREEN", 2),
             ("BLUE", 3),
         ),
     )
     message1 = make_message(nested_enums=[nested_enum1])
     message2 = make_message(nested_enums=[nested_enum2])
     DescriptorComparator(message1,
                          message2,
                          self.finding_container,
                          context="ctx").compare()
     finding = next(f for f in self.finding_container.get_all_findings()
                    if f.category.name == "ENUM_VALUE_ADDITION")
     self.assertEqual(finding.change_type.name, "MINOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
Beispiel #4
0
 def test_method_types(self):
     input_msg = make_message(name="Input", full_name=".example.v1.input")
     output_msg = make_message(name="Output", full_name=".example.v1.output")
     method = make_method("DoSomething", input_msg, output_msg)
     self.assertEqual(method.name, "DoSomething")
     self.assertEqual(method.input.value, ".example.v1.input")
     self.assertEqual(method.output.value, ".example.v1.output")
Beispiel #5
0
 def test_nested_map_entries(self):
     # Create the inner message.
     inner_msg = [
         make_message(
             "FieldEntry",
             fields=(
                 make_field(
                     name="key",
                     number=1,
                 ),
                 make_field(
                     name="value",
                     number=2,
                 ),
             ),
             map_entry=True,
         ),
     ]
     field = make_field("field",
                        type_name="FieldEntry",
                        repeated=True,
                        number=1)
     outer_msg = make_message(fields=[field], nested_messages=inner_msg)
     self.assertEqual(list(outer_msg.map_entries.keys()), ["FieldEntry"])
     self.assertTrue(outer_msg.map_entries["FieldEntry"]["key"])
     self.assertTrue(outer_msg.map_entries["FieldEntry"]["value"])
     self.assertFalse(outer_msg.nested_messages)
     self.assertTrue(outer_msg.fields[1].map_entry)
Beispiel #6
0
    def test_nested_types(self):
        # Create the inner message.
        inner_msg = [
            make_message(
                "InnerMessage",
                fields=(make_field(
                    name="hidden_message",
                    number=1,
                ), ),
            )
        ]
        inner_enums = [make_enum(name="InnerEnum")]
        inner_fields = [make_field("not_interesting")]

        # Create the outer message, which contains inner fields, enums, messages.
        outer_msg = make_message(
            "Outer",
            fields=inner_fields,
            nested_enums=inner_enums,
            nested_messages=inner_msg,
        )

        self.assertEqual(len(outer_msg.fields.keys()), 1)
        self.assertEqual(outer_msg.fields[1].name, "not_interesting")
        self.assertEqual(len(outer_msg.nested_enums.keys()), 1)
        self.assertEqual(
            outer_msg.nested_messages["InnerMessage"].fields[1].name,
            "hidden_message")
 def test_service_methods(self):
     input_message = make_message("InputRequest")
     output_message = make_message("OutputResponse")
     service = make_service(
         name="ThingDoer",
         methods=(
             make_method(
                 name="DoThing",
                 input_message=input_message,
                 output_message=output_message,
             ),
             make_method(
                 name="Jump",
                 input_message=input_message,
                 output_message=output_message,
             ),
             make_method(
                 name="Yawn",
                 input_message=input_message,
                 output_message=output_message,
             ),
         ),
     )
     expected_names = ["DoThing", "Jump", "Yawn"]
     self.assertEqual(list(service.methods.keys()), expected_names)
Beispiel #8
0
 def test_method_no_page_field(self):
     # No repeated field in the response message.
     field_next_page_token = make_field(
         name="next_page_token",
         proto_type="TYPE_STRING",
         number=2,
     )
     response_message = make_message(
         name="ResponseMessage",
         fields=[field_next_page_token],
     )
     field_page_size = make_field(
         name="page_size",
         proto_type="TYPE_INT32",
         number=1,
     )
     field_page_token = make_field(
         name="page_token",
         proto_type="TYPE_STRING",
         number=2,
     )
     request_message = make_message(
         name="RequestMessage",
         fields=[field_page_size, field_page_token],
     )
     messages_map = {
         "ResponseMessage": response_message,
         "RequestMessage": request_message,
     }
     method = make_method(
         name="PagedMethod",
         input_message=request_message,
         output_message=response_message,
         messages_map=messages_map,
     )
     self.assertEqual(method.paged_result_field, None)
     # Missing `page_size` in request message.
     request_message_without_page_size = make_message(
         name="RequestMessage",
         fields=[field_page_size],
     )
     method = make_method(
         name="NoPagedMethod",
         input_message=request_message_without_page_size,
         output_message=response_message,
         messages_map=messages_map,
     )
     self.assertEqual(method.paged_result_field, None)
     # Missing `next_page_token` in response message.
     response_message_without_next_page_token = make_message(
         name="ResponseMessage",
     )
     method = make_method(
         name="NoPagedMethod",
         input_message=request_message,
         output_message=response_message_without_next_page_token,
         messages_map=messages_map,
     )
     self.assertEqual(method.paged_result_field, None)
Beispiel #9
0
 def test_detector_basic(self):
     # Mock original and updated FileDescriptorSet.
     L = desc.SourceCodeInfo.Location
     # fmt: off
     locations = [
         L(path=(6, 0, 2, 0), span=(1, 2, 3, 4)),
         L(
             path=(
                 4,
                 0,
             ),
             span=(5, 6, 7, 8),
         ),
         L(path=(4, 1), span=(11, 12, 13, 14)),
     ]
     # fmt: on
     input_msg = make_message(name="input", full_name=".example.v1.input")
     output_msg = make_message(name="output",
                               full_name=".example.v1.output")
     service_original = make_service(methods=(make_method(
         name="DoThing", input_message=input_msg,
         output_message=output_msg), ))
     service_update = make_service()
     file_set_original = desc.FileDescriptorSet(file=[
         make_file_pb2(
             services=[service_original],
             locations=locations,
             messages=[input_msg, output_msg],
         )
     ])
     file_set_update = desc.FileDescriptorSet(
         file=[make_file_pb2(services=[service_update])])
     with mock.patch("os.path.isdir") as mocked_isdir:
         with mock.patch("os.path.isfile") as mocked_isfile:
             mocked_isdir.return_value = True
             mocked_isfile.return_value = True
             opts = Options(
                 original_api_definition_dirs="c,d",
                 update_api_definition_dirs="a,b",
                 original_proto_files="pf1, pf2",
                 update_proto_files="pf3, pf4",
                 original_descriptor_set_file_path=None,
                 update_descriptor_set_file_path=None,
                 human_readable_message=True,
             )
     with mock.patch("sys.stdout", new=StringIO()) as fake_output:
         result = Detector(file_set_original, file_set_update,
                           opts).detect_breaking_changes()
         self.assertEqual(
             fake_output.getvalue(),
             "my_proto.proto L2: An existing method `DoThing` is removed from service `Placeholder`.\n"
             +
             "my_proto.proto L6: An existing message `input` is removed.\n"
             +
             "my_proto.proto L12: An existing message `output` is removed.\n",
         )
         self.assertEqual(len(result), 3)
 def test_nested_field_addition(self):
     field_int = make_field(proto_type="TYPE_INT32")
     message_update = make_message(fields=[field_int])
     DescriptorComparator(make_message(), message_update,
                          self.finding_container).compare()
     finding = self.finding_container.getAllFindings()[0]
     self.assertEqual(finding.category.name, "FIELD_ADDITION")
     self.assertEqual(finding.change_type.name, "MINOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
 def test_nested_enum_addition(self):
     DescriptorComparator(
         make_message(),
         make_message(nested_enums=[make_enum(name="nested_message")]),
         self.finding_container,
     ).compare()
     finding = self.finding_container.getAllFindings()[0]
     self.assertEqual(finding.category.name, "ENUM_ADDITION")
     self.assertEqual(finding.change_type.name, "MINOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
    def test_file_set_resources(self):
        options = descriptor_pb2.FileOptions()
        options.Extensions[resource_pb2.resource_definition].append(
            resource_pb2.ResourceDescriptor(
                type="example.v1/Foo",
                pattern=["foo/{foo}"],
            ))
        # File1 with file-level resource definition `example.v1/Foo`.
        file1 = make_file_pb2(
            name="foo.proto",
            package=".example.v1",
            dependency=["bar.proto"],
            options=options,
        )
        # File2 with resource definition in message and nested message.
        message_options = descriptor_pb2.MessageOptions()
        resource = message_options.Extensions[resource_pb2.resource]
        resource.pattern.append("user/{user}")
        resource.pattern.append("user/{user}/bar/")
        resource.type = "example.v1/Bar"

        nested_message_options = descriptor_pb2.MessageOptions()
        resource = nested_message_options.Extensions[resource_pb2.resource]
        resource.pattern.append("tests/{test}/")
        resource.type = "example.v1/Test"
        nesed_message = make_message("nested_message",
                                     options=nested_message_options)
        message = make_message(
            name="outer_message",
            nested_messages=[nesed_message],
            options=message_options,
        )
        file2 = make_file_pb2(name="bar.proto",
                              package=".example.bar",
                              messages=[message])
        file_set = make_file_set(files=[file1, file2])
        # All resources should be registered in the database.
        resource_types = file_set.resources_database.types
        resource_patterns = file_set.resources_database.patterns
        self.assertEqual(
            list(resource_types.keys()),
            ["example.v1/Foo", "example.v1/Bar", "example.v1/Test"],
        )
        self.assertEqual(
            list(resource_patterns.keys()),
            ["foo/{foo}", "user/{user}", "user/{user}/bar/", "tests/{test}/"],
        )
        # Check used resources database.
        # File1 depends on file2, but they are not in the same package, only file1
        # is API definition file. So only resources in file1 are in used_resource_database.
        self.assertEqual(list(file_set.used_resources_database.types.keys()),
                         ["example.v1/Foo"])
        self.assertEqual(
            list(file_set.used_resources_database.patterns.keys()),
            ["foo/{foo}"])
 def test_nested_message_removal(self):
     DescriptorComparator(
         make_message(nested_messages=[make_message(
             name="nested_message")]),
         make_message(),
         self.finding_container,
     ).compare()
     finding = self.finding_container.getAllFindings()[0]
     self.assertEqual(finding.category.name, "MESSAGE_REMOVAL")
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
Beispiel #14
0
 def test_method_longrunning(self):
     input_msg = make_message(name="Input", full_name=".example.v1.input")
     output_msg = make_message(
         name=".google.longrunning.Operation",
         full_name=".google.longrunning.Operation",
     )
     method = make_method("DoSomething", input_msg, output_msg)
     self.assertEqual(method.name, "DoSomething")
     self.assertEqual(method.input.value, ".example.v1.input")
     self.assertEqual(method.output.value, ".google.longrunning.Operation")
     self.assertEqual(method.longrunning, True)
 def test_nested_enum_removal(self):
     DescriptorComparator(
         make_message(nested_enums=[make_enum(name="nested_message")]),
         make_message(),
         self.finding_container,
         context="ctx",
     ).compare()
     finding = self.finding_container.get_all_findings()[0]
     self.assertEqual(finding.category.name, "ENUM_REMOVAL")
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
 def test_nested_message_addition(self):
     DescriptorComparator(
         make_message(),
         make_message(nested_messages=[make_message(
             name="nested_message")]),
         self.finding_container,
         context="ctx",
     ).compare()
     finding = self.finding_container.get_all_findings()[0]
     self.assertEqual(finding.category.name, "MESSAGE_ADDITION")
     self.assertEqual(finding.change_type.name, "MINOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
Beispiel #17
0
 def test_resource_annotation(self):
     options = descriptor_pb2.MessageOptions()
     resource = options.Extensions[resource_pb2.resource]
     resource.pattern.append("foo/{foo}/bar")
     resource.pattern.append("foo/{foo}/bar/{bar}")
     resource.type = "example/Bar"
     message = make_message("Message", options=options)
     message_without_resource = make_message("Message")
     self.assertEqual(message_without_resource.resource, None)
     self.assertEqual(message.resource.value.type, "example/Bar")
     self.assertEqual(message.resource.value.pattern,
                      ["foo/{foo}/bar", "foo/{foo}/bar/{bar}"])
 def test_nested_field_type_change(self):
     field_int = make_field(proto_type="TYPE_INT32")
     field_string = make_field(proto_type="TYPE_STRING")
     message1 = make_message(fields=[field_int])
     message2 = make_message(fields=[field_string])
     DescriptorComparator(message1,
                          message2,
                          self.finding_container,
                          context="ctx").compare()
     finding = next(f for f in self.finding_container.get_all_findings()
                    if f.category.name == "FIELD_TYPE_CHANGE")
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
Beispiel #19
0
 def test_message_change_breaking(self):
     message_original = make_message(
         fields=(make_field(name="field_one", number=1), ))
     message_update = make_message(
         fields=(make_field(name="field_two", number=1), ))
     FileSetComparator(
         make_file_set(files=[make_file_pb2(messages=[message_original])]),
         make_file_set(files=[make_file_pb2(messages=[message_update])]),
         self.finding_container,
     ).compare()
     finding = self.finding_container.get_all_findings()[0]
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.category.name, "FIELD_NAME_CHANGE")
     self.assertEqual(finding.location.proto_file_name, "my_proto.proto")
    def test_file_set_source_code_location(self):
        L = descriptor_pb2.SourceCodeInfo.Location
        locations = [
            L(path=(4, 0, 2, 0, 5), span=(5, 2, 3, 4)),
            L(path=(4, 0, 3, 0), span=(6, 1, 2, 4)),
            L(path=(4, 0, 4, 0), span=(7, 1, 2, 4)),
            L(path=(4, 0, 4, 0, 2, 1), span=(9, 1, 2, 4)),
        ]
        messages = [
            make_message(
                "OuterMessage",
                fields=(make_field(
                    name="hidden_message",
                    number=1,
                ), ),
                nested_messages=(make_message(name="InterMessage"), ),
                nested_enums=(make_enum(
                    name="InterEnum",
                    values=(
                        ("RED", 1),
                        ("GREEN", 2),
                        ("BLUE", 3),
                    ),
                ), ),
            )
        ]

        file_pb2 = make_file_pb2(messages=messages, locations=locations)
        file_set = make_file_set(files=[file_pb2])
        self.assertEqual(
            file_set.messages_map[".example.v1.OuterMessage"].fields[1].
            proto_type.source_code_line,
            6,
        )
        self.assertEqual(
            file_set.messages_map[".example.v1.OuterMessage"].
            nested_messages["InterMessage"].source_code_line,
            7,
        )
        self.assertEqual(
            file_set.messages_map[".example.v1.OuterMessage"].
            nested_enums["InterEnum"].source_code_line,
            8,
        )
        self.assertEqual(
            file_set.messages_map[".example.v1.OuterMessage"].
            nested_enums["InterEnum"].values[2].source_code_line,
            10,
        )
 def test_nested_field_type_change(self):
     field_int = make_field(proto_type="TYPE_INT32")
     field_string = make_field(proto_type="TYPE_STRING")
     message1 = make_message(fields=[field_int])
     message2 = make_message(fields=[field_string])
     DescriptorComparator(message1, message2,
                          self.finding_container).compare()
     findings_map = {
         f.message: f
         for f in self.finding_container.getAllFindings()
     }
     finding = findings_map[
         "Type of an existing field `my_field` is changed from `int32` to `string`."]
     self.assertEqual(finding.category.name, "FIELD_TYPE_CHANGE")
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
 def test_nested_message_change(self):
     nested_field = make_field(name="nested_field")
     nested_message_with_fields = make_message(name="nested_message",
                                               fields=[nested_field])
     nested_message_without_fields = make_message(name="nested_message")
     message1 = make_message(nested_messages=[nested_message_with_fields])
     message2 = make_message(
         nested_messages=[nested_message_without_fields])
     DescriptorComparator(message1,
                          message2,
                          self.finding_container,
                          context="ctx").compare()
     finding = next(f for f in self.finding_container.get_all_findings()
                    if f.category.name == "FIELD_REMOVAL")
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
Beispiel #23
0
 def test_method_lro_annotationn(self):
     input_msg = make_message(name="Input", full_name=".example.v1.input")
     output_msg = make_message(
         name=".google.longrunning.Operation",
         full_name=".google.longrunning.Operation",
     )
     method = make_method(
         name="Method",
         input_message=input_msg,
         output_message=output_msg,
         lro_response_type="response_type",
         lro_metadata_type="metadata_type",
     )
     lro_annotation = method.lro_annotation.value
     self.assertEqual(lro_annotation["response_type"], "response_type")
     self.assertEqual(lro_annotation["metadata_type"], "metadata_type")
Beispiel #24
0
 def test_lro_annotation_invalid(self):
     lro_output_msg = make_message(
         name=".google.longrunning.Operation",
         full_name=".google.longrunning.Operation",
     )
     method_lro = make_method(
         name="Method",
         output_message=lro_output_msg,
         lro_response_type="response_type",
         lro_metadata_type="FooMetadata",
     )
     method_not_lro = make_method(
         name="Method",
         output_message=lro_output_msg,
     )
     # `method_not_lro` returns `google.longrunning.Operation`
     # but is missing a response type or metadata type, the definition
     # is invalid. We still compare the two methods and take it as
     # lro annotation removal.
     ServiceComparator(
         make_service(methods=(method_lro, )),
         make_service(methods=(method_not_lro, )),
         self.finding_container,
         context="ctx",
     ).compare()
     finding = next(f for f in self.finding_container.get_all_findings()
                    if f.category.name == "LRO_ANNOTATION_REMOVAL")
     self.assertTrue(finding)
Beispiel #25
0
 def test_resources_removal(self):
     # Create message with resource options.
     message_options = make_message_options_resource_definition(
         resource_type="example.v1/Bar",
         resource_patterns=["user/{user}", "user/{user}/bar/"],
     )
     message = make_message("Test", options=message_options)
     # Original file set with one resource defined at message level.
     file_set_original = make_file_set(files=[
         make_file_pb2(
             name="bar.proto", package=".example.v1", messages=[message])
     ])
     # Update file set without any resources.
     file_set_update = make_file_set(
         files=[make_file_pb2(name="foo.proto", package=".example.v1")])
     FileSetComparator(file_set_original, file_set_update,
                       self.finding_container).compare()
     findings_map = {
         f.message: f
         for f in self.finding_container.getAllFindings()
     }
     file_resource_removal = findings_map[
         "An existing resource definition `example.v1/Bar` has been removed."]
     self.assertEqual(
         file_resource_removal.category.name,
         "RESOURCE_DEFINITION_REMOVAL",
     )
     self.assertEqual(
         file_resource_removal.location.proto_file_name,
         "bar.proto",
     )
Beispiel #26
0
 def test_lro_annotation_metadata_change(self):
     lro_output_msg = make_message(
         name=".google.longrunning.Operation",
         full_name=".google.longrunning.Operation",
     )
     method_original = make_method(
         name="Method",
         output_message=lro_output_msg,
         lro_response_type="response_type",
         lro_metadata_type="FooMetadata",
     )
     method_update = make_method(
         name="Method",
         output_message=lro_output_msg,
         lro_response_type="response_type",
         lro_metadata_type="FooMetadataUpdate",
     )
     ServiceComparator(
         make_service(methods=(method_original, )),
         make_service(methods=(method_update, )),
         self.finding_container,
         context="ctx",
     ).compare()
     finding = next(f for f in self.finding_container.get_all_findings()
                    if f.category.name == "LRO_METADATA_CHANGE")
     self.assertEqual(finding.location.proto_file_name, "foo")
Beispiel #27
0
 def test_method_input_type_change(self):
     message_foo_request = make_message(name="FooRequest",
                                        full_name="FooRequest")
     message_bar_request = make_message(name="BarRequest",
                                        full_name="BarRequest")
     service_original = make_service(methods=(
         make_method(name="Foo", input_message=message_foo_request), ))
     service_update = make_service(methods=(
         make_method(name="Foo", input_message=message_bar_request), ))
     ServiceComparator(service_original,
                       service_update,
                       self.finding_container,
                       context="ctx").compare()
     finding = next(f for f in self.finding_container.get_all_findings()
                    if f.category.name == "METHOD_INPUT_TYPE_CHANGE")
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
Beispiel #28
0
 def test_enum_in_dependency_change_breaking(self):
     # Enum "dep_message" is imported from dep.proto and referenced as a field type.
     field_type_original = make_enum(
         name="dep_enum",
         proto_file_name="dep.proto",
     )
     message_original = make_message(
         fields=[make_field(type_name=".test.import.dep_enum")], )
     # Message "test_enum" is defined in update.proto referenced as a field type.
     field_type_update = make_enum(name="test_enum", )
     message_update = make_message(
         fields=[make_field(type_name="test_enum")])
     FileSetComparator(
         make_file_set(files=[
             make_file_pb2(
                 name="orignal.proto",
                 messages=[message_original],
                 dependency="test/import/dep.proto",
                 package="example.v1",
             ),
             make_file_pb2(
                 name="dep.proto",
                 enums=[field_type_original],
                 package="test.import",
             ),
         ]),
         make_file_set(files=[
             make_file_pb2(
                 name="update.proto",
                 messages=[message_update],
                 enums=[field_type_update],
                 package="example.v1beta1",
             )
         ]),
         self.finding_container,
     ).compare()
     # The breaking change should be in field level, instead of message removal,
     # since the message is imported from dependency file.
     finding = self.finding_container.getAllFindings()[0]
     self.assertEqual(
         finding.message,
         "Type of an existing field `my_field` is changed from `.test.import.dep_enum` to `test_enum`.",
     )
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.category.name, "FIELD_TYPE_CHANGE")
     self.assertEqual(finding.location.proto_file_name, "update.proto")
 def test_nested_message_change(self):
     nested_field = make_field(name="nested_field")
     nested_message_with_fields = make_message(name="nested_message",
                                               fields=[nested_field])
     nested_message_without_fields = make_message(name="nested_message")
     message1 = make_message(nested_messages=[nested_message_with_fields])
     message2 = make_message(
         nested_messages=[nested_message_without_fields])
     DescriptorComparator(message1, message2,
                          self.finding_container).compare()
     findings_map = {
         f.message: f
         for f in self.finding_container.getAllFindings()
     }
     finding = findings_map["An existing field `nested_field` is removed."]
     self.assertEqual(finding.category.name, "FIELD_REMOVAL")
     self.assertEqual(finding.change_type.name, "MAJOR")
     self.assertEqual(finding.location.proto_file_name, "foo")
Beispiel #30
0
 def test_get_field(self):
     fields = (
         make_field(name="field_one", number=1),
         make_field(name="field_two", number=2),
     )
     message = make_message("Message", fields=fields)
     field_one = message.fields[1]
     self.assertIsInstance(field_one, wrappers.Field)
     self.assertEqual(field_one.name, "field_one")