| #include "testee.h" |
| |
| #include <string> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.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; |
| request.ParseFromString(arg); |
| TextFormat::ParseFromString(expected_textproto, &expected); |
| if (!util::MessageDifferencer::Equals(request, expected)) { |
| std::string request_string; |
| 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; |
| 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 |