blob: 97b90dadaae1c887e0ba72e1246b0698cee90819 [file] [log] [blame]
#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