| #include "binary_wireformat.h" |
| |
| #include <cstdint> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| #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<TagTestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| TagTest, TagTest, |
| testing::ValuesIn(std::vector<TagTestCase>{ |
| {.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<TagTest::ParamType>& 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<VarintTestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| VarintTest, VarintTest, |
| testing::ValuesIn(std::vector<VarintTestCase>{ |
| {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<VarintTest::ParamType>& 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<LongVarintTestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| LongVarintTest, LongVarintTest, |
| testing::ValuesIn(std::vector<LongVarintTestCase>{ |
| {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<LongVarintTest::ParamType>& 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<SInt32TestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| SInt32Test, SInt32Test, |
| testing::ValuesIn(std::vector<SInt32TestCase>{ |
| {0, std::string("\000", 1)}, // |
| {1, "\002"}, |
| {-1, "\001"}}), |
| [](const testing::TestParamInfo<SInt32Test::ParamType>& 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<SInt64TestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| SInt64Test, SInt64Test, |
| testing::ValuesIn(std::vector<SInt64TestCase>{ |
| {0, std::string("\000", 1)}, // |
| {1, "\002"}, |
| {-1, "\001"}}), |
| [](const testing::TestParamInfo<SInt64Test::ParamType>& 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<Fixed32TestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| Fixed32Test, Fixed32Test, |
| testing::ValuesIn(std::vector<Fixed32TestCase>{ |
| {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<Fixed32Test::ParamType>& 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<Fixed64TestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| Fixed64Test, Fixed64Test, |
| testing::ValuesIn(std::vector<Fixed64TestCase>{ |
| {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<Fixed64Test::ParamType>& 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<FloatTestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| FloatTest, FloatTest, |
| testing::ValuesIn(std::vector<FloatTestCase>{ |
| {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<FloatTest::ParamType>& 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<DoubleTestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| DoubleTest, DoubleTest, |
| testing::ValuesIn(std::vector<DoubleTestCase>{ |
| {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<DoubleTest::ParamType>& 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<LengthPrefixedTestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P( |
| LengthPrefixedTest, LengthPrefixedTest, |
| testing::ValuesIn(std::vector<LengthPrefixedTestCase>{ |
| {"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<LengthPrefixedTest::ParamType>& 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<int>, std::vector<int>{}), |
| Wire(absl::string_view("\0", 1))); |
| } |
| |
| TEST(PackedTest, OneFixed32) { |
| EXPECT_EQ(Packed(Fixed32<int>, {9}), |
| Wire(absl::string_view("\001\011\000\000\000", 5))); |
| } |
| |
| TEST(PackedTest, Varints) { |
| EXPECT_EQ(Packed(Varint<int>, {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<int> v = {9, 8}; |
| EXPECT_EQ(Packed(Varint<int>, 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<int>, {1, 2, 3}), |
| Wire("\112\003\001\002\003")); |
| } |
| |
| TEST(FieldTest, PackedFieldContainer) { |
| std::vector<int> v = {1, 2, 3}; |
| EXPECT_EQ(PackedField(9, Varint<int>, v), Wire("\112\003\001\002\003")); |
| } |
| |
| } // namespace |
| } // namespace conformance |
| } // namespace protobuf |
| } // namespace google |