diff options
Diffstat (limited to 'src/google/protobuf/map_test.cc')
-rw-r--r-- | src/google/protobuf/map_test.cc | 115 |
1 files changed, 110 insertions, 5 deletions
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index beaacc47..080b9dfc 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -79,6 +79,8 @@ #include <google/protobuf/stubs/casts.h> +#include <google/protobuf/port_def.inc> + namespace google { namespace protobuf { @@ -1977,7 +1979,7 @@ TEST(GeneratedMapFieldTest, CopyAssignmentOperator) { MapTestUtil::ExpectMapFieldsSet(message2); } -#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || GOOGLE_PROTOBUF_RTTI +#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || PROTOBUF_RTTI TEST(GeneratedMapFieldTest, UpcastCopyFrom) { // Test the CopyFrom method that takes in the generic const Message& // parameter. @@ -2205,6 +2207,7 @@ TEST(GeneratedMapFieldTest, UnorderedWireFormat) { EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); + ASSERT_NE(message.map_int32_int32().find(2), message.map_int32_int32().end()); EXPECT_EQ(1, message.map_int32_int32().at(2)); } @@ -2280,10 +2283,21 @@ TEST(GeneratedMapFieldTest, KeysValuesUnknownsWireFormat) { wire_format.push_back(c); if (is_key) expected_key = static_cast<int>(c); if (is_value) expected_value = static_cast<int>(c); - ASSERT_TRUE(message.ParseFromString(wire_format)); - ASSERT_EQ(1, message.map_int32_int32().size()); - ASSERT_EQ(expected_key, message.map_int32_int32().begin()->first); - ASSERT_EQ(expected_value, message.map_int32_int32().begin()->second); + bool res = message.ParseFromString(wire_format); + bool expect_success = true; +#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER + // Unfortunately the old map parser accepts malformed input, the new + // parser accepts only correct input. + if (j != items - 1) expect_success = false; +#endif + if (expect_success) { + ASSERT_TRUE(res); + ASSERT_EQ(1, message.map_int32_int32().size()); + ASSERT_EQ(expected_key, message.map_int32_int32().begin()->first); + ASSERT_EQ(expected_value, message.map_int32_int32().begin()->second); + } else { + ASSERT_FALSE(res); + } } } } @@ -2308,6 +2322,7 @@ TEST(GeneratedMapFieldTest, MissedKeyWireFormat) { EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); + ASSERT_NE(message.map_int32_int32().find(0), message.map_int32_int32().end()); EXPECT_EQ(1, message.map_int32_int32().at(0)); } @@ -2319,6 +2334,7 @@ TEST(GeneratedMapFieldTest, MissedValueWireFormat) { EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); + ASSERT_NE(message.map_int32_int32().find(1), message.map_int32_int32().end()); EXPECT_EQ(0, message.map_int32_int32().at(1)); } @@ -3178,6 +3194,23 @@ TEST(TextFormatMapTest, SerializeAndParse) { MapTestUtil::ExpectMapFieldsSet(dest); } +TEST(TextFormatMapTest, DynamicMessage) { + TestMap prototype; + DynamicMessageFactory factory; + std::unique_ptr<Message> message( + factory.GetPrototype(prototype.GetDescriptor())->New()); + MapReflectionTester tester(message->GetDescriptor()); + tester.SetMapFieldsViaReflection(message.get()); + + string expected_text; + GOOGLE_CHECK_OK(File::GetContents( + TestUtil::GetTestDataPath("net/proto2/internal/" + "testdata/map_test_data.txt"), + &expected_text, true)); + + EXPECT_EQ(message->DebugString(), expected_text); +} + TEST(TextFormatMapTest, Sorted) { unittest::TestMap message; MapReflectionTester tester(message.GetDescriptor()); @@ -3211,6 +3244,78 @@ TEST(TextFormatMapTest, ParseCorruptedString) { TestParseCorruptedString<protobuf_unittest::TestMaps, false>(message); } +// Previously, serializing to text format will disable iterator from generated +// API. Now, the iterator can be still used even after serializing to text +// format. +TEST(TextFormatMapTest, NoDisableIterator) { + unittest::TestMap source; + (*source.mutable_map_int32_int32())[1] = 1; + + // Get iterator. + Map<int32, int32>::iterator iter = + source.mutable_map_int32_int32()->find(1); + + // Serialize message to text format, which will invalidate the previous + // iterator previously. + string output; + TextFormat::Printer printer; + printer.PrintToString(source, &output); + + // Modify map via the iterator (invalidated in prvious implementation.). + iter->second = 2; + + // In previous implementation, the new change won't be reflected in text + // format, because the previous iterator has been invalidated. + output.clear(); + printer.PrintToString(source, &output); + string expected = + "map_int32_int32 {\n" + " key: 1\n" + " value: 2\n" + "}\n"; + EXPECT_EQ(output, expected); +} + +// Previously, serializing to text format will disable iterator from reflection +// API. +TEST(TextFormatMapTest, NoDisableReflectionIterator) { + unittest::TestMap source; + (*source.mutable_map_int32_int32())[1] = 1; + + // Get iterator. This will also sync internal repeated field with map inside + // of MapField. + const Reflection* reflection = source.GetReflection(); + const FieldDescriptor* field_desc = + source.GetDescriptor()->FindFieldByName("map_int32_int32"); + RepeatedPtrField<Message>* map_field = + reflection->MutableRepeatedPtrField<Message>(&source, field_desc); + RepeatedPtrField<Message>::iterator iter = map_field->begin(); + + // Serialize message to text format, which will invalidate the prvious + // iterator previously. + string output; + TextFormat::Printer printer; + printer.PrintToString(source, &output); + + // Modify map via the iterator (invalidated in prvious implementation.). + const Reflection* map_entry_reflection = iter->GetReflection(); + const FieldDescriptor* value_field_desc = + iter->GetDescriptor()->FindFieldByName("value"); + map_entry_reflection->SetInt32(&(*iter), value_field_desc, 2); + GOOGLE_LOG(INFO) << iter->DebugString(); + + // In previous implementation, the new change won't be reflected in text + // format, because the previous iterator has been invalidated. + output.clear(); + printer.PrintToString(source, &output); + string expected = + "map_int32_int32 {\n" + " key: 1\n" + " value: 2\n" + "}\n"; + EXPECT_EQ(output, expected); +} + // arena support ================================================= TEST(ArenaTest, ParsingAndSerializingNoHeapAllocation) { |