| #include "testee.h" | |
| #include <string> | |
| #include <gmock/gmock.h> | |
| #include <gtest/gtest.h> | |
| #include "absl/log/absl_check.h" | |
| #include "absl/strings/string_view.h" | |
| #include "binary_wireformat.h" | |
| #include "test_runner.h" | |
| #include "google/protobuf/test_messages_proto2.pb.h" | |
| #include "google/protobuf/test_messages_proto3.pb.h" | |
| #include "google/protobuf/test_textproto.h" | |
| #include "google/protobuf/text_format.h" | |
| #include "google/protobuf/util/message_differencer.h" | |
| namespace google { | |
| namespace protobuf { | |
| namespace conformance { | |
| namespace internal { | |
| namespace { | |
| using ::protobuf_test_messages::proto2::TestAllTypesProto2; | |
| using ::testing::Return; | |
| MATCHER_P(RequestEquals, expected_textproto, "") { | |
| ::conformance::ConformanceRequest request, expected; | |
| ABSL_CHECK(request.ParseFromString(arg)); | |
| ABSL_CHECK(TextFormat::ParseFromString(expected_textproto, &expected)); | |
| if (!util::MessageDifferencer::Equals(request, expected)) { | |
| std::string request_string; | |
| ABSL_CHECK(TextFormat::PrintToString(request, &request_string)); | |
| *result_listener << "with equivalent text format:\n" << request_string; | |
| return false; | |
| } | |
| return true; | |
| } | |
| auto RespondWith(absl::string_view textproto) { | |
| ::conformance::ConformanceResponse response; | |
| ABSL_CHECK(TextFormat::ParseFromString(textproto, &response)); | |
| return Return(response.SerializeAsString()); | |
| } | |
| class MockTestRunner : public ConformanceTestRunner { | |
| public: | |
| MOCK_METHOD(std::string, RunTest, | |
| (absl::string_view test_name, absl::string_view input), | |
| (override)); | |
| }; | |
| TEST(TesteeTest, BinaryToBinary) { | |
| MockTestRunner mock; | |
| Testee testee(&mock); | |
| EXPECT_CALL( | |
| mock, | |
| RunTest("Required.Proto2.ProtobufInput.foo.ProtobufOutput", | |
| RequestEquals(R"pb( | |
| protobuf_payload: "wire" | |
| requested_output_format: PROTOBUF | |
| message_type: "protobuf_test_messages.proto2.TestAllTypesProto2" | |
| test_category: BINARY_TEST | |
| )pb"))) | |
| .WillOnce(RespondWith(R"pb(runtime_error: "error")pb")); | |
| TestResult result = | |
| testee.CreateTest("foo", TestStrictness::kRequired) | |
| .ParseBinary(TestAllTypesProto2::descriptor(), Wire("wire")) | |
| .SerializeBinary(); | |
| EXPECT_EQ(result.name(), "Required.Proto2.ProtobufInput.foo.ProtobufOutput"); | |
| EXPECT_EQ(result.strictness(), TestStrictness::kRequired); | |
| EXPECT_EQ(result.type(), TestAllTypesProto2::descriptor()); | |
| EXPECT_THAT(result.format(), ::conformance::PROTOBUF); | |
| EXPECT_THAT(result.response(), EqualsProto(R"pb(runtime_error: "error")pb")); | |
| } | |
| TEST(TesteeTest, TextToText) { | |
| MockTestRunner mock; | |
| Testee testee(&mock); | |
| EXPECT_CALL( | |
| mock, | |
| RunTest("Recommended.Proto2.TextFormatInput.foo.TextFormatOutput", | |
| RequestEquals(R"pb( | |
| text_payload: "text" | |
| requested_output_format: TEXT_FORMAT | |
| message_type: "protobuf_test_messages.proto2.TestAllTypesProto2" | |
| test_category: TEXT_FORMAT_TEST | |
| )pb"))) | |
| .WillOnce(RespondWith(R"pb(runtime_error: "error")pb")); | |
| TestResult result = testee.CreateTest("foo", TestStrictness::kRecommended) | |
| .ParseText(TestAllTypesProto2::descriptor(), "text") | |
| .SerializeText(); | |
| EXPECT_EQ(result.name(), | |
| "Recommended.Proto2.TextFormatInput.foo.TextFormatOutput"); | |
| EXPECT_EQ(result.strictness(), TestStrictness::kRecommended); | |
| EXPECT_EQ(result.type(), TestAllTypesProto2::descriptor()); | |
| EXPECT_THAT(result.format(), ::conformance::TEXT_FORMAT); | |
| EXPECT_THAT(result.response(), EqualsProto(R"pb(runtime_error: "error")pb")); | |
| } | |
| TEST(TesteeTest, TextPrintUnknownFields) { | |
| MockTestRunner mock; | |
| Testee testee(&mock); | |
| EXPECT_CALL( | |
| mock, | |
| RunTest("Required.Proto2.ProtobufInput.foo.TextFormatOutput", | |
| RequestEquals(R"pb( | |
| protobuf_payload: "wire" | |
| requested_output_format: TEXT_FORMAT | |
| message_type: "protobuf_test_messages.proto2.TestAllTypesProto2" | |
| test_category: BINARY_TEST | |
| print_unknown_fields: true | |
| )pb"))) | |
| .WillOnce(RespondWith(R"pb(runtime_error: "error")pb")); | |
| TestResult result = | |
| testee.CreateTest("foo", TestStrictness::kRequired) | |
| .ParseBinary(TestAllTypesProto2::descriptor(), Wire("wire")) | |
| .SerializeText({.print_unknown_fields = true}); | |
| EXPECT_EQ(result.name(), | |
| "Required.Proto2.ProtobufInput.foo.TextFormatOutput"); | |
| EXPECT_EQ(result.strictness(), TestStrictness::kRequired); | |
| EXPECT_EQ(result.type(), TestAllTypesProto2::descriptor()); | |
| EXPECT_THAT(result.format(), ::conformance::TEXT_FORMAT); | |
| EXPECT_THAT(result.response(), EqualsProto(R"pb(runtime_error: "error")pb")); | |
| } | |
| TEST(TesteeTest, JsonToJson) { | |
| MockTestRunner mock; | |
| Testee testee(&mock); | |
| EXPECT_CALL( | |
| mock, | |
| RunTest("Required.Proto2.JsonInput.foo.JsonOutput", RequestEquals(R"pb( | |
| json_payload: "json" | |
| requested_output_format: JSON | |
| message_type: "protobuf_test_messages.proto2.TestAllTypesProto2" | |
| test_category: JSON_TEST | |
| )pb"))) | |
| .WillOnce(RespondWith(R"pb(runtime_error: "error")pb")); | |
| TestResult result = testee.CreateTest("foo", TestStrictness::kRequired) | |
| .ParseJson(TestAllTypesProto2::descriptor(), "json") | |
| .SerializeJson(); | |
| EXPECT_EQ(result.name(), "Required.Proto2.JsonInput.foo.JsonOutput"); | |
| EXPECT_EQ(result.strictness(), TestStrictness::kRequired); | |
| EXPECT_EQ(result.type(), TestAllTypesProto2::descriptor()); | |
| EXPECT_THAT(result.format(), ::conformance::JSON); | |
| EXPECT_THAT(result.response(), EqualsProto(R"pb(runtime_error: "error")pb")); | |
| } | |
| TEST(TesteeTest, JsonIgnoreUnknownParsing) { | |
| MockTestRunner mock; | |
| Testee testee(&mock); | |
| EXPECT_CALL( | |
| mock, | |
| RunTest("Required.Proto2.JsonInput.foo.ProtobufOutput", | |
| RequestEquals(R"pb( | |
| json_payload: "json" | |
| requested_output_format: PROTOBUF | |
| message_type: "protobuf_test_messages.proto2.TestAllTypesProto2" | |
| test_category: JSON_IGNORE_UNKNOWN_PARSING_TEST | |
| )pb"))) | |
| .WillOnce(RespondWith(R"pb(runtime_error: "error")pb")); | |
| TestResult result = testee.CreateTest("foo", TestStrictness::kRequired) | |
| .ParseJson(TestAllTypesProto2::descriptor(), "json", | |
| {.ignore_unknown_fields = true}) | |
| .SerializeBinary(); | |
| EXPECT_EQ(result.name(), "Required.Proto2.JsonInput.foo.ProtobufOutput"); | |
| EXPECT_EQ(result.strictness(), TestStrictness::kRequired); | |
| EXPECT_EQ(result.type(), TestAllTypesProto2::descriptor()); | |
| EXPECT_THAT(result.format(), ::conformance::PROTOBUF); | |
| EXPECT_THAT(result.response(), EqualsProto(R"pb(runtime_error: "error")pb")); | |
| } | |
| TEST(TesteeTest, InvalidResponse) { | |
| MockTestRunner mock; | |
| Testee testee(&mock); | |
| EXPECT_CALL( | |
| mock, | |
| RunTest("Required.Proto2.ProtobufInput.foo.ProtobufOutput", | |
| RequestEquals(R"pb( | |
| protobuf_payload: "wire" | |
| requested_output_format: PROTOBUF | |
| message_type: "protobuf_test_messages.proto2.TestAllTypesProto2" | |
| test_category: BINARY_TEST | |
| )pb"))) | |
| .WillOnce(Return(std::string("\004"))); | |
| TestResult result = | |
| testee.CreateTest("foo", TestStrictness::kRequired) | |
| .ParseBinary(TestAllTypesProto2::descriptor(), Wire("wire")) | |
| .SerializeBinary(); | |
| EXPECT_EQ(result.name(), "Required.Proto2.ProtobufInput.foo.ProtobufOutput"); | |
| EXPECT_EQ(result.strictness(), TestStrictness::kRequired); | |
| EXPECT_EQ(result.type(), TestAllTypesProto2::descriptor()); | |
| EXPECT_THAT(result.format(), ::conformance::PROTOBUF); | |
| EXPECT_THAT( | |
| result.response(), | |
| EqualsProto( | |
| R"pb(runtime_error: "response proto could not be parsed.")pb")); | |
| } | |
| TEST(TesteeTest, DuplicateTestName) { | |
| MockTestRunner mock; | |
| Testee testee(&mock); | |
| EXPECT_CALL( | |
| mock, | |
| RunTest("Required.Proto2.ProtobufInput.foo.ProtobufOutput", | |
| RequestEquals(R"pb( | |
| protobuf_payload: "wire" | |
| requested_output_format: PROTOBUF | |
| message_type: "protobuf_test_messages.proto2.TestAllTypesProto2" | |
| test_category: BINARY_TEST | |
| )pb"))) | |
| .WillRepeatedly(Return(std::string("\004"))); | |
| TestResult result = | |
| testee.CreateTest("foo", TestStrictness::kRequired) | |
| .ParseBinary(TestAllTypesProto2::descriptor(), Wire("wire")) | |
| .SerializeBinary(); | |
| EXPECT_DEATH( | |
| testee.CreateTest("foo", TestStrictness::kRequired) | |
| .ParseBinary(TestAllTypesProto2::descriptor(), Wire("wire")) | |
| .SerializeBinary(), | |
| "Duplicated test name: Required.Proto2.ProtobufInput.foo.ProtobufOutput"); | |
| } | |
| } // namespace | |
| } // namespace internal | |
| } // namespace conformance | |
| } // namespace protobuf | |
| } // namespace google |