From d36c0c538a545fac5d9db6ba65c525246d4efa95 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 14:32:48 -0700 Subject: Down-integrate from google3. --- .../java/com/google/protobuf/LazyFieldTest.java | 2 +- .../test/java/com/google/protobuf/LiteTest.java | 108 +++++++++++++++++++++ .../java/com/google/protobuf/MapForProto2Test.java | 1 + .../src/test/java/com/google/protobuf/MapTest.java | 39 +++++++- .../test/java/com/google/protobuf/ParserTest.java | 27 +++++- .../test/java/com/google/protobuf/TestUtil.java | 2 + .../java/com/google/protobuf/TextFormatTest.java | 92 ++++++++++++++++++ 7 files changed, 265 insertions(+), 6 deletions(-) (limited to 'java/core/src/test/java') diff --git a/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java index 5f013f3c..f27e8e51 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java @@ -32,7 +32,6 @@ package com.google.protobuf; import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; -import java.io.IOException; import junit.framework.TestCase; /** @@ -89,6 +88,7 @@ public class LazyFieldTest extends TestCase { assertFalse(message.equals(lazyField.getValue())); } + @SuppressWarnings("EqualsIncompatibleType") // LazyField.equals() is not symmetric public void testEqualsObjectEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyField lazyField = createLazyFieldFromMessage(message); diff --git a/java/core/src/test/java/com/google/protobuf/LiteTest.java b/java/core/src/test/java/com/google/protobuf/LiteTest.java index 538432f7..98c637a9 100644 --- a/java/core/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/LiteTest.java @@ -52,6 +52,7 @@ import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime; import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo; import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals; import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof; +import java.nio.ByteBuffer; import junit.framework.TestCase; /** @@ -2174,6 +2175,24 @@ public class LiteTest extends TestCase { assertFalse(bar.equals(barPrime)); } + public void testEqualsAndHashCodeForTrickySchemaTypes() { + Foo foo1 = Foo.newBuilder() + .build(); + Foo foo2 = Foo.newBuilder() + .setSint64(1) + .build(); + Foo foo3 = Foo.newBuilder() + .putMyMap("key", "value2") + .build(); + Foo foo4 = Foo.newBuilder() + .setMyGroup(Foo.MyGroup.newBuilder().setValue(4).build()) + .build(); + + assertEqualsAndHashCodeAreFalse(foo1, foo2); + assertEqualsAndHashCodeAreFalse(foo1, foo3); + assertEqualsAndHashCodeAreFalse(foo1, foo4); + } + public void testOneofEquals() throws Exception { TestOneofEquals.Builder builder = TestOneofEquals.newBuilder(); TestOneofEquals message1 = builder.build(); @@ -2270,4 +2289,93 @@ public class LiteTest extends TestCase { // This tests that we don't infinite loop. TestRecursiveOneof.getDefaultInstance().hashCode(); } + + public void testParseFromByteBuffer() throws Exception { + TestAllTypesLite message = + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .addRepeatedString("hello") + .setOptionalNestedMessage(TestAllTypesLite.NestedMessage.newBuilder().setBb(7)) + .build(); + + TestAllTypesLite copy = + TestAllTypesLite.parseFrom(message.toByteString().asReadOnlyByteBuffer()); + + assertEquals(message, copy); + } + + public void testParseFromByteBufferThrows() { + try { + TestAllTypesLite.parseFrom(ByteBuffer.wrap(new byte[] { 0x5 })); + fail(); + } catch (InvalidProtocolBufferException expected) { + } + + TestAllTypesLite message = + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .addRepeatedString("hello") + .build(); + + ByteBuffer buffer = ByteBuffer.wrap(message.toByteArray(), 0, message.getSerializedSize() - 1); + try { + TestAllTypesLite.parseFrom(buffer); + fail(); + } catch (InvalidProtocolBufferException expected) { + assertEquals( + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .build(), + expected.getUnfinishedMessage()); + } + } + + public void testParseFromByteBuffer_extensions() throws Exception { + TestAllExtensionsLite message = + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .addExtension(UnittestLite.repeatedStringExtensionLite, "hello") + .setExtension( + UnittestLite.optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ) + .setExtension( + UnittestLite.optionalNestedMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(7).build()) + .build(); + + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + UnittestLite.registerAllExtensions(registry); + + TestAllExtensionsLite copy = + TestAllExtensionsLite.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry); + + assertEquals(message, copy); + } + + public void testParseFromByteBufferThrows_extensions() { + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + UnittestLite.registerAllExtensions(registry); + try { + TestAllExtensionsLite.parseFrom(ByteBuffer.wrap(new byte[] { 0x5 }), registry); + fail(); + } catch (InvalidProtocolBufferException expected) { + } + + TestAllExtensionsLite message = + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .addExtension(UnittestLite.repeatedStringExtensionLite, "hello") + .build(); + + ByteBuffer buffer = ByteBuffer.wrap(message.toByteArray(), 0, message.getSerializedSize() - 1); + try { + TestAllExtensionsLite.parseFrom(buffer, registry); + fail(); + } catch (InvalidProtocolBufferException expected) { + assertEquals( + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .build(), + expected.getUnfinishedMessage()); + } + } } diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java index cfe4c453..453d3928 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java @@ -759,6 +759,7 @@ public class MapForProto2Test extends TestCase { assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); } + // See additional coverage in TextFormatTest.java. public void testTextFormat() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); diff --git a/java/core/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java index 81e951cc..01b371a3 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -30,7 +30,7 @@ package com.google.protobuf; - +import static org.junit.Assert.assertArrayEquals; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -870,6 +870,7 @@ public class MapTest extends TestCase { assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); } + // See additional coverage in TextFormatTest.java. public void testTextFormat() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -1492,4 +1493,40 @@ public class MapTest extends TestCase { map.put(key3, value3); return map; } + + public void testMap_withNulls() { + TestMap.Builder builder = TestMap.newBuilder(); + + try { + builder.putStringToInt32Field(null, 3); + fail(); + } catch (NullPointerException expected) { + } + + try { + builder.putAllStringToInt32Field(newMap(null, 3, "hi", 4)); + fail(); + } catch (NullPointerException expected) { + } + + try { + builder.putInt32ToMessageField(3, null); + fail(); + } catch (NullPointerException expected) { + } + + try { + builder.putAllInt32ToMessageField(newMap(4, null, 5, null)); + fail(); + } catch (NullPointerException expected) { + } + + try { + builder.putAllInt32ToMessageField(null); + fail(); + } catch (NullPointerException expected) { + } + + assertArrayEquals(new byte[0], builder.build().toByteArray()); + } } diff --git a/java/core/src/test/java/com/google/protobuf/ParserTest.java b/java/core/src/test/java/com/google/protobuf/ParserTest.java index 8c2e4c26..4bd34112 100644 --- a/java/core/src/test/java/com/google/protobuf/ParserTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParserTest.java @@ -79,6 +79,8 @@ public class ParserTest extends TestCase { new ByteArrayInputStream(data), registry)); assertMessageEquals(message, parser.parseFrom( CodedInputStream.newInstance(data), registry)); + assertMessageEquals( + message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry)); } @SuppressWarnings("unchecked") @@ -99,6 +101,7 @@ public class ParserTest extends TestCase { new ByteArrayInputStream(data))); assertMessageEquals(message, parser.parseFrom( CodedInputStream.newInstance(data))); + assertMessageEquals(message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer())); } private void assertMessageEquals( @@ -178,6 +181,9 @@ public class ParserTest extends TestCase { public void testParseExtensions() throws Exception { assertRoundTripEquals(TestUtil.getAllExtensionsSet(), TestUtil.getExtensionRegistry()); + } + + public void testParseExtensionsLite() throws Exception { assertRoundTripEquals( TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite()); } @@ -186,6 +192,9 @@ public class ParserTest extends TestCase { assertRoundTripEquals(TestUtil.getPackedSet()); assertRoundTripEquals(TestUtil.getPackedExtensionsSet(), TestUtil.getExtensionRegistry()); + } + + public void testParsePackedLite() throws Exception { assertRoundTripEquals( TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite()); } @@ -195,15 +204,26 @@ public class ParserTest extends TestCase { TestAllTypes normalMessage = TestUtil.getAllSet(); ByteArrayOutputStream output = new ByteArrayOutputStream(); normalMessage.writeDelimitedTo(output); + normalMessage.writeDelimitedTo(output); + InputStream input = new ByteArrayInputStream(output.toByteArray()); + assertMessageEquals(normalMessage, normalMessage.getParserForType().parseDelimitedFrom(input)); + assertMessageEquals(normalMessage, normalMessage.getParserForType().parseDelimitedFrom(input)); + } + + public void testParseDelimitedToLite() throws Exception { // Write MessageLite with packed extension fields. TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + packedMessage.writeDelimitedTo(output); packedMessage.writeDelimitedTo(output); InputStream input = new ByteArrayInputStream(output.toByteArray()); assertMessageEquals( - normalMessage, - normalMessage.getParserForType().parseDelimitedFrom(input)); + packedMessage, + packedMessage + .getParserForType() + .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite())); assertMessageEquals( packedMessage, packedMessage @@ -314,8 +334,7 @@ public class ParserTest extends TestCase { public void testParsingMergeLite() throws Exception { // Build messages. - TestAllTypesLite.Builder builder = - TestAllTypesLite.newBuilder(); + TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder(); TestAllTypesLite msg1 = builder.setOptionalInt32(1).build(); builder.clear(); TestAllTypesLite msg2 = builder.setOptionalInt64(2).build(); diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java index c1bd21db..e96adf07 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java @@ -2622,6 +2622,8 @@ public final class TestUtil { break; case FOO_NOT_SET: break; + default: + // TODO(b/18683919): go/enum-switch-lsc } } diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java index 6a91b02f..249d7c5e 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -30,9 +30,12 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy; +import map_test.MapTestProto.TestMap; import protobuf_unittest.UnittestMset.TestMessageSetExtension1; import protobuf_unittest.UnittestMset.TestMessageSetExtension2; import protobuf_unittest.UnittestProto.OneString; @@ -940,6 +943,7 @@ public class TextFormatTest extends TestCase { } + // See additional coverage in testOneofOverwriteForbidden and testMapOverwriteForbidden. public void testParseNonRepeatedFields() throws Exception { assertParseSuccessWithOverwriteForbidden( "repeated_int32: 1\n" + @@ -950,6 +954,7 @@ public class TextFormatTest extends TestCase { assertParseSuccessWithOverwriteForbidden( "repeated_nested_message { bb: 1 }\n" + "repeated_nested_message { bb: 2 }\n"); + assertParseErrorWithOverwriteForbidden( "3:17: Non-repeated field " + "\"protobuf_unittest.TestAllTypes.optional_int32\" " + @@ -988,6 +993,7 @@ public class TextFormatTest extends TestCase { assertParseSuccessWithOverwriteForbidden("repeated_int32: [ 1, 2 ]\n"); assertParseSuccessWithOverwriteForbidden("RepeatedGroup [{ a: 1 },{ a: 2 }]\n"); assertParseSuccessWithOverwriteForbidden("repeated_nested_message [{ bb: 1 }, { bb: 2 }]\n"); + // See also testMapShortForm. } public void testParseShortRepeatedFormOfEmptyRepeatedFields() throws Exception { @@ -995,6 +1001,7 @@ public class TextFormatTest extends TestCase { assertParseSuccessWithOverwriteForbidden("repeated_int32: []\n"); assertParseSuccessWithOverwriteForbidden("RepeatedGroup []\n"); assertParseSuccessWithOverwriteForbidden("repeated_nested_message []\n"); + // See also testMapShortFormEmpty. } public void testParseShortRepeatedFormWithTrailingComma() throws Exception { @@ -1010,6 +1017,7 @@ public class TextFormatTest extends TestCase { assertParseErrorWithOverwriteForbidden( "1:37: Expected \"{\".", "repeated_nested_message [{ bb: 1 }, ]\n"); + // See also testMapShortFormTrailingComma. } public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception { @@ -1057,6 +1065,90 @@ public class TextFormatTest extends TestCase { assertTrue(oneof.hasFooInt()); } + // ======================================================================= + // test map + + public void testMapTextFormat() throws Exception { + TestMap message = + TestMap.newBuilder() + .putInt32ToStringField(10, "apple") + .putInt32ToStringField(20, "banana") + .putInt32ToStringField(30, "cherry") + .build(); + String text = TextFormat.printToUnicodeString(message); + { + TestMap.Builder dest = TestMap.newBuilder(); + TextFormat.merge(text, dest); + assertThat(dest.build()).isEqualTo(message); + } + { + TestMap.Builder dest = TestMap.newBuilder(); + parserWithOverwriteForbidden.merge(text, dest); + assertThat(dest.build()).isEqualTo(message); + } + } + + public void testMapShortForm() throws Exception { + String text = + "string_to_int32_field [{ key: 'x' value: 10 }, { key: 'y' value: 20 }]\n" + + "int32_to_message_field " + + "[{ key: 1 value { value: 100 } }, { key: 2 value: { value: 200 } }]\n"; + TestMap.Builder dest = TestMap.newBuilder(); + parserWithOverwriteForbidden.merge(text, dest); + TestMap message = dest.build(); + assertThat(message.getStringToInt32Field().size()).isEqualTo(2); + assertThat(message.getInt32ToMessageField().size()).isEqualTo(2); + assertThat(message.getStringToInt32Field().get("x")).isEqualTo(10); + assertThat(message.getInt32ToMessageField().get(2).getValue()).isEqualTo(200); + } + + public void testMapShortFormEmpty() throws Exception { + String text = "string_to_int32_field []\n" + + "int32_to_message_field: []\n"; + TestMap.Builder dest = TestMap.newBuilder(); + parserWithOverwriteForbidden.merge(text, dest); + TestMap message = dest.build(); + assertThat(message.getStringToInt32Field().size()).isEqualTo(0); + assertThat(message.getInt32ToMessageField().size()).isEqualTo(0); + } + + public void testMapShortFormTrailingComma() throws Exception { + String text = "string_to_int32_field [{ key: 'x' value: 10 }, ]\n"; + TestMap.Builder dest = TestMap.newBuilder(); + try { + parserWithOverwriteForbidden.merge(text, dest); + fail("Expected parse exception."); + } catch (TextFormat.ParseException e) { + assertThat(e).hasMessageThat().isEqualTo("1:48: Expected \"{\"."); + } + } + + public void testMapOverwrite() throws Exception { + String text = + "int32_to_int32_field { key: 1 value: 10 }\n" + + "int32_to_int32_field { key: 2 value: 20 }\n" + + "int32_to_int32_field { key: 1 value: 30 }\n"; + + { + // With default parser, last value set for the key holds. + TestMap.Builder builder = TestMap.newBuilder(); + defaultParser.merge(text, builder); + TestMap map = builder.build(); + assertThat(map.getInt32ToInt32Field().size()).isEqualTo(2); + assertThat(map.getInt32ToInt32Field().get(1).intValue()).isEqualTo(30); + } + + { + // With overwrite forbidden, same behavior. + // TODO(b/29122459): Expect parse exception here. + TestMap.Builder builder = TestMap.newBuilder(); + defaultParser.merge(text, builder); + TestMap map = builder.build(); + assertThat(map.getInt32ToInt32Field().size()).isEqualTo(2); + assertThat(map.getInt32ToInt32Field().get(1).intValue()).isEqualTo(30); + } + } + // ======================================================================= // test location information -- cgit v1.2.3