#include "binary_wireformat.h" #include #include #include #include #include #include "absl/strings/str_cat.h" #include "absl/strings/str_replace.h" #include "absl/strings/string_view.h" namespace google { namespace protobuf { namespace conformance { namespace { TEST(WireTest, Constructor) { Wire wire("foo"); EXPECT_EQ(wire.size(), 3); EXPECT_EQ(wire.data(), "foo"); } TEST(WireTest, ConstructorConcat) { Wire wire("foo", "bar"); EXPECT_EQ(wire.size(), 6); EXPECT_EQ(wire.data(), "foobar"); } TEST(WireTest, CopyConstructor) { Wire wire("foo"); Wire copy(wire); EXPECT_EQ(copy.data(), "foo"); } TEST(WireTest, MoveConstructor) { Wire wire("foo"); Wire move(std::move(wire)); EXPECT_EQ(move.data(), "foo"); } TEST(WireTest, CopyAssignement) { Wire wire("foo"); Wire copy; copy = wire; EXPECT_EQ(copy.data(), "foo"); } TEST(WireTest, MoveAssignement) { Wire wire("foo"); Wire move; move = std::move(wire); EXPECT_EQ(move.data(), "foo"); } TEST(WireTest, Comparison) { Wire wire("foo", absl::string_view("\0", 1), "bar"); ASSERT_EQ(wire.size(), 7); EXPECT_TRUE(wire == Wire(absl::string_view("foo\0bar", 7))); EXPECT_FALSE(wire != Wire(absl::string_view("foo\0bar", 7))); EXPECT_FALSE(wire == Wire("foo")); EXPECT_TRUE(wire != Wire("foo")); } TEST(WireTest, Stringify) { Wire wire("\xa0\032"); std::string str = absl::StrCat(wire, Wire("abc")); EXPECT_EQ(str, "\240\032abc"); } TEST(WireTest, PrintTo) { Wire wire("\xa0\032abc"); std::string str = testing::PrintToString(wire); EXPECT_EQ(str, "\\240\\032abc"); } struct TagTestCase { std::string name; uint32_t fieldnum; WireType wire_type; std::string expected; }; class TagTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( TagTest, TagTest, testing::ValuesIn(std::vector{ {.name = "Varint", .fieldnum = 1, .wire_type = WireType::kVarint, .expected = "\010"}, {.name = "Fixed32", .fieldnum = 2, .wire_type = WireType::kFixed32, .expected = "\025"}, {.name = "Fixed64", .fieldnum = 3, .wire_type = WireType::kFixed64, .expected = "\031"}, {.name = "LengthPrefixed", .fieldnum = 4, .wire_type = WireType::kLengthPrefixed, .expected = "\042"}, {.name = "StartGroup", .fieldnum = 5, .wire_type = WireType::kStartGroup, .expected = "\053"}, {.name = "EndGroup", .fieldnum = 6, .wire_type = WireType::kEndGroup, .expected = "\064"}, {.name = "TwoByteTag", .fieldnum = 256, .wire_type = WireType::kStartGroup, .expected = "\203\020"}, {.name = "ThreeByteTag", .fieldnum = 0xFFFF, .wire_type = WireType::kStartGroup, .expected = "\373\377\037"}}), [](const testing::TestParamInfo& info) { return info.param.name; }); TEST_P(TagTest, Check) { auto& param = GetParam(); EXPECT_EQ(Tag(param.fieldnum, param.wire_type), Wire(param.expected)); } struct VarintTestCase { uint64_t value; std::string expected; }; class VarintTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( VarintTest, VarintTest, testing::ValuesIn(std::vector{ {0, std::string("\000", 1)}, {1, "\001"}, {127, "\177"}, {128, "\200\001"}, {128 * 128, "\200\200\001"}, {128 * 128 * 128, "\200\200\200\001"}}), [](const testing::TestParamInfo& info) { return absl::StrCat(info.param.value); }); TEST_P(VarintTest, Check) { auto& param = GetParam(); EXPECT_EQ(Varint(param.value), Wire(param.expected)); } struct LongVarintTestCase { uint64_t value; int extra; std::string expected; }; class LongVarintTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( LongVarintTest, LongVarintTest, testing::ValuesIn(std::vector{ {0, 1, std::string("\000", 1)}, {1, 1, std::string("\201\000", 2)}, {1, 4, std::string("\201\200\200\200\000", 5)}, {127, 1, std::string("\377\000", 2)}, {128, 1, std::string("\200\201\000", 3)}}), [](const testing::TestParamInfo& info) { return absl::StrCat(info.param.value, "_", info.param.extra); }); TEST_P(LongVarintTest, Check) { auto& param = GetParam(); EXPECT_EQ(LongVarint(param.value, param.extra), Wire(param.expected)); } struct SInt32TestCase { int32_t value; std::string expected; }; class SInt32Test : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( SInt32Test, SInt32Test, testing::ValuesIn(std::vector{ {0, std::string("\000", 1)}, // {1, "\002"}, {-1, "\001"}}), [](const testing::TestParamInfo& info) { return absl::StrReplaceAll(absl::StrCat(info.param.value), {{"-", "neg"}}); }); TEST_P(SInt32Test, Check) { auto& param = GetParam(); EXPECT_EQ(SInt32(param.value), Wire(param.expected)); } struct SInt64TestCase { int64_t value; std::string expected; }; class SInt64Test : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( SInt64Test, SInt64Test, testing::ValuesIn(std::vector{ {0, std::string("\000", 1)}, // {1, "\002"}, {-1, "\001"}}), [](const testing::TestParamInfo& info) { return absl::StrReplaceAll(absl::StrCat(info.param.value), {{"-", "neg"}}); }); TEST_P(SInt64Test, Check) { auto& param = GetParam(); EXPECT_EQ(SInt64(param.value), Wire(param.expected)); } struct Fixed32TestCase { uint32_t value; std::string expected; }; class Fixed32Test : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( Fixed32Test, Fixed32Test, testing::ValuesIn(std::vector{ {0, std::string(4, '\0')}, {128, std::string("\200\0\0\0", 4)}, {0x80000000U, std::string("\0\0\0\200", 4)}, {0xFEDCBA98U, "\x98\xba\xdc\xfe"}, {0xFFFFFFFFU, "\xff\xff\xff\xff"}, }), [](const testing::TestParamInfo& info) { return absl::StrCat(info.param.value); }); TEST_P(Fixed32Test, Check) { auto& param = GetParam(); EXPECT_EQ(Fixed32(param.value), Wire(param.expected)); } struct Fixed64TestCase { uint64_t value; std::string expected; }; class Fixed64Test : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( Fixed64Test, Fixed64Test, testing::ValuesIn(std::vector{ {0, std::string(8, '\0')}, {128, std::string("\200\0\0\0\0\0\0\0", 8)}, {0x8000000000000000UL, std::string("\0\0\0\0\0\0\0\200", 8)}, {0xFEDCBA9876543210UL, "\x10\x32\x54\x76\x98\xba\xdc\xfe"}, {0xFFFFFFFFFFFFFFFFUL, "\xff\xff\xff\xff\xff\xff\xff\xff"}, }), [](const testing::TestParamInfo& info) { return absl::StrCat(info.param.value); }); TEST_P(Fixed64Test, Check) { auto& param = GetParam(); EXPECT_EQ(Fixed64(param.value), Wire(param.expected)); } struct FloatTestCase { float value; std::string expected; }; class FloatTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( FloatTest, FloatTest, testing::ValuesIn(std::vector{ {0, std::string(4, '\0')}, {-1, std::string("\0\0\200\277", 4)}, {1, std::string("\0\0\200\077", 4)}, {1.5, std::string("\0\0\300\077", 4)}, {1.123456, "\150\315\217\077"}, }), [](const testing::TestParamInfo& info) { return absl::StrReplaceAll(absl::StrCat(info.param.value), {{".", "_"}, {"-", "neg"}}); }); TEST_P(FloatTest, Check) { auto& param = GetParam(); EXPECT_EQ(Float(param.value), Wire(param.expected)); } struct DoubleTestCase { double value; std::string expected; }; class DoubleTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( DoubleTest, DoubleTest, testing::ValuesIn(std::vector{ {0, std::string(8, '\0')}, {-1, std::string("\0\0\0\0\0\0\360\277", 8)}, {1, std::string("\0\0\0\0\0\0\360\077", 8)}, {1.5, std::string("\0\0\0\0\0\0\370\077", 8)}, {1.123456, "\154\353\247\377\254\371\361\077"}, }), [](const testing::TestParamInfo& info) { return absl::StrReplaceAll(absl::StrCat(info.param.value), {{".", "_"}, {"-", "neg"}}); }); TEST_P(DoubleTest, Check) { auto& param = GetParam(); EXPECT_EQ(Double(param.value), Wire(param.expected)); } struct LengthPrefixedTestCase { std::string name; std::string value; std::string expected; }; class LengthPrefixedTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P( LengthPrefixedTest, LengthPrefixedTest, testing::ValuesIn(std::vector{ {"Empty", "", std::string("\0", 1)}, {"Ascii", "abc", "\003abc"}, {"NonAscii", "\x80\x81\x82", "\003\x80\x81\x82"}, {"Long", std::string(128, 'a'), "\200\001" + std::string(128, 'a')}, }), [](const testing::TestParamInfo& info) { return info.param.name; }); TEST_P(LengthPrefixedTest, Check) { auto& param = GetParam(); EXPECT_EQ(LengthPrefixed(param.value), Wire(param.expected)); } TEST_F(LengthPrefixedTest, Nested) { EXPECT_EQ(LengthPrefixed(Wire("foo")), Wire("\003foo")); } TEST(PackedTest, Empty) { EXPECT_EQ(Packed(Varint, std::vector{}), Wire(absl::string_view("\0", 1))); } TEST(PackedTest, OneFixed32) { EXPECT_EQ(Packed(Fixed32, {9}), Wire(absl::string_view("\001\011\000\000\000", 5))); } TEST(PackedTest, Varints) { EXPECT_EQ(Packed(Varint, {9, 8}), Wire("\002\011\010")); } TEST(PackedTest, SInt32s) { EXPECT_EQ(Packed(SInt32, {0, 1, -1}), Wire(absl::string_view("\003\000\002\001", 4))); } TEST(PackedTest, Container) { std::vector v = {9, 8}; EXPECT_EQ(Packed(Varint, v), Wire("\002\011\010")); } TEST(FieldTest, VarintField) { EXPECT_EQ(VarintField(9, 1), Wire("\110\001")); } TEST(FieldTest, LongVarintField) { EXPECT_EQ(LongVarintField(9, 1, 1), Wire(absl::string_view("\110\201\000", 3))); } TEST(FieldTest, SInt32Field) { EXPECT_EQ(SInt32Field(9, -1), Wire("\110\001")); } TEST(FieldTest, SInt64Field) { EXPECT_EQ(SInt64Field(9, -1), Wire("\110\001")); } TEST(FieldTest, Fixed32Field) { EXPECT_EQ(Fixed32Field(9, 1), Wire(absl::string_view("\115\1\0\0\0", 5))); } TEST(FieldTest, Fixed64Field) { EXPECT_EQ(Fixed64Field(9, 1), Wire(absl::string_view("\111\1\0\0\0\0\0\0\0", 9))); } TEST(FieldTest, FloatField) { EXPECT_EQ(FloatField(9, 1), Wire(absl::string_view("\115\0\0\200\077", 5))); } TEST(FieldTest, DoubleField) { EXPECT_EQ(DoubleField(9, 1), Wire(absl::string_view("\111\0\0\0\0\0\0\360\077", 9))); } TEST(FieldTest, LengthPrefixedField) { EXPECT_EQ(LengthPrefixedField(9, "foo"), Wire("\112\003foo")); } TEST(FieldTest, LengthPrefixedFieldNested) { EXPECT_EQ(LengthPrefixedField(9, Wire("foo")), Wire("\112\003foo")); } TEST(FieldTest, DelimitedField) { EXPECT_EQ(DelimitedField(9, Wire("foo")), Wire("\113foo\114")); } TEST(FieldTest, PackedField) { EXPECT_EQ(PackedField(9, Varint, {1, 2, 3}), Wire("\112\003\001\002\003")); } TEST(FieldTest, PackedFieldContainer) { std::vector v = {1, 2, 3}; EXPECT_EQ(PackedField(9, Varint, v), Wire("\112\003\001\002\003")); } } // namespace } // namespace conformance } // namespace protobuf } // namespace google