diff options
author | liujisi@google.com <liujisi@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2010-11-02 13:14:58 +0000 |
---|---|---|
committer | liujisi@google.com <liujisi@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2010-11-02 13:14:58 +0000 |
commit | 33165fe0d5c265c92f2a67fc2b437b567c24e294 (patch) | |
tree | 52def0850ddd2e976da238d1a437fbda79c96e44 /java/src/test/java/com | |
parent | 80aa23df6c63750e8cdfdcf3996fbc37d63cac61 (diff) | |
download | protobuf-33165fe0d5c265c92f2a67fc2b437b567c24e294.tar.gz protobuf-33165fe0d5c265c92f2a67fc2b437b567c24e294.tar.bz2 protobuf-33165fe0d5c265c92f2a67fc2b437b567c24e294.zip |
Submit recent changes from internal branch. See CHANGES.txt for more details.
Diffstat (limited to 'java/src/test/java/com')
25 files changed, 2375 insertions, 86 deletions
diff --git a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java index c44d6605..d53ce8d7 100644 --- a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java +++ b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java @@ -366,7 +366,7 @@ public class AbstractMessageTest extends TestCase { // ----------------------------------------------------------------- // Tests for equals and hashCode - + public void testEqualsAndHashCode() throws Exception { TestAllTypes a = TestUtil.getAllSet(); TestAllTypes b = TestAllTypes.newBuilder().build(); @@ -382,7 +382,7 @@ public class AbstractMessageTest extends TestCase { checkEqualsIsConsistent(d); checkEqualsIsConsistent(e); checkEqualsIsConsistent(f); - + checkNotEqual(a, b); checkNotEqual(a, c); checkNotEqual(a, d); @@ -413,19 +413,20 @@ public class AbstractMessageTest extends TestCase { checkEqualsIsConsistent(eUnknownFields); checkEqualsIsConsistent(fUnknownFields); - // Subseqent reconstitutions should be identical + // Subsequent reconstitutions should be identical UnittestProto.TestEmptyMessage eUnknownFields2 = UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray()); checkEqualsIsConsistent(eUnknownFields, eUnknownFields2); } - + + /** * Asserts that the given proto has symetric equals and hashCode methods. */ private void checkEqualsIsConsistent(Message message) { // Object should be equal to itself. assertEquals(message, message); - + // Object should be equal to a dynamic copy of itself. DynamicMessage dynamic = DynamicMessage.newBuilder(message).build(); checkEqualsIsConsistent(message, dynamic); @@ -442,7 +443,7 @@ public class AbstractMessageTest extends TestCase { /** * Asserts that the given protos are not equal and have different hash codes. - * + * * @warning It's valid for non-equal objects to have the same hash code, so * this test is stricter than it needs to be. However, this should happen * relatively rarely. diff --git a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java index 6acd3223..83f7f8da 100644 --- a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java +++ b/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java @@ -325,6 +325,27 @@ public class CodedInputStreamTest extends TestCase { assertEquals(2, input.readRawByte()); } + /** + * Test that a bug in skipRawBytes() has been fixed: if the skip skips + * past the end of a buffer with a limit that has been set past the end of + * that buffer, this should not break things. + */ + public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception { + byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 }; + CodedInputStream input = CodedInputStream.newInstance( + new SmallBlockInputStream(rawBytes, 3)); + + int limit = input.pushLimit(4); + // In order to expose the bug we need to read at least one byte to prime the + // buffer inside the CodedInputStream. + assertEquals(1, input.readRawByte()); + // Skip to the end of the limit. + input.skipRawBytes(3); + assertTrue(input.isAtEnd()); + input.popLimit(limit); + assertEquals(5, input.readRawByte()); + } + public void testReadHugeBlob() throws Exception { // Allocate and initialize a 1MB blob. byte[] blob = new byte[1 << 20]; diff --git a/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java b/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java new file mode 100644 index 00000000..1f8bb445 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java @@ -0,0 +1,80 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestDeprecatedFields; + +import junit.framework.TestCase; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +/** + * Test field deprecation + * + * @author birdo@google.com (Roberto Scaramuzzi) + */ +public class DeprecatedFieldTest extends TestCase { + private String[] deprecatedGetterNames = { + "hasDeprecatedInt32", + "getDeprecatedInt32"}; + + private String[] deprecatedBuilderGetterNames = { + "hasDeprecatedInt32", + "getDeprecatedInt32", + "clearDeprecatedInt32"}; + + private String[] deprecatedBuilderSetterNames = { + "setDeprecatedInt32"}; + + public void testDeprecatedField() throws Exception { + Class<?> deprecatedFields = TestDeprecatedFields.class; + Class<?> deprecatedFieldsBuilder = TestDeprecatedFields.Builder.class; + for (String name : deprecatedGetterNames) { + Method method = deprecatedFields.getMethod(name); + assertTrue("Method " + name + " should be deprecated", + isDeprecated(method)); + } + for (String name : deprecatedBuilderGetterNames) { + Method method = deprecatedFieldsBuilder.getMethod(name); + assertTrue("Method " + name + " should be deprecated", + isDeprecated(method)); + } + for (String name : deprecatedBuilderSetterNames) { + Method method = deprecatedFieldsBuilder.getMethod(name, int.class); + assertTrue("Method " + name + " should be deprecated", + isDeprecated(method)); + } + } + + private boolean isDeprecated(AnnotatedElement annotated) { + return annotated.isAnnotationPresent(Deprecated.class); + } +} diff --git a/java/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/src/test/java/com/google/protobuf/DescriptorsTest.java index c77af5d2..65d06e32 100644 --- a/java/src/test/java/com/google/protobuf/DescriptorsTest.java +++ b/java/src/test/java/com/google/protobuf/DescriptorsTest.java @@ -44,6 +44,7 @@ import com.google.protobuf.Descriptors.MethodDescriptor; import com.google.protobuf.test.UnittestImport; import com.google.protobuf.test.UnittestImport.ImportEnum; +import com.google.protobuf.test.UnittestImport.ImportMessage; import protobuf_unittest.UnittestProto; import protobuf_unittest.UnittestProto.ForeignEnum; import protobuf_unittest.UnittestProto.ForeignMessage; diff --git a/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java b/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java new file mode 100644 index 00000000..108a28e1 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +/** + * A prerun for a test suite that allows running the full protocol buffer + * tests in a mode that disables the optimization for not using + * {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder} until they are + * requested. This allows us to run all the tests through both code paths + * and ensures that both code paths produce identical results. + * + * @author jonp@google.com (Jon Perlow) + */ +public class ForceFieldBuildersPreRun implements Runnable { + + @Override + public void run() { + GeneratedMessage.enableAlwaysUseFieldBuildersForTesting(); + } +} diff --git a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java index 73c71f31..3675e003 100644 --- a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java +++ b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java @@ -30,26 +30,43 @@ package com.google.protobuf; +import com.google.protobuf.UnittestLite.TestAllExtensionsLite; +import com.google.protobuf.test.UnittestImport; +import protobuf_unittest.EnumWithNoOuter; +import protobuf_unittest.MessageWithNoOuter; +import protobuf_unittest.MultipleFilesTestProto; +import protobuf_unittest.NestedExtension.MyNestedExtension; +import protobuf_unittest.NestedExtensionLite.MyNestedExtensionLite; +import protobuf_unittest.NonNestedExtension; +import protobuf_unittest.NonNestedExtension.MessageToBeExtended; +import protobuf_unittest.NonNestedExtension.MyNonNestedExtension; +import protobuf_unittest.NonNestedExtensionLite; +import protobuf_unittest.NonNestedExtensionLite.MessageLiteToBeExtended; +import protobuf_unittest.NonNestedExtensionLite.MyNonNestedExtensionLite; +import protobuf_unittest.ServiceWithNoOuter; import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize; import protobuf_unittest.UnittestOptimizeFor.TestOptionalOptimizedForSize; import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize; import protobuf_unittest.UnittestProto; -import protobuf_unittest.UnittestProto.ForeignMessage; import protobuf_unittest.UnittestProto.ForeignEnum; -import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.ForeignMessage; +import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder; import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; import protobuf_unittest.UnittestProto.TestExtremeDefaultValues; import protobuf_unittest.UnittestProto.TestPackedTypes; import protobuf_unittest.UnittestProto.TestUnpackedTypes; -import protobuf_unittest.MultipleFilesTestProto; -import protobuf_unittest.MessageWithNoOuter; -import protobuf_unittest.EnumWithNoOuter; -import protobuf_unittest.ServiceWithNoOuter; -import com.google.protobuf.UnittestLite; -import com.google.protobuf.UnittestLite.TestAllExtensionsLite; import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Unit test for generated messages and generated code. See also @@ -68,32 +85,111 @@ public class GeneratedMessageTest extends TestCase { TestAllTypes.newBuilder().getDefaultInstanceForType()); } - public void testAccessors() throws Exception { + public void testMessageOrBuilder() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); TestAllTypes message = builder.build(); TestUtil.assertAllFieldsSet(message); } - public void testDoubleBuildError() throws Exception { + public void testUsingBuilderMultipleTimes() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - builder.build(); - try { - builder.build(); - fail("Should have thrown exception."); - } catch (IllegalStateException e) { - // Success. - } + // primitive field scalar and repeated + builder.setOptionalSfixed64(100); + builder.addRepeatedInt32(100); + // enum field scalar and repeated + builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); + builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); + // proto field scalar and repeated + builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(1)); + builder.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(1)); + + TestAllTypes value1 = builder.build(); + + assertEquals(100, value1.getOptionalSfixed64()); + assertEquals(100, value1.getRepeatedInt32(0)); + assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, + value1.getOptionalImportEnum()); + assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, + value1.getRepeatedImportEnum(0)); + assertEquals(1, value1.getOptionalForeignMessage().getC()); + assertEquals(1, value1.getRepeatedForeignMessage(0).getC()); + + // Make sure that builder didn't update previously created values + builder.setOptionalSfixed64(200); + builder.setRepeatedInt32(0, 200); + builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_FOO); + builder.setRepeatedImportEnum(0, UnittestImport.ImportEnum.IMPORT_FOO); + builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(2)); + builder.setRepeatedForeignMessage(0, ForeignMessage.newBuilder().setC(2)); + + TestAllTypes value2 = builder.build(); + + // Make sure value1 didn't change. + assertEquals(100, value1.getOptionalSfixed64()); + assertEquals(100, value1.getRepeatedInt32(0)); + assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, + value1.getOptionalImportEnum()); + assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, + value1.getRepeatedImportEnum(0)); + assertEquals(1, value1.getOptionalForeignMessage().getC()); + assertEquals(1, value1.getRepeatedForeignMessage(0).getC()); + + // Make sure value2 is correct + assertEquals(200, value2.getOptionalSfixed64()); + assertEquals(200, value2.getRepeatedInt32(0)); + assertEquals(UnittestImport.ImportEnum.IMPORT_FOO, + value2.getOptionalImportEnum()); + assertEquals(UnittestImport.ImportEnum.IMPORT_FOO, + value2.getRepeatedImportEnum(0)); + assertEquals(2, value2.getOptionalForeignMessage().getC()); + assertEquals(2, value2.getRepeatedForeignMessage(0).getC()); + } + + public void testProtosShareRepeatedArraysIfDidntChange() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + builder.addRepeatedInt32(100); + builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); + builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance()); + + TestAllTypes value1 = builder.build(); + TestAllTypes value2 = value1.toBuilder().build(); + + assertSame(value1.getRepeatedInt32List(), value2.getRepeatedInt32List()); + assertSame(value1.getRepeatedImportEnumList(), + value2.getRepeatedImportEnumList()); + assertSame(value1.getRepeatedForeignMessageList(), + value2.getRepeatedForeignMessageList()); } - public void testClearAfterBuildError() throws Exception { + public void testRepeatedArraysAreImmutable() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - builder.build(); - try { - builder.clear(); - fail("Should have thrown exception."); - } catch (IllegalStateException e) { - // Success. + builder.addRepeatedInt32(100); + builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR); + builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance()); + assertIsUnmodifiable(builder.getRepeatedInt32List()); + assertIsUnmodifiable(builder.getRepeatedImportEnumList()); + assertIsUnmodifiable(builder.getRepeatedForeignMessageList()); + assertIsUnmodifiable(builder.getRepeatedFloatList()); + + + TestAllTypes value = builder.build(); + assertIsUnmodifiable(value.getRepeatedInt32List()); + assertIsUnmodifiable(value.getRepeatedImportEnumList()); + assertIsUnmodifiable(value.getRepeatedForeignMessageList()); + assertIsUnmodifiable(value.getRepeatedFloatList()); + } + + private void assertIsUnmodifiable(List<?> list) { + if (list == Collections.emptyList()) { + // OKAY -- Need to check this b/c EmptyList allows you to call clear. + } else { + try { + list.clear(); + fail("List wasn't immutable"); + } catch (UnsupportedOperationException e) { + // good + } } } @@ -316,9 +412,19 @@ public class GeneratedMessageTest extends TestCase { assertTrue(Float.isNaN(message.getNanFloat())); } + public void testClear() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.assertClear(builder); + TestUtil.setAllFields(builder); + builder.clear(); + TestUtil.assertClear(builder); + } + public void testReflectionGetters() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); + reflectionTester.assertAllFieldsSetViaReflection(builder); + TestAllTypes message = builder.build(); reflectionTester.assertAllFieldsSetViaReflection(message); } @@ -326,6 +432,8 @@ public class GeneratedMessageTest extends TestCase { public void testReflectionSetters() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); reflectionTester.setAllFieldsViaReflection(builder); + TestUtil.assertAllFieldsSet(builder); + TestAllTypes message = builder.build(); TestUtil.assertAllFieldsSet(message); } @@ -339,6 +447,8 @@ public class GeneratedMessageTest extends TestCase { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); reflectionTester.setAllFieldsViaReflection(builder); reflectionTester.modifyRepeatedFieldsViaReflection(builder); + TestUtil.assertRepeatedFieldsModified(builder); + TestAllTypes message = builder.build(); TestUtil.assertRepeatedFieldsModified(message); } @@ -391,7 +501,7 @@ public class GeneratedMessageTest extends TestCase { new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(), TestUtil.getExtensionRegistry()); - public void testExtensionAccessors() throws Exception { + public void testExtensionMessageOrBuilder() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); TestUtil.setAllExtensions(builder); TestAllExtensions message = builder.build(); @@ -414,6 +524,8 @@ public class GeneratedMessageTest extends TestCase { public void testExtensionReflectionGetters() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); TestUtil.setAllExtensions(builder); + extensionsReflectionTester.assertAllFieldsSetViaReflection(builder); + TestAllExtensions message = builder.build(); extensionsReflectionTester.assertAllFieldsSetViaReflection(message); } @@ -421,6 +533,8 @@ public class GeneratedMessageTest extends TestCase { public void testExtensionReflectionSetters() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); extensionsReflectionTester.setAllFieldsViaReflection(builder); + TestUtil.assertAllExtensionsSet(builder); + TestAllExtensions message = builder.build(); TestUtil.assertAllExtensionsSet(message); } @@ -434,6 +548,8 @@ public class GeneratedMessageTest extends TestCase { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); extensionsReflectionTester.setAllFieldsViaReflection(builder); extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder); + TestUtil.assertRepeatedExtensionsModified(builder); + TestAllExtensions message = builder.build(); TestUtil.assertRepeatedExtensionsModified(message); } @@ -491,9 +607,11 @@ public class GeneratedMessageTest extends TestCase { // lite fields directly since they are implemented exactly the same as // regular fields. - public void testLiteExtensionAccessors() throws Exception { + public void testLiteExtensionMessageOrBuilder() throws Exception { TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder(); TestUtil.setAllExtensions(builder); + TestUtil.assertAllExtensionsSet(builder); + TestAllExtensionsLite message = builder.build(); TestUtil.assertAllExtensionsSet(message); } @@ -502,6 +620,8 @@ public class GeneratedMessageTest extends TestCase { TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder(); TestUtil.setAllExtensions(builder); TestUtil.modifyRepeatedExtensions(builder); + TestUtil.assertRepeatedExtensionsModified(builder); + TestAllExtensionsLite message = builder.build(); TestUtil.assertRepeatedExtensionsModified(message); } @@ -609,6 +729,7 @@ public class GeneratedMessageTest extends TestCase { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); TestAllTypes message = builder.build(); + TestUtil.assertAllFieldsSet(message); TestUtil.assertAllFieldsSet(message.toBuilder().build()); } @@ -646,4 +767,207 @@ public class GeneratedMessageTest extends TestCase { assertTrue(message.getA() != null); assertTrue(message.getA() == message); } + + public void testSerialize() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestUtil.setAllFields(builder); + TestAllTypes expected = builder.build(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(expected); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + TestAllTypes actual = (TestAllTypes) in.readObject(); + assertEquals(expected, actual); + } + + public void testSerializePartial() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestAllTypes expected = builder.buildPartial(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(expected); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + TestAllTypes actual = (TestAllTypes) in.readObject(); + assertEquals(expected, actual); + } + + public void testEnumValues() { + assertEquals( + TestAllTypes.NestedEnum.BAR.getNumber(), + TestAllTypes.NestedEnum.BAR_VALUE); + assertEquals( + TestAllTypes.NestedEnum.BAZ.getNumber(), + TestAllTypes.NestedEnum.BAZ_VALUE); + assertEquals( + TestAllTypes.NestedEnum.FOO.getNumber(), + TestAllTypes.NestedEnum.FOO_VALUE); + } + + public void testNonNestedExtensionInitialization() { + assertTrue(NonNestedExtension.nonNestedExtension + .getMessageDefaultInstance() instanceof MyNonNestedExtension); + assertEquals("nonNestedExtension", + NonNestedExtension.nonNestedExtension.getDescriptor().getName()); + } + + public void testNestedExtensionInitialization() { + assertTrue(MyNestedExtension.recursiveExtension.getMessageDefaultInstance() + instanceof MessageToBeExtended); + assertEquals("recursiveExtension", + MyNestedExtension.recursiveExtension.getDescriptor().getName()); + } + + public void testNonNestedExtensionLiteInitialization() { + assertTrue(NonNestedExtensionLite.nonNestedExtensionLite + .getMessageDefaultInstance() instanceof MyNonNestedExtensionLite); + } + + public void testNestedExtensionLiteInitialization() { + assertTrue(MyNestedExtensionLite.recursiveExtensionLite + .getMessageDefaultInstance() instanceof MessageLiteToBeExtended); + } + + public void testInvalidations() throws Exception { + GeneratedMessage.enableAlwaysUseFieldBuildersForTesting(); + TestAllTypes.NestedMessage nestedMessage1 = + TestAllTypes.NestedMessage.newBuilder().build(); + TestAllTypes.NestedMessage nestedMessage2 = + TestAllTypes.NestedMessage.newBuilder().build(); + + // Set all three flavors (enum, primitive, message and singular/repeated) + // and verify no invalidations fired + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + + TestAllTypes.Builder builder = (TestAllTypes.Builder) + ((GeneratedMessage) TestAllTypes.getDefaultInstance()). + newBuilderForType(mockParent); + builder.setOptionalInt32(1); + builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR); + builder.setOptionalNestedMessage(nestedMessage1); + builder.addRepeatedInt32(1); + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR); + builder.addRepeatedNestedMessage(nestedMessage1); + assertEquals(0, mockParent.getInvalidationCount()); + + // Now tell it we want changes and make sure it's only fired once + // And do this for each flavor + + // primitive single + builder.buildPartial(); + builder.setOptionalInt32(2); + builder.setOptionalInt32(3); + assertEquals(1, mockParent.getInvalidationCount()); + + // enum single + builder.buildPartial(); + builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ); + builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR); + assertEquals(2, mockParent.getInvalidationCount()); + + // message single + builder.buildPartial(); + builder.setOptionalNestedMessage(nestedMessage2); + builder.setOptionalNestedMessage(nestedMessage1); + assertEquals(3, mockParent.getInvalidationCount()); + + // primitive repated + builder.buildPartial(); + builder.addRepeatedInt32(2); + builder.addRepeatedInt32(3); + assertEquals(4, mockParent.getInvalidationCount()); + + // enum repeated + builder.buildPartial(); + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); + assertEquals(5, mockParent.getInvalidationCount()); + + // message repeated + builder.buildPartial(); + builder.addRepeatedNestedMessage(nestedMessage2); + builder.addRepeatedNestedMessage(nestedMessage1); + assertEquals(6, mockParent.getInvalidationCount()); + + } + + public void testInvalidations_Extensions() throws Exception { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + + TestAllExtensions.Builder builder = (TestAllExtensions.Builder) + ((GeneratedMessage) TestAllExtensions.getDefaultInstance()). + newBuilderForType(mockParent); + + builder.addExtension(UnittestProto.repeatedInt32Extension, 1); + builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2); + builder.clearExtension(UnittestProto.repeatedInt32Extension); + assertEquals(0, mockParent.getInvalidationCount()); + + // Now tell it we want changes and make sure it's only fired once + builder.buildPartial(); + builder.addExtension(UnittestProto.repeatedInt32Extension, 2); + builder.addExtension(UnittestProto.repeatedInt32Extension, 3); + assertEquals(1, mockParent.getInvalidationCount()); + + builder.buildPartial(); + builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4); + builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5); + assertEquals(2, mockParent.getInvalidationCount()); + + builder.buildPartial(); + builder.clearExtension(UnittestProto.repeatedInt32Extension); + builder.clearExtension(UnittestProto.repeatedInt32Extension); + assertEquals(3, mockParent.getInvalidationCount()); + } + + public void testBaseMessageOrBuilder() { + // Mostly just makes sure the base interface exists and has some methods. + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TestAllTypes message = builder.buildPartial(); + TestAllTypesOrBuilder builderAsInterface = (TestAllTypesOrBuilder) builder; + TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message; + + assertEquals( + messageAsInterface.getDefaultBool(), + messageAsInterface.getDefaultBool()); + assertEquals( + messageAsInterface.getOptionalDouble(), + messageAsInterface.getOptionalDouble()); + } + + public void testMessageOrBuilderGetters() { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + + // single fields + assertSame(ForeignMessage.getDefaultInstance(), + builder.getOptionalForeignMessageOrBuilder()); + ForeignMessage.Builder subBuilder = + builder.getOptionalForeignMessageBuilder(); + assertSame(subBuilder, builder.getOptionalForeignMessageOrBuilder()); + + // repeated fields + ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial(); + ForeignMessage m1 = ForeignMessage.newBuilder().buildPartial(); + ForeignMessage m2 = ForeignMessage.newBuilder().buildPartial(); + builder.addRepeatedForeignMessage(m0); + builder.addRepeatedForeignMessage(m1); + builder.addRepeatedForeignMessage(m2); + assertSame(m0, builder.getRepeatedForeignMessageOrBuilder(0)); + assertSame(m1, builder.getRepeatedForeignMessageOrBuilder(1)); + assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2)); + ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0); + ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1); + assertSame(b0, builder.getRepeatedForeignMessageOrBuilder(0)); + assertSame(b1, builder.getRepeatedForeignMessageOrBuilder(1)); + assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2)); + + List<? extends ForeignMessageOrBuilder> messageOrBuilderList = + builder.getRepeatedForeignMessageOrBuilderList(); + assertSame(b0, messageOrBuilderList.get(0)); + assertSame(b1, messageOrBuilderList.get(1)); + assertSame(m2, messageOrBuilderList.get(2)); + } } diff --git a/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java new file mode 100644 index 00000000..4dcdc74d --- /dev/null +++ b/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java @@ -0,0 +1,118 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +/** + * Tests for {@link LazyStringArrayList}. + * + * @author jonp@google.com (Jon Perlow) + */ +public class LazyStringArrayListTest extends TestCase { + + private static String STRING_A = "A"; + private static String STRING_B = "B"; + private static String STRING_C = "C"; + + private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A"); + private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B"); + private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C"); + + public void testJustStrings() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + list.add(STRING_B); + list.add(STRING_C); + + assertEquals(3, list.size()); + assertSame(STRING_A, list.get(0)); + assertSame(STRING_B, list.get(1)); + assertSame(STRING_C, list.get(2)); + + list.set(1, STRING_C); + assertSame(STRING_C, list.get(1)); + + list.remove(1); + assertSame(STRING_A, list.get(0)); + assertSame(STRING_C, list.get(1)); + } + + public void testJustByteString() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(BYTE_STRING_A); + list.add(BYTE_STRING_B); + list.add(BYTE_STRING_C); + + assertEquals(3, list.size()); + assertSame(BYTE_STRING_A, list.getByteString(0)); + assertSame(BYTE_STRING_B, list.getByteString(1)); + assertSame(BYTE_STRING_C, list.getByteString(2)); + + list.remove(1); + assertSame(BYTE_STRING_A, list.getByteString(0)); + assertSame(BYTE_STRING_C, list.getByteString(1)); + } + + public void testConversionBackAndForth() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + list.add(BYTE_STRING_B); + list.add(BYTE_STRING_C); + + // String a should be the same because it was originally a string + assertSame(STRING_A, list.get(0)); + + // String b and c should be different because the string has to be computed + // from the ByteString + String bPrime = list.get(1); + assertNotSame(STRING_B, bPrime); + assertEquals(STRING_B, bPrime); + String cPrime = list.get(2); + assertNotSame(STRING_C, cPrime); + assertEquals(STRING_C, cPrime); + + // String c and c should stay the same once cached. + assertSame(bPrime, list.get(1)); + assertSame(cPrime, list.get(2)); + + // ByteString needs to be computed from string for both a and b + ByteString aPrimeByteString = list.getByteString(0); + assertEquals(BYTE_STRING_A, aPrimeByteString); + ByteString bPrimeByteString = list.getByteString(1); + assertNotSame(BYTE_STRING_B, bPrimeByteString); + assertEquals(BYTE_STRING_B, list.getByteString(1)); + + // Once cached, ByteString should stay cached. + assertSame(aPrimeByteString, list.getByteString(0)); + assertSame(bPrimeByteString, list.getByteString(1)); + } +} diff --git a/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java b/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java new file mode 100644 index 00000000..e6870b51 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java @@ -0,0 +1,115 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + + +import protobuf_unittest.UnittestProto; + +import junit.framework.TestCase; + +import java.io.IOException; + +/** + * Tests to make sure the lazy conversion of UTF8-encoded byte arrays to + * strings works correctly. + * + * @author jonp@google.com (Jon Perlow) + */ +public class LazyStringEndToEndTest extends TestCase { + + private static ByteString TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8 = + ByteString.copyFrom(new byte[] { + 114, 4, -1, 0, -1, 0, -30, 2, 4, -1, + 0, -1, 0, -30, 2, 4, -1, 0, -1, 0, }); + + /** + * Tests that an invalid UTF8 string will roundtrip through a parse + * and serialization. + */ + public void testParseAndSerialize() throws InvalidProtocolBufferException { + UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom( + TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); + ByteString bytes = tV2.toByteString(); + assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes); + + tV2.getOptionalString(); + bytes = tV2.toByteString(); + assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes); + } + + public void testParseAndWrite() throws IOException { + UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom( + TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); + byte[] sink = new byte[TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8.size()]; + CodedOutputStream outputStream = CodedOutputStream.newInstance(sink); + tV2.writeTo(outputStream); + outputStream.flush(); + assertEquals( + TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, + ByteString.copyFrom(sink)); + } + + public void testCaching() { + String a = "a"; + String b = "b"; + String c = "c"; + UnittestProto.TestAllTypes proto = UnittestProto.TestAllTypes.newBuilder() + .setOptionalString(a) + .addRepeatedString(b) + .addRepeatedString(c) + .build(); + + // String should be the one we passed it. + assertSame(a, proto.getOptionalString()); + assertSame(b, proto.getRepeatedString(0)); + assertSame(c, proto.getRepeatedString(1)); + + + // There's no way to directly observe that the ByteString is cached + // correctly on serialization, but we can observe that it had to recompute + // the string after serialization. + proto.toByteString(); + String aPrime = proto.getOptionalString(); + assertNotSame(a, aPrime); + assertEquals(a, aPrime); + String bPrime = proto.getRepeatedString(0); + assertNotSame(b, bPrime); + assertEquals(b, bPrime); + String cPrime = proto.getRepeatedString(1); + assertNotSame(c, cPrime); + assertEquals(c, cPrime); + + // And now the string should stay cached. + assertSame(aPrime, proto.getOptionalString()); + assertSame(bPrime, proto.getRepeatedString(0)); + assertSame(cPrime, proto.getRepeatedString(1)); + } +} diff --git a/java/src/test/java/com/google/protobuf/LiteTest.java b/java/src/test/java/com/google/protobuf/LiteTest.java index 728bad9d..4e1003d9 100644 --- a/java/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/src/test/java/com/google/protobuf/LiteTest.java @@ -37,6 +37,11 @@ import com.google.protobuf.UnittestLite.TestNestedExtensionLite; import junit.framework.TestCase; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + /** * Test lite runtime. * @@ -113,4 +118,28 @@ public class LiteTest extends TestCase { assertEquals(7, message2.getExtension( UnittestLite.optionalNestedMessageExtensionLite).getBb()); } + + public void testSerialize() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + TestAllTypesLite expected = + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .addRepeatedString("hello") + .setOptionalNestedMessage( + TestAllTypesLite.NestedMessage.newBuilder().setBb(7)) + .build(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(expected); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + TestAllTypesLite actual = (TestAllTypesLite) in.readObject(); + assertEquals(expected.getOptionalInt32(), actual.getOptionalInt32()); + assertEquals(expected.getRepeatedStringCount(), + actual.getRepeatedStringCount()); + assertEquals(expected.getRepeatedString(0), + actual.getRepeatedString(0)); + assertEquals(expected.getOptionalNestedMessage().getBb(), + actual.getOptionalNestedMessage().getBb()); + } } diff --git a/java/src/test/java/com/google/protobuf/NestedBuildersTest.java b/java/src/test/java/com/google/protobuf/NestedBuildersTest.java new file mode 100644 index 00000000..f5375801 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/NestedBuildersTest.java @@ -0,0 +1,185 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.Vehicle; +import protobuf_unittest.Wheel; + +import junit.framework.TestCase; + +import java.util.List; +import java.util.ArrayList; + +/** + * Test cases that exercise end-to-end use cases involving + * {@link SingleFieldBuilder} and {@link RepeatedFieldBuilder}. + * + * @author jonp@google.com (Jon Perlow) + */ +public class NestedBuildersTest extends TestCase { + + public void testMessagesAndBuilders() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.addWheelBuilder() + .setRadius(4) + .setWidth(1); + vehicleBuilder.addWheelBuilder() + .setRadius(4) + .setWidth(2); + vehicleBuilder.addWheelBuilder() + .setRadius(4) + .setWidth(3); + vehicleBuilder.addWheelBuilder() + .setRadius(4) + .setWidth(4); + vehicleBuilder.getEngineBuilder() + .setLiters(10); + + Vehicle vehicle = vehicleBuilder.build(); + assertEquals(4, vehicle.getWheelCount()); + for (int i = 0; i < 4; i++) { + Wheel wheel = vehicle.getWheel(i); + assertEquals(4, wheel.getRadius()); + assertEquals(i + 1, wheel.getWidth()); + } + assertEquals(10, vehicle.getEngine().getLiters()); + + for (int i = 0; i < 4; i++) { + vehicleBuilder.getWheelBuilder(i) + .setRadius(5) + .setWidth(i + 10); + } + vehicleBuilder.getEngineBuilder().setLiters(20); + + vehicle = vehicleBuilder.build(); + for (int i = 0; i < 4; i++) { + Wheel wheel = vehicle.getWheel(i); + assertEquals(5, wheel.getRadius()); + assertEquals(i + 10, wheel.getWidth()); + } + assertEquals(20, vehicle.getEngine().getLiters()); + assertTrue(vehicle.hasEngine()); + } + + public void testMessagesAreCached() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.addWheelBuilder() + .setRadius(1) + .setWidth(2); + vehicleBuilder.addWheelBuilder() + .setRadius(3) + .setWidth(4); + vehicleBuilder.addWheelBuilder() + .setRadius(5) + .setWidth(6); + vehicleBuilder.addWheelBuilder() + .setRadius(7) + .setWidth(8); + + // Make sure messages are cached. + List<Wheel> wheels = new ArrayList<Wheel>(vehicleBuilder.getWheelList()); + for (int i = 0; i < wheels.size(); i++) { + assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + } + + // Now get builders and check they didn't change. + for (int i = 0; i < wheels.size(); i++) { + vehicleBuilder.getWheel(i); + } + for (int i = 0; i < wheels.size(); i++) { + assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + } + + // Change just one + vehicleBuilder.getWheelBuilder(3) + .setRadius(20).setWidth(20); + + // Now get wheels and check that only that one changed + for (int i = 0; i < wheels.size(); i++) { + if (i < 3) { + assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + } else { + assertNotSame(wheels.get(i), vehicleBuilder.getWheel(i)); + } + } + } + + public void testRemove_WithNestedBuilders() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.addWheelBuilder() + .setRadius(1) + .setWidth(1); + vehicleBuilder.addWheelBuilder() + .setRadius(2) + .setWidth(2); + vehicleBuilder.removeWheel(0); + + assertEquals(1, vehicleBuilder.getWheelCount()); + assertEquals(2, vehicleBuilder.getWheel(0).getRadius()); + } + + public void testRemove_WithNestedMessages() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.addWheel(Wheel.newBuilder() + .setRadius(1) + .setWidth(1)); + vehicleBuilder.addWheel(Wheel.newBuilder() + .setRadius(2) + .setWidth(2)); + vehicleBuilder.removeWheel(0); + + assertEquals(1, vehicleBuilder.getWheelCount()); + assertEquals(2, vehicleBuilder.getWheel(0).getRadius()); + } + + public void testMerge() { + Vehicle vehicle1 = Vehicle.newBuilder() + .addWheel(Wheel.newBuilder().setRadius(1).build()) + .addWheel(Wheel.newBuilder().setRadius(2).build()) + .build(); + + Vehicle vehicle2 = Vehicle.newBuilder() + .mergeFrom(vehicle1) + .build(); + // List should be the same -- no allocation + assertSame(vehicle1.getWheelList(), vehicle2.getWheelList()); + + Vehicle vehicle3 = vehicle1.toBuilder().build(); + assertSame(vehicle1.getWheelList(), vehicle3.getWheelList()); + } + + public void testGettingBuilderMarksFieldAsHaving() { + Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); + vehicleBuilder.getEngineBuilder(); + Vehicle vehicle = vehicleBuilder.buildPartial(); + assertTrue(vehicle.hasEngine()); + } +} diff --git a/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java b/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java new file mode 100644 index 00000000..cdcdcb25 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java @@ -0,0 +1,190 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; + +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.List; + +/** + * Tests for {@link RepeatedFieldBuilder}. This tests basic functionality. + * More extensive testing is provided via other tests that exercise the + * builder. + * + * @author jonp@google.com (Jon Perlow) + */ +public class RepeatedFieldBuilderTest extends TestCase { + + public void testBasicUse() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + + List<TestAllTypes> list = builder.build(); + assertEquals(2, list.size()); + assertEquals(0, list.get(0).getOptionalInt32()); + assertEquals(1, list.get(1).getOptionalInt32()); + assertIsUnmodifiable(list); + + // Make sure it doesn't change. + List<TestAllTypes> list2 = builder.build(); + assertSame(list, list2); + assertEquals(0, mockParent.getInvalidationCount()); + } + + public void testGoingBackAndForth() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + + // Convert to list + List<TestAllTypes> list = builder.build(); + assertEquals(2, list.size()); + assertEquals(0, list.get(0).getOptionalInt32()); + assertEquals(1, list.get(1).getOptionalInt32()); + assertIsUnmodifiable(list); + + // Update 0th item + assertEquals(0, mockParent.getInvalidationCount()); + builder.getBuilder(0).setOptionalString("foo"); + assertEquals(1, mockParent.getInvalidationCount()); + list = builder.build(); + assertEquals(2, list.size()); + assertEquals(0, list.get(0).getOptionalInt32()); + assertEquals("foo", list.get(0).getOptionalString()); + assertEquals(1, list.get(1).getOptionalInt32()); + assertIsUnmodifiable(list); + assertEquals(1, mockParent.getInvalidationCount()); + } + + public void testVariousMethods() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(2).build()); + builder.addBuilder(0, TestAllTypes.getDefaultInstance()) + .setOptionalInt32(0); + builder.addBuilder(TestAllTypes.getDefaultInstance()).setOptionalInt32(3); + + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + assertEquals(2, builder.getMessage(2).getOptionalInt32()); + assertEquals(3, builder.getMessage(3).getOptionalInt32()); + + assertEquals(0, mockParent.getInvalidationCount()); + List<TestAllTypes> messages = builder.build(); + assertEquals(4, messages.size()); + assertSame(messages, builder.build()); // expect same list + + // Remove a message. + builder.remove(2); + assertEquals(1, mockParent.getInvalidationCount()); + assertEquals(3, builder.getCount()); + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + assertEquals(3, builder.getMessage(2).getOptionalInt32()); + + // Remove a builder. + builder.remove(0); + assertEquals(1, mockParent.getInvalidationCount()); + assertEquals(2, builder.getCount()); + assertEquals(1, builder.getMessage(0).getOptionalInt32()); + assertEquals(3, builder.getMessage(1).getOptionalInt32()); + + // Test clear. + builder.clear(); + assertEquals(1, mockParent.getInvalidationCount()); + assertEquals(0, builder.getCount()); + assertTrue(builder.isEmpty()); + } + + public void testLists() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent); + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); + builder.addMessage(0, + TestAllTypes.newBuilder().setOptionalInt32(0).build()); + assertEquals(0, builder.getMessage(0).getOptionalInt32()); + assertEquals(1, builder.getMessage(1).getOptionalInt32()); + + // Use list of builders. + List<TestAllTypes.Builder> builders = builder.getBuilderList(); + assertEquals(0, builders.get(0).getOptionalInt32()); + assertEquals(1, builders.get(1).getOptionalInt32()); + builders.get(0).setOptionalInt32(10); + builders.get(1).setOptionalInt32(11); + + // Use list of protos + List<TestAllTypes> protos = builder.getMessageList(); + assertEquals(10, protos.get(0).getOptionalInt32()); + assertEquals(11, protos.get(1).getOptionalInt32()); + + // Add an item to the builders and verify it's updated in both + builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(12).build()); + assertEquals(3, builders.size()); + assertEquals(3, protos.size()); + } + + private void assertIsUnmodifiable(List<?> list) { + if (list == Collections.emptyList()) { + // OKAY -- Need to check this b/c EmptyList allows you to call clear. + } else { + try { + list.clear(); + fail("List wasn't immutable"); + } catch (UnsupportedOperationException e) { + // good + } + } + } + + private RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> + newRepeatedFieldBuilder(GeneratedMessage.BuilderParent parent) { + return new RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder>(Collections.<TestAllTypes>emptyList(), false, + parent, false); + } +} diff --git a/java/src/test/java/com/google/protobuf/ServiceTest.java b/java/src/test/java/com/google/protobuf/ServiceTest.java index 802eb0e0..4be84f5b 100644 --- a/java/src/test/java/com/google/protobuf/ServiceTest.java +++ b/java/src/test/java/com/google/protobuf/ServiceTest.java @@ -244,6 +244,14 @@ public class ServiceTest extends TestCase { // make assumptions, so I'm just going to accept any character as the // separator. assertTrue(fullName.startsWith(outerName)); + + if (!Service.class.isAssignableFrom(innerClass) && + !Message.class.isAssignableFrom(innerClass) && + !ProtocolMessageEnum.class.isAssignableFrom(innerClass)) { + // Ignore any classes not generated by the base code generator. + continue; + } + innerClassNames.add(fullName.substring(outerName.length() + 1)); } diff --git a/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java b/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java new file mode 100644 index 00000000..5c2f7e75 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java @@ -0,0 +1,155 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; + +import junit.framework.TestCase; + +/** + * Tests for {@link SingleFieldBuilder}. This tests basic functionality. + * More extensive testing is provided via other tests that exercise the + * builder. + * + * @author jonp@google.com (Jon Perlow) + */ +public class SingleFieldBuilderTest extends TestCase { + + public void testBasicUseAndInvalidations() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> builder = + new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder>( + TestAllTypes.getDefaultInstance(), + mockParent, + false); + assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + assertEquals(TestAllTypes.getDefaultInstance(), + builder.getBuilder().buildPartial()); + assertEquals(0, mockParent.getInvalidationCount()); + + builder.getBuilder().setOptionalInt32(10); + assertEquals(0, mockParent.getInvalidationCount()); + TestAllTypes message = builder.build(); + assertEquals(10, message.getOptionalInt32()); + + // Test that we receive invalidations now that build has been called. + assertEquals(0, mockParent.getInvalidationCount()); + builder.getBuilder().setOptionalInt32(20); + assertEquals(1, mockParent.getInvalidationCount()); + + // Test that we don't keep getting invalidations on every change + builder.getBuilder().setOptionalInt32(30); + assertEquals(1, mockParent.getInvalidationCount()); + + } + + public void testSetMessage() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> builder = + new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder>( + TestAllTypes.getDefaultInstance(), + mockParent, + false); + builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); + assertEquals(0, builder.getMessage().getOptionalInt32()); + + // Update message using the builder + builder.getBuilder().setOptionalInt32(1); + assertEquals(0, mockParent.getInvalidationCount()); + assertEquals(1, builder.getBuilder().getOptionalInt32()); + assertEquals(1, builder.getMessage().getOptionalInt32()); + builder.build(); + builder.getBuilder().setOptionalInt32(2); + assertEquals(2, builder.getBuilder().getOptionalInt32()); + assertEquals(2, builder.getMessage().getOptionalInt32()); + + // Make sure message stays cached + assertSame(builder.getMessage(), builder.getMessage()); + } + + public void testClear() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> builder = + new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder>( + TestAllTypes.getDefaultInstance(), + mockParent, + false); + builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); + assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + builder.clear(); + assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + + builder.getBuilder().setOptionalInt32(1); + assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + builder.clear(); + assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + } + + public void testMerge() { + TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); + SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder> builder = + new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder, + TestAllTypesOrBuilder>( + TestAllTypes.getDefaultInstance(), + mockParent, + false); + + // Merge into default field. + builder.mergeFrom(TestAllTypes.getDefaultInstance()); + assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + + // Merge into non-default field on existing builder. + builder.getBuilder().setOptionalInt32(2); + builder.mergeFrom(TestAllTypes.newBuilder() + .setOptionalDouble(4.0) + .buildPartial()); + assertEquals(2, builder.getMessage().getOptionalInt32()); + assertEquals(4.0, builder.getMessage().getOptionalDouble()); + + // Merge into non-default field on existing message + builder.setMessage(TestAllTypes.newBuilder() + .setOptionalInt32(10) + .buildPartial()); + builder.mergeFrom(TestAllTypes.newBuilder() + .setOptionalDouble(5.0) + .buildPartial()); + assertEquals(10, builder.getMessage().getOptionalInt32()); + assertEquals(5.0, builder.getMessage().getOptionalDouble()); + } +} diff --git a/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java b/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java new file mode 100644 index 00000000..922115fc --- /dev/null +++ b/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java @@ -0,0 +1,378 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +import java.util.AbstractMap.SimpleEntry; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +/** + * @author darick@google.com Darick Tong + */ +public class SmallSortedMapTest extends TestCase { + + public void testPutAndGetArrayEntriesOnly() { + runPutAndGetTest(3); + } + + public void testPutAndGetOverflowEntries() { + runPutAndGetTest(6); + } + + private void runPutAndGetTest(int numElements) { + // Test with even and odd arraySize + SmallSortedMap<Integer, Integer> map1 = + SmallSortedMap.newInstanceForTest(3); + SmallSortedMap<Integer, Integer> map2 = + SmallSortedMap.newInstanceForTest(4); + SmallSortedMap<Integer, Integer> map3 = + SmallSortedMap.newInstanceForTest(3); + SmallSortedMap<Integer, Integer> map4 = + SmallSortedMap.newInstanceForTest(4); + + // Test with puts in ascending order. + for (int i = 0; i < numElements; i++) { + assertNull(map1.put(i, i + 1)); + assertNull(map2.put(i, i + 1)); + } + // Test with puts in descending order. + for (int i = numElements - 1; i >= 0; i--) { + assertNull(map3.put(i, i + 1)); + assertNull(map4.put(i, i + 1)); + } + + assertEquals(Math.min(3, numElements), map1.getNumArrayEntries()); + assertEquals(Math.min(4, numElements), map2.getNumArrayEntries()); + assertEquals(Math.min(3, numElements), map3.getNumArrayEntries()); + assertEquals(Math.min(4, numElements), map4.getNumArrayEntries()); + + List<SmallSortedMap<Integer, Integer>> allMaps = + new ArrayList<SmallSortedMap<Integer, Integer>>(); + allMaps.add(map1); + allMaps.add(map2); + allMaps.add(map3); + allMaps.add(map4); + + for (SmallSortedMap<Integer, Integer> map : allMaps) { + assertEquals(numElements, map.size()); + for (int i = 0; i < numElements; i++) { + assertEquals(new Integer(i + 1), map.get(i)); + } + } + + assertEquals(map1, map2); + assertEquals(map2, map3); + assertEquals(map3, map4); + } + + public void testReplacingPut() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + assertNull(map.remove(i + 1)); + } + for (int i = 0; i < 6; i++) { + assertEquals(new Integer(i + 1), map.put(i, i + 2)); + } + } + + public void testRemove() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + assertNull(map.remove(i + 1)); + } + + assertEquals(3, map.getNumArrayEntries()); + assertEquals(3, map.getNumOverflowEntries()); + assertEquals(6, map.size()); + assertEquals(makeSortedKeySet(0, 1, 2, 3, 4, 5), map.keySet()); + + assertEquals(new Integer(2), map.remove(1)); + assertEquals(3, map.getNumArrayEntries()); + assertEquals(2, map.getNumOverflowEntries()); + assertEquals(5, map.size()); + assertEquals(makeSortedKeySet(0, 2, 3, 4, 5), map.keySet()); + + assertEquals(new Integer(5), map.remove(4)); + assertEquals(3, map.getNumArrayEntries()); + assertEquals(1, map.getNumOverflowEntries()); + assertEquals(4, map.size()); + assertEquals(makeSortedKeySet(0, 2, 3, 5), map.keySet()); + + assertEquals(new Integer(4), map.remove(3)); + assertEquals(3, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(3, map.size()); + assertEquals(makeSortedKeySet(0, 2, 5), map.keySet()); + + assertNull(map.remove(3)); + assertEquals(3, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(3, map.size()); + + assertEquals(new Integer(1), map.remove(0)); + assertEquals(2, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(2, map.size()); + } + + public void testClear() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + map.clear(); + assertEquals(0, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(0, map.size()); + } + + public void testGetArrayEntryAndOverflowEntries() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + assertEquals(3, map.getNumArrayEntries()); + for (int i = 0; i < 3; i++) { + Map.Entry<Integer, Integer> entry = map.getArrayEntryAt(i); + assertEquals(new Integer(i), entry.getKey()); + assertEquals(new Integer(i + 1), entry.getValue()); + } + Iterator<Map.Entry<Integer, Integer>> it = + map.getOverflowEntries().iterator(); + for (int i = 3; i < 6; i++) { + assertTrue(it.hasNext()); + Map.Entry<Integer, Integer> entry = it.next(); + assertEquals(new Integer(i), entry.getKey()); + assertEquals(new Integer(i + 1), entry.getValue()); + } + assertFalse(it.hasNext()); + } + + public void testEntrySetContains() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet(); + for (int i = 0; i < 6; i++) { + assertTrue( + entrySet.contains(new SimpleEntry<Integer, Integer>(i, i + 1))); + assertFalse( + entrySet.contains(new SimpleEntry<Integer, Integer>(i, i))); + } + } + + public void testEntrySetAdd() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet(); + for (int i = 0; i < 6; i++) { + Map.Entry<Integer, Integer> entry = + new SimpleEntry<Integer, Integer>(i, i + 1); + assertTrue(entrySet.add(entry)); + assertFalse(entrySet.add(entry)); + } + for (int i = 0; i < 6; i++) { + assertEquals(new Integer(i + 1), map.get(i)); + } + assertEquals(3, map.getNumArrayEntries()); + assertEquals(3, map.getNumOverflowEntries()); + assertEquals(6, map.size()); + } + + public void testEntrySetRemove() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet(); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + for (int i = 0; i < 6; i++) { + Map.Entry<Integer, Integer> entry = + new SimpleEntry<Integer, Integer>(i, i + 1); + assertTrue(entrySet.remove(entry)); + assertFalse(entrySet.remove(entry)); + } + assertTrue(map.isEmpty()); + assertEquals(0, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(0, map.size()); + } + + public void testEntrySetClear() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + map.entrySet().clear(); + assertTrue(map.isEmpty()); + assertEquals(0, map.getNumArrayEntries()); + assertEquals(0, map.getNumOverflowEntries()); + assertEquals(0, map.size()); + } + + public void testEntrySetIteratorNext() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); + for (int i = 0; i < 6; i++) { + assertTrue(it.hasNext()); + Map.Entry<Integer, Integer> entry = it.next(); + assertEquals(new Integer(i), entry.getKey()); + assertEquals(new Integer(i + 1), entry.getValue()); + } + assertFalse(it.hasNext()); + } + + public void testEntrySetIteratorRemove() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); + for (int i = 0; i < 6; i++) { + assertTrue(map.containsKey(i)); + it.next(); + it.remove(); + assertFalse(map.containsKey(i)); + assertEquals(6 - i - 1, map.size()); + } + } + + public void testMapEntryModification() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); + for (int i = 0; i < 6; i++) { + Map.Entry<Integer, Integer> entry = it.next(); + entry.setValue(i + 23); + } + for (int i = 0; i < 6; i++) { + assertEquals(new Integer(i + 23), map.get(i)); + } + } + + public void testMakeImmutable() { + SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); + for (int i = 0; i < 6; i++) { + assertNull(map.put(i, i + 1)); + } + map.makeImmutable(); + assertEquals(new Integer(1), map.get(0)); + assertEquals(6, map.size()); + + try { + map.put(23, 23); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + Map<Integer, Integer> other = new HashMap<Integer, Integer>(); + other.put(23, 23); + try { + map.putAll(other); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + try { + map.remove(0); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + try { + map.clear(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet(); + try { + entrySet.clear(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + Iterator<Map.Entry<Integer, Integer>> it = entrySet.iterator(); + while (it.hasNext()) { + Map.Entry<Integer, Integer> entry = it.next(); + try { + entry.setValue(0); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + try { + it.remove(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + } + + Set<Integer> keySet = map.keySet(); + try { + keySet.clear(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + + Iterator<Integer> keys = keySet.iterator(); + while (keys.hasNext()) { + Integer key = keys.next(); + try { + keySet.remove(key); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + try { + keys.remove(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + } + } + } + + private Set<Integer> makeSortedKeySet(Integer... keys) { + return new TreeSet<Integer>(Arrays.<Integer>asList(keys)); + } +} diff --git a/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java b/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java new file mode 100644 index 00000000..6feec4e6 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java @@ -0,0 +1,49 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +/** + * Tests that proto2 api generation doesn't cause compile errors when + * compiling protocol buffers that have names that would otherwise conflict + * if not fully qualified (like @Deprecated and @Override). + * + * @author jonp@google.com (Jon Perlow) + */ +public class TestBadIdentifiers extends TestCase { + + public void testCompilation() { + // If this compiles, it means the generation was correct. + TestBadIdentifiersProto.Deprecated.newBuilder(); + TestBadIdentifiersProto.Override.newBuilder(); + } +} diff --git a/java/src/test/java/com/google/protobuf/TestUtil.java b/java/src/test/java/com/google/protobuf/TestUtil.java index 2b8b2af8..7c458d75 100644 --- a/java/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/src/test/java/com/google/protobuf/TestUtil.java @@ -214,7 +214,9 @@ import static com.google.protobuf.UnittestLite.packedBoolExtensionLite; import static com.google.protobuf.UnittestLite.packedEnumExtensionLite; import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder; import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; import protobuf_unittest.UnittestProto.TestPackedExtensions; import protobuf_unittest.UnittestProto.TestPackedTypes; import protobuf_unittest.UnittestProto.TestUnpackedTypes; @@ -225,6 +227,7 @@ import com.google.protobuf.test.UnittestImport.ImportEnum; import com.google.protobuf.UnittestLite.TestAllTypesLite; import com.google.protobuf.UnittestLite.TestAllExtensionsLite; +import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder; import com.google.protobuf.UnittestLite.TestPackedExtensionsLite; import com.google.protobuf.UnittestLite.ForeignMessageLite; import com.google.protobuf.UnittestLite.ForeignEnumLite; @@ -244,9 +247,12 @@ import java.io.RandomAccessFile; * set all fields of a message, serialize it, parse it, and check that all * fields are set. * + * <p>This code is not to be used outside of {@code com.google.protobuf} and + * subpackages. + * * @author kenton@google.com Kenton Varda */ -class TestUtil { +public final class TestUtil { private TestUtil() {} /** Helper to convert a String to ByteString. */ @@ -485,7 +491,7 @@ class TestUtil { * Assert (using {@code junit.framework.Assert}} that all fields of * {@code message} are set to the values assigned by {@code setAllFields}. */ - public static void assertAllFieldsSet(TestAllTypes message) { + public static void assertAllFieldsSet(TestAllTypesOrBuilder message) { Assert.assertTrue(message.hasOptionalInt32 ()); Assert.assertTrue(message.hasOptionalInt64 ()); Assert.assertTrue(message.hasOptionalUint32 ()); @@ -682,13 +688,12 @@ class TestUtil { } // ------------------------------------------------------------------- - /** * Assert (using {@code junit.framework.Assert}} that all fields of * {@code message} are cleared, and that getting the fields returns their * default values. */ - public static void assertClear(TestAllTypes message) { + public static void assertClear(TestAllTypesOrBuilder message) { // hasBlah() should initially be false for all optional fields. Assert.assertFalse(message.hasOptionalInt32 ()); Assert.assertFalse(message.hasOptionalInt64 ()); @@ -838,7 +843,8 @@ class TestUtil { * {@code message} are set to the values assigned by {@code setAllFields} * followed by {@code modifyRepeatedFields}. */ - public static void assertRepeatedFieldsModified(TestAllTypes message) { + public static void assertRepeatedFieldsModified( + TestAllTypesOrBuilder message) { // ModifyRepeatedFields only sets the second repeated element of each // field. In addition to verifying this, we also verify that the first // element and size were *not* modified. @@ -1352,7 +1358,8 @@ class TestUtil { * Assert (using {@code junit.framework.Assert}} that all extensions of * {@code message} are set to the values assigned by {@code setAllExtensions}. */ - public static void assertAllExtensionsSet(TestAllExtensions message) { + public static void assertAllExtensionsSet( + TestAllExtensionsOrBuilder message) { Assert.assertTrue(message.hasExtension(optionalInt32Extension )); Assert.assertTrue(message.hasExtension(optionalInt64Extension )); Assert.assertTrue(message.hasExtension(optionalUint32Extension )); @@ -1567,7 +1574,7 @@ class TestUtil { * {@code message} are cleared, and that getting the extensions returns their * default values. */ - public static void assertExtensionsClear(TestAllExtensions message) { + public static void assertExtensionsClear(TestAllExtensionsOrBuilder message) { // hasBlah() should initially be false for all optional fields. Assert.assertFalse(message.hasExtension(optionalInt32Extension )); Assert.assertFalse(message.hasExtension(optionalInt64Extension )); @@ -1752,7 +1759,7 @@ class TestUtil { * followed by {@code modifyRepeatedExtensions}. */ public static void assertRepeatedExtensionsModified( - TestAllExtensions message) { + TestAllExtensionsOrBuilder message) { // ModifyRepeatedFields only sets the second repeated element of each // field. In addition to verifying this, we also verify that the first // element and size were *not* modified. @@ -2106,7 +2113,8 @@ class TestUtil { * Assert (using {@code junit.framework.Assert}} that all extensions of * {@code message} are set to the values assigned by {@code setAllExtensions}. */ - public static void assertAllExtensionsSet(TestAllExtensionsLite message) { + public static void assertAllExtensionsSet( + TestAllExtensionsLiteOrBuilder message) { Assert.assertTrue(message.hasExtension(optionalInt32ExtensionLite )); Assert.assertTrue(message.hasExtension(optionalInt64ExtensionLite )); Assert.assertTrue(message.hasExtension(optionalUint32ExtensionLite )); @@ -2321,7 +2329,8 @@ class TestUtil { * {@code message} are cleared, and that getting the extensions returns their * default values. */ - public static void assertExtensionsClear(TestAllExtensionsLite message) { + public static void assertExtensionsClear( + TestAllExtensionsLiteOrBuilder message) { // hasBlah() should initially be false for all optional fields. Assert.assertFalse(message.hasExtension(optionalInt32ExtensionLite )); Assert.assertFalse(message.hasExtension(optionalInt64ExtensionLite )); @@ -2478,7 +2487,7 @@ class TestUtil { * followed by {@code modifyRepeatedExtensions}. */ public static void assertRepeatedExtensionsModified( - TestAllExtensionsLite message) { + TestAllExtensionsLiteOrBuilder message) { // ModifyRepeatedFields only sets the second repeated element of each // field. In addition to verifying this, we also verify that the first // element and size were *not* modified. @@ -3015,7 +3024,7 @@ class TestUtil { * {@code message} are set to the values assigned by {@code setAllFields}, * using the {@link Message} reflection interface. */ - public void assertAllFieldsSetViaReflection(Message message) { + public void assertAllFieldsSetViaReflection(MessageOrBuilder message) { Assert.assertTrue(message.hasField(f("optional_int32" ))); Assert.assertTrue(message.hasField(f("optional_int64" ))); Assert.assertTrue(message.hasField(f("optional_uint32" ))); @@ -3248,7 +3257,7 @@ class TestUtil { * {@code message} are cleared, and that getting the fields returns their * default values, using the {@link Message} reflection interface. */ - public void assertClearViaReflection(Message message) { + public void assertClearViaReflection(MessageOrBuilder message) { // has_blah() should initially be false for all optional fields. Assert.assertFalse(message.hasField(f("optional_int32" ))); Assert.assertFalse(message.hasField(f("optional_int64" ))); @@ -3405,9 +3414,11 @@ class TestUtil { Assert.assertEquals("123", message.getField(f("default_cord"))); } + // --------------------------------------------------------------- - public void assertRepeatedFieldsModifiedViaReflection(Message message) { + public void assertRepeatedFieldsModifiedViaReflection( + MessageOrBuilder message) { // ModifyRepeatedFields only sets the second repeated element of each // field. In addition to verifying this, we also verify that the first // element and size were *not* modified. @@ -3543,7 +3554,7 @@ class TestUtil { message.addRepeatedField(f("packed_enum" ), foreignBaz); } - public void assertPackedFieldsSetViaReflection(Message message) { + public void assertPackedFieldsSetViaReflection(MessageOrBuilder message) { Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int32" ))); Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int64" ))); Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint32" ))); @@ -3699,7 +3710,7 @@ class TestUtil { /** * @param filePath The path relative to - * {@link com.google.testing.util.TestUtil#getDefaultSrcDir}. + * {@link #getTestDataDir}. */ public static String readTextFromFile(String filePath) { return readBytesFromFile(filePath).toStringUtf8(); @@ -3728,8 +3739,8 @@ class TestUtil { } /** - * @param filePath The path relative to - * {@link com.google.testing.util.TestUtil#getDefaultSrcDir}. + * @param filename The path relative to + * {@link #getTestDataDir}. */ public static ByteString readBytesFromFile(String filename) { File fullPath = new File(getTestDataDir(), filename); @@ -3749,7 +3760,7 @@ class TestUtil { /** * Get the bytes of the "golden message". This is a serialized TestAllTypes * with all fields set as they would be by - * {@link setAllFields(TestAllTypes.Builder)}, but it is loaded from a file + * {@link #setAllFields(TestAllTypes.Builder)}, but it is loaded from a file * on disk rather than generated dynamically. The file is actually generated * by C++ code, so testing against it verifies compatibility with C++. */ @@ -3764,7 +3775,7 @@ class TestUtil { /** * Get the bytes of the "golden packed fields message". This is a serialized * TestPackedTypes with all fields set as they would be by - * {@link setPackedFields(TestPackedTypes.Builder)}, but it is loaded from a + * {@link #setPackedFields(TestPackedTypes.Builder)}, but it is loaded from a * file on disk rather than generated dynamically. The file is actually * generated by C++ code, so testing against it verifies compatibility with * C++. @@ -3777,4 +3788,24 @@ class TestUtil { return goldenPackedFieldsMessage; } private static ByteString goldenPackedFieldsMessage = null; + + /** + * Mock implementation of {@link GeneratedMessage.BuilderParent} for testing. + * + * @author jonp@google.com (Jon Perlow) + */ + public static class MockBuilderParent + implements GeneratedMessage.BuilderParent { + + private int invalidations; + + @Override + public void markDirty() { + invalidations++; + } + + public int getInvalidationCount() { + return invalidations; + } + } } diff --git a/java/src/test/java/com/google/protobuf/TextFormatTest.java b/java/src/test/java/com/google/protobuf/TextFormatTest.java index ad48157a..47690d1f 100644 --- a/java/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/src/test/java/com/google/protobuf/TextFormatTest.java @@ -31,14 +31,14 @@ package com.google.protobuf; import com.google.protobuf.Descriptors.FieldDescriptor; -import protobuf_unittest.UnittestProto.OneString; -import protobuf_unittest.UnittestProto.TestAllTypes; -import protobuf_unittest.UnittestProto.TestAllExtensions; -import protobuf_unittest.UnittestProto.TestEmptyMessage; -import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; import protobuf_unittest.UnittestMset.TestMessageSet; import protobuf_unittest.UnittestMset.TestMessageSetExtension1; import protobuf_unittest.UnittestMset.TestMessageSetExtension2; +import protobuf_unittest.UnittestProto.OneString; +import protobuf_unittest.UnittestProto.TestAllExtensions; +import protobuf_unittest.UnittestProto.TestAllTypes; +import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; +import protobuf_unittest.UnittestProto.TestEmptyMessage; import junit.framework.TestCase; @@ -133,40 +133,44 @@ public class TextFormatTest extends TestCase { assertEquals(allExtensionsSetText, javaText); } + // Creates an example unknown field set. + private UnknownFieldSet makeUnknownFieldSet() { + return UnknownFieldSet.newBuilder() + .addField(5, + UnknownFieldSet.Field.newBuilder() + .addVarint(1) + .addFixed32(2) + .addFixed64(3) + .addLengthDelimited(ByteString.copyFromUtf8("4")) + .addGroup( + UnknownFieldSet.newBuilder() + .addField(10, + UnknownFieldSet.Field.newBuilder() + .addVarint(5) + .build()) + .build()) + .build()) + .addField(8, + UnknownFieldSet.Field.newBuilder() + .addVarint(1) + .addVarint(2) + .addVarint(3) + .build()) + .addField(15, + UnknownFieldSet.Field.newBuilder() + .addVarint(0xABCDEF1234567890L) + .addFixed32(0xABCD1234) + .addFixed64(0xABCDEF1234567890L) + .build()) + .build(); + } + public void testPrintUnknownFields() throws Exception { // Test printing of unknown fields in a message. TestEmptyMessage message = TestEmptyMessage.newBuilder() - .setUnknownFields( - UnknownFieldSet.newBuilder() - .addField(5, - UnknownFieldSet.Field.newBuilder() - .addVarint(1) - .addFixed32(2) - .addFixed64(3) - .addLengthDelimited(ByteString.copyFromUtf8("4")) - .addGroup( - UnknownFieldSet.newBuilder() - .addField(10, - UnknownFieldSet.Field.newBuilder() - .addVarint(5) - .build()) - .build()) - .build()) - .addField(8, - UnknownFieldSet.Field.newBuilder() - .addVarint(1) - .addVarint(2) - .addVarint(3) - .build()) - .addField(15, - UnknownFieldSet.Field.newBuilder() - .addVarint(0xABCDEF1234567890L) - .addFixed32(0xABCD1234) - .addFixed64(0xABCDEF1234567890L) - .build()) - .build()) + .setUnknownFields(makeUnknownFieldSet()) .build(); assertEquals( @@ -409,6 +413,9 @@ public class TextFormatTest extends TestCase { "1:16: Expected \"true\" or \"false\".", "optional_bool: maybe"); assertParseError( + "1:16: Expected \"true\" or \"false\".", + "optional_bool: 2"); + assertParseError( "1:18: Expected string.", "optional_string: 123"); assertParseError( @@ -485,6 +492,11 @@ public class TextFormatTest extends TestCase { assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\xe1\\x88\\xb4")); + // Handling of strings with unescaped Unicode characters > 255. + final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; + ByteString zhByteString = ByteString.copyFromUtf8(zh); + assertEquals(zhByteString, TextFormat.unescapeBytes(zh)); + // Errors. try { TextFormat.unescapeText("\\x"); @@ -626,6 +638,13 @@ public class TextFormatTest extends TestCase { } } + public void testParseString() throws Exception { + final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_string: \"" + zh + "\"", builder); + assertEquals(zh, builder.getOptionalString()); + } + public void testParseLongString() throws Exception { String longText = "123456789012345678901234567890123456789012345678901234567890" + @@ -654,9 +673,80 @@ public class TextFormatTest extends TestCase { assertEquals(longText, builder.getOptionalString()); } + public void testParseBoolean() throws Exception { + String goodText = + "repeated_bool: t repeated_bool : 0\n" + + "repeated_bool :f repeated_bool:1"; + String goodTextCanonical = + "repeated_bool: true\n" + + "repeated_bool: false\n" + + "repeated_bool: false\n" + + "repeated_bool: true\n"; + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge(goodText, builder); + assertEquals(goodTextCanonical, builder.build().toString()); + + try { + TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_bool:2", badBuilder); + fail("Should have thrown an exception."); + } catch (TextFormat.ParseException e) { + // success + } + try { + TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_bool: foo", badBuilder); + fail("Should have thrown an exception."); + } catch (TextFormat.ParseException e) { + // success + } + } + public void testParseAdjacentStringLiterals() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder); assertEquals("foocorgegrault", builder.getOptionalString()); } + + public void testPrintFieldValue() throws Exception { + assertPrintFieldValue("\"Hello\"", "Hello", "repeated_string"); + assertPrintFieldValue("123.0", 123f, "repeated_float"); + assertPrintFieldValue("123.0", 123d, "repeated_double"); + assertPrintFieldValue("123", 123, "repeated_int32"); + assertPrintFieldValue("123", 123L, "repeated_int64"); + assertPrintFieldValue("true", true, "repeated_bool"); + assertPrintFieldValue("4294967295", 0xFFFFFFFF, "repeated_uint32"); + assertPrintFieldValue("18446744073709551615", 0xFFFFFFFFFFFFFFFFL, + "repeated_uint64"); + assertPrintFieldValue("\"\\001\\002\\003\"", + ByteString.copyFrom(new byte[] {1, 2, 3}), "repeated_bytes"); + } + + private void assertPrintFieldValue(String expect, Object value, + String fieldName) throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + StringBuilder sb = new StringBuilder(); + TextFormat.printFieldValue( + TestAllTypes.getDescriptor().findFieldByName(fieldName), + value, sb); + assertEquals(expect, sb.toString()); + } + + public void testShortDebugString() { + assertEquals("optional_nested_message { bb: 42 } repeated_int32: 1" + + " repeated_uint32: 2", + TextFormat.shortDebugString(TestAllTypes.newBuilder() + .addRepeatedInt32(1) + .addRepeatedUint32(2) + .setOptionalNestedMessage( + NestedMessage.newBuilder().setBb(42).build()) + .build())); + } + + public void testShortDebugString_unknown() { + assertEquals("5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5 { 10: 5 }" + + " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:" + + " 0xabcdef1234567890", + TextFormat.shortDebugString(makeUnknownFieldSet())); + } } diff --git a/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java b/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java new file mode 100644 index 00000000..ed5d069e --- /dev/null +++ b/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java @@ -0,0 +1,152 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +import java.util.Iterator; +import java.util.ListIterator; + +/** + * Tests for {@link UnmodifiableLazyStringList}. + * + * @author jonp@google.com (Jon Perlow) + */ +public class UnmodifiableLazyStringListTest extends TestCase { + + private static String STRING_A = "A"; + private static String STRING_B = "B"; + private static String STRING_C = "C"; + + private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A"); + private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B"); + private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C"); + + public void testReadOnlyMethods() { + LazyStringArrayList rawList = createSampleList(); + UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); + assertEquals(3, list.size()); + assertSame(STRING_A, list.get(0)); + assertSame(STRING_B, list.get(1)); + assertSame(STRING_C, list.get(2)); + assertEquals(BYTE_STRING_A, list.getByteString(0)); + assertEquals(BYTE_STRING_B, list.getByteString(1)); + assertEquals(BYTE_STRING_C, list.getByteString(2)); + } + + public void testModifyMethods() { + LazyStringArrayList rawList = createSampleList(); + UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); + + try { + list.remove(0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(3, list.size()); + + try { + list.add(STRING_B); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(3, list.size()); + + try { + list.set(1, STRING_B); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + public void testIterator() { + LazyStringArrayList rawList = createSampleList(); + UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); + + Iterator<String> iter = list.iterator(); + int count = 0; + while (iter.hasNext()) { + iter.next(); + count++; + try { + iter.remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + assertEquals(3, count); + + } + + public void testListIterator() { + LazyStringArrayList rawList = createSampleList(); + UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); + + ListIterator<String> iter = list.listIterator(); + int count = 0; + while (iter.hasNext()) { + iter.next(); + count++; + try { + iter.remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + iter.set("bar"); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + iter.add("bar"); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + assertEquals(3, count); + + } + + private LazyStringArrayList createSampleList() { + LazyStringArrayList rawList = new LazyStringArrayList(); + rawList.add(STRING_A); + rawList.add(STRING_B); + rawList.add(STRING_C); + return rawList; + } +} diff --git a/java/src/test/java/com/google/protobuf/multiple_files_test.proto b/java/src/test/java/com/google/protobuf/multiple_files_test.proto index 060f159a..9a040145 100644 --- a/java/src/test/java/com/google/protobuf/multiple_files_test.proto +++ b/java/src/test/java/com/google/protobuf/multiple_files_test.proto @@ -33,6 +33,10 @@ // A proto file which tests the java_multiple_files option. +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option java_generic_services = true; // auto-added + import "google/protobuf/unittest.proto"; package protobuf_unittest; diff --git a/java/src/test/java/com/google/protobuf/nested_builders_test.proto b/java/src/test/java/com/google/protobuf/nested_builders_test.proto new file mode 100644 index 00000000..abffb9d2 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/nested_builders_test.proto @@ -0,0 +1,53 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jonp@google.com (Jon Perlow) +// + +package protobuf_unittest; + +option java_multiple_files = true; +option java_outer_classname = "NestedBuilders"; + + +message Vehicle { + optional Engine engine = 1; + repeated Wheel wheel = 2; +} + +message Engine { + optional int32 cylinder = 1; + optional int32 liters = 2; +} + +message Wheel { + optional int32 radius = 1; + optional int32 width = 2; +} diff --git a/java/src/test/java/com/google/protobuf/nested_extension.proto b/java/src/test/java/com/google/protobuf/nested_extension.proto new file mode 100644 index 00000000..9fe5d560 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/nested_extension.proto @@ -0,0 +1,45 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Darick Tong (darick@google.com) +// +// A proto file with nested extensions. Note that this must be defined in +// a separate file to properly test the initialization of the outer class. + + +import "com/google/protobuf/non_nested_extension.proto"; + +package protobuf_unittest; + +message MyNestedExtension { + extend MessageToBeExtended { + optional MessageToBeExtended recursiveExtension = 2; + } +} diff --git a/java/src/test/java/com/google/protobuf/nested_extension_lite.proto b/java/src/test/java/com/google/protobuf/nested_extension_lite.proto new file mode 100644 index 00000000..16ee46e5 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/nested_extension_lite.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Darick Tong (darick@google.com) +// +// A proto file with nested extensions for a MessageLite messages. Note that +// this must be defined in a separate file to properly test the initialization +// of the outer class. + + +package protobuf_unittest; + +option optimize_for = LITE_RUNTIME; + +import "com/google/protobuf/non_nested_extension_lite.proto"; + +message MyNestedExtensionLite { + extend MessageLiteToBeExtended { + optional MessageLiteToBeExtended recursiveExtensionLite = 3; + } +} diff --git a/java/src/test/java/com/google/protobuf/non_nested_extension.proto b/java/src/test/java/com/google/protobuf/non_nested_extension.proto new file mode 100644 index 00000000..f61b419b --- /dev/null +++ b/java/src/test/java/com/google/protobuf/non_nested_extension.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Darick Tong (darick@google.com) +// +// A proto file with extensions. + + +package protobuf_unittest; + +message MessageToBeExtended { + extensions 1 to max; +} + +message MyNonNestedExtension { +} + +extend MessageToBeExtended { + optional MyNonNestedExtension nonNestedExtension = 1; +} + diff --git a/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto b/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto new file mode 100644 index 00000000..3c82659b --- /dev/null +++ b/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto @@ -0,0 +1,50 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Darick Tong (darick@google.com) +// +// A proto file with extensions for a MessageLite messages. + + +package protobuf_unittest; + +option optimize_for = LITE_RUNTIME; + +message MessageLiteToBeExtended { + extensions 1 to max; +} + +message MyNonNestedExtensionLite { +} + +extend MessageLiteToBeExtended { + optional MyNonNestedExtensionLite nonNestedExtensionLite = 1; +} + diff --git a/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto b/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto new file mode 100644 index 00000000..5cc42af8 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto @@ -0,0 +1,66 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jonp@google.com (Jon Perlow) + +// This file tests that various identifiers work as field and type names even +// though the same identifiers are used internally by the java code generator. + + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option java_generic_services = true; // auto-added + +package io_protocol_tests; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "TestBadIdentifiersProto"; + +message TestMessage { +} + +message Deprecated { + enum TestEnum { + FOO = 1; + } + + optional int32 field1 = 1 [deprecated=true]; + optional TestEnum field2 = 2 [deprecated=true]; + optional TestMessage field3 = 3 [deprecated=true]; +} + +message Override { + optional int32 override = 1; +} + +service TestConflictingMethodNames { + rpc Override(TestMessage) returns (TestMessage); +} + |