diff options
author | Bo Yang <teboring@google.com> | 2015-05-21 14:28:59 -0700 |
---|---|---|
committer | Bo Yang <teboring@google.com> | 2015-05-21 19:32:02 -0700 |
commit | 5db217305f37a79eeccd70f000088a06ec82fcec (patch) | |
tree | be53dcf0c0b47ef9178ab8a6fa5c1946ee84a28f /java/src/test | |
parent | 56095026ccc2f755a6fdb296e30c3ddec8f556a2 (diff) | |
download | protobuf-5db217305f37a79eeccd70f000088a06ec82fcec.tar.gz protobuf-5db217305f37a79eeccd70f000088a06ec82fcec.tar.bz2 protobuf-5db217305f37a79eeccd70f000088a06ec82fcec.zip |
down-integrate internal changes
Diffstat (limited to 'java/src/test')
16 files changed, 4699 insertions, 24 deletions
diff --git a/java/src/test/java/com/google/protobuf/BooleanArrayListTest.java b/java/src/test/java/com/google/protobuf/BooleanArrayListTest.java new file mode 100644 index 00000000..df89c263 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/BooleanArrayListTest.java @@ -0,0 +1,473 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 static java.util.Arrays.asList; + +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; + +/** + * Tests for {@link BooleanArrayList}. + * + * @author dweis@google.com (Daniel Weis) + */ +public class BooleanArrayListTest extends TestCase { + + private static final BooleanArrayList UNARY_LIST = newImmutableBooleanArrayList(true); + private static final BooleanArrayList TERTIARY_LIST = + newImmutableBooleanArrayList(true, true, false); + + private BooleanArrayList list; + + @Override + protected void setUp() throws Exception { + list = new BooleanArrayList(); + } + + public void testEmptyListReturnsSameInstance() { + assertSame(BooleanArrayList.emptyList(), BooleanArrayList.emptyList()); + } + + public void testEmptyListIsImmutable() { + assertImmutable(BooleanArrayList.emptyList()); + } + + public void testMakeImmutable() { + list.addBoolean(true); + list.addBoolean(false); + list.addBoolean(true); + list.addBoolean(true); + list.makeImmutable(); + assertImmutable(list); + } + + public void testCopyConstructor() { + BooleanArrayList copy = new BooleanArrayList(TERTIARY_LIST); + assertEquals(TERTIARY_LIST, copy); + + copy = new BooleanArrayList(BooleanArrayList.emptyList()); + assertEquals(BooleanArrayList.emptyList(), copy); + + copy = new BooleanArrayList(asList(false, false, true)); + assertEquals(asList(false, false, true), copy); + + copy = new BooleanArrayList(Collections.<Boolean>emptyList()); + assertEquals(BooleanArrayList.emptyList(), copy); + } + + public void testModificationWithIteration() { + list.addAll(asList(true, false, false, true)); + Iterator<Boolean> iterator = list.iterator(); + assertEquals(4, list.size()); + assertEquals(true, (boolean) list.get(0)); + assertEquals(true, (boolean) iterator.next()); + list.set(0, true); + assertEquals(false, (boolean) iterator.next()); + + list.remove(0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + + iterator = list.iterator(); + list.add(0, false); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + } + + public void testGet() { + assertEquals(true, (boolean) TERTIARY_LIST.get(0)); + assertEquals(true, (boolean) TERTIARY_LIST.get(1)); + assertEquals(false, (boolean) TERTIARY_LIST.get(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testGetInt() { + assertEquals(true, TERTIARY_LIST.getBoolean(0)); + assertEquals(true, TERTIARY_LIST.getBoolean(1)); + assertEquals(false, TERTIARY_LIST.getBoolean(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSize() { + assertEquals(0, BooleanArrayList.emptyList().size()); + assertEquals(1, UNARY_LIST.size()); + assertEquals(3, TERTIARY_LIST.size()); + + list.addBoolean(true); + list.addBoolean(false); + list.addBoolean(false); + list.addBoolean(false); + assertEquals(4, list.size()); + + list.remove(0); + assertEquals(3, list.size()); + + list.add(true); + assertEquals(4, list.size()); + } + + public void testSet() { + list.addBoolean(false); + list.addBoolean(false); + + assertEquals(false, (boolean) list.set(0, true)); + assertEquals(true, list.getBoolean(0)); + + assertEquals(false, (boolean) list.set(1, false)); + assertEquals(false, list.getBoolean(1)); + + try { + list.set(-1, true); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.set(2, false); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSetInt() { + list.addBoolean(true); + list.addBoolean(true); + + assertEquals(true, list.setBoolean(0, false)); + assertEquals(false, list.getBoolean(0)); + + assertEquals(true, list.setBoolean(1, false)); + assertEquals(false, list.getBoolean(1)); + + try { + list.setBoolean(-1, false); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.setBoolean(2, true); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAdd() { + assertEquals(0, list.size()); + + assertTrue(list.add(true)); + assertEquals(asList(true), list); + + assertTrue(list.add(false)); + list.add(0, false); + assertEquals(asList(false, true, false), list); + + list.add(0, false); + list.add(0, true); + // Force a resize by getting up to 11 elements. + for (int i = 0; i < 6; i++) { + list.add(true); + } + assertEquals(asList(true, false, false, true, false, true, true, true, true, true, true), list); + + try { + list.add(-1, false); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.add(4, true); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAddInt() { + assertEquals(0, list.size()); + + list.addBoolean(true); + assertEquals(asList(true), list); + + list.addBoolean(false); + assertEquals(asList(true, false), list); + } + + public void testAddAll() { + assertEquals(0, list.size()); + + assertTrue(list.addAll(Collections.singleton(false))); + assertEquals(1, list.size()); + assertEquals(false, (boolean) list.get(0)); + assertEquals(false, list.getBoolean(0)); + + assertTrue(list.addAll(asList(true, false, false, false, true))); + assertEquals(asList(false, true, false, false, false, true), list); + + assertTrue(list.addAll(TERTIARY_LIST)); + assertEquals(asList(false, true, false, false, false, true, true, true, false), list); + + assertFalse(list.addAll(Collections.<Boolean>emptyList())); + assertFalse(list.addAll(BooleanArrayList.emptyList())); + } + + public void testRemove() { + list.addAll(TERTIARY_LIST); + assertEquals(true, (boolean) list.remove(0)); + assertEquals(asList(true, false), list); + + assertTrue(list.remove(Boolean.TRUE)); + assertEquals(asList(false), list); + + assertFalse(list.remove(Boolean.TRUE)); + assertEquals(asList(false), list); + + assertEquals(false, (boolean) list.remove(0)); + assertEquals(asList(), list); + + try { + list.remove(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.remove(0); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + private void assertImmutable(BooleanArrayList list) { + if (list.contains(1)) { + throw new RuntimeException("Cannot test the immutability of lists that contain 1."); + } + + try { + list.add(false); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.add(0, true); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.<Boolean>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.singletonList(false)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(new BooleanArrayList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.singleton(true)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.<Boolean>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addBoolean(true); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.clear(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.<Boolean>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.<Boolean>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, true); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.setBoolean(0, false); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + private static BooleanArrayList newImmutableBooleanArrayList(boolean... elements) { + BooleanArrayList list = new BooleanArrayList(); + for (boolean element : elements) { + list.addBoolean(element); + } + list.makeImmutable(); + return list; + } +} diff --git a/java/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/src/test/java/com/google/protobuf/DescriptorsTest.java index 6cfa18d5..edd7fc46 100644 --- a/java/src/test/java/com/google/protobuf/DescriptorsTest.java +++ b/java/src/test/java/com/google/protobuf/DescriptorsTest.java @@ -56,6 +56,7 @@ import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestExtremeDefaultValues; import protobuf_unittest.UnittestProto.TestMultipleExtensionRanges; import protobuf_unittest.UnittestProto.TestRequired; +import protobuf_unittest.UnittestProto.TestReservedFields; import protobuf_unittest.UnittestProto.TestService; import junit.framework.TestCase; @@ -687,6 +688,9 @@ public class DescriptorsTest extends TestCase { assertEquals(4, oneofDescriptor.getFieldCount()); assertSame(oneofDescriptor.getField(1), field); + + assertEquals(4, oneofDescriptor.getFields().size()); + assertEquals(oneofDescriptor.getFields().get(1), field); } public void testMessageDescriptorExtensions() throws Exception { @@ -702,6 +706,19 @@ public class DescriptorsTest extends TestCase { assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4143)); } + public void testReservedFields() { + Descriptor d = TestReservedFields.getDescriptor(); + assertTrue(d.isReservedNumber(2)); + assertFalse(d.isReservedNumber(8)); + assertTrue(d.isReservedNumber(9)); + assertTrue(d.isReservedNumber(10)); + assertTrue(d.isReservedNumber(11)); + assertFalse(d.isReservedNumber(12)); + assertFalse(d.isReservedName("foo")); + assertTrue(d.isReservedName("bar")); + assertTrue(d.isReservedName("baz")); + } + public void testToString() { assertEquals("protobuf_unittest.TestAllTypes.optional_uint64", UnittestProto.TestAllTypes.getDescriptor().findFieldByNumber( diff --git a/java/src/test/java/com/google/protobuf/DoubleArrayListTest.java b/java/src/test/java/com/google/protobuf/DoubleArrayListTest.java new file mode 100644 index 00000000..e7a73d70 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/DoubleArrayListTest.java @@ -0,0 +1,473 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 static java.util.Arrays.asList; + +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; + +/** + * Tests for {@link DoubleArrayList}. + * + * @author dweis@google.com (Daniel Weis) + */ +public class DoubleArrayListTest extends TestCase { + + private static final DoubleArrayList UNARY_LIST = newImmutableDoubleArrayList(1); + private static final DoubleArrayList TERTIARY_LIST = + newImmutableDoubleArrayList(1, 2, 3); + + private DoubleArrayList list; + + @Override + protected void setUp() throws Exception { + list = new DoubleArrayList(); + } + + public void testEmptyListReturnsSameInstance() { + assertSame(DoubleArrayList.emptyList(), DoubleArrayList.emptyList()); + } + + public void testEmptyListIsImmutable() { + assertImmutable(DoubleArrayList.emptyList()); + } + + public void testMakeImmutable() { + list.addDouble(2); + list.addDouble(4); + list.addDouble(6); + list.addDouble(8); + list.makeImmutable(); + assertImmutable(list); + } + + public void testCopyConstructor() { + DoubleArrayList copy = new DoubleArrayList(TERTIARY_LIST); + assertEquals(TERTIARY_LIST, copy); + + copy = new DoubleArrayList(DoubleArrayList.emptyList()); + assertEquals(DoubleArrayList.emptyList(), copy); + + copy = new DoubleArrayList(asList(1D, 2D, 3D)); + assertEquals(asList(1D, 2D, 3D), copy); + + copy = new DoubleArrayList(Collections.<Double>emptyList()); + assertEquals(DoubleArrayList.emptyList(), copy); + } + + public void testModificationWithIteration() { + list.addAll(asList(1D, 2D, 3D, 4D)); + Iterator<Double> iterator = list.iterator(); + assertEquals(4, list.size()); + assertEquals(1D, (double) list.get(0)); + assertEquals(1D, (double) iterator.next()); + list.set(0, 1D); + assertEquals(2D, (double) iterator.next()); + + list.remove(0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + + iterator = list.iterator(); + list.add(0, 0D); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + } + + public void testGet() { + assertEquals(1D, (double) TERTIARY_LIST.get(0)); + assertEquals(2D, (double) TERTIARY_LIST.get(1)); + assertEquals(3D, (double) TERTIARY_LIST.get(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testGetInt() { + assertEquals(1D, TERTIARY_LIST.getDouble(0)); + assertEquals(2D, TERTIARY_LIST.getDouble(1)); + assertEquals(3D, TERTIARY_LIST.getDouble(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSize() { + assertEquals(0, DoubleArrayList.emptyList().size()); + assertEquals(1, UNARY_LIST.size()); + assertEquals(3, TERTIARY_LIST.size()); + + list.addDouble(2); + list.addDouble(4); + list.addDouble(6); + list.addDouble(8); + assertEquals(4, list.size()); + + list.remove(0); + assertEquals(3, list.size()); + + list.add(16D); + assertEquals(4, list.size()); + } + + public void testSet() { + list.addDouble(2); + list.addDouble(4); + + assertEquals(2D, (double) list.set(0, 0D)); + assertEquals(0D, list.getDouble(0)); + + assertEquals(4D, (double) list.set(1, 0D)); + assertEquals(0D, list.getDouble(1)); + + try { + list.set(-1, 0D); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.set(2, 0D); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSetInt() { + list.addDouble(2); + list.addDouble(4); + + assertEquals(2D, list.setDouble(0, 0)); + assertEquals(0D, list.getDouble(0)); + + assertEquals(4D, list.setDouble(1, 0)); + assertEquals(0D, list.getDouble(1)); + + try { + list.setDouble(-1, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.setDouble(2, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAdd() { + assertEquals(0, list.size()); + + assertTrue(list.add(2D)); + assertEquals(asList(2D), list); + + assertTrue(list.add(3D)); + list.add(0, 4D); + assertEquals(asList(4D, 2D, 3D), list); + + list.add(0, 1D); + list.add(0, 0D); + // Force a resize by getting up to 11 elements. + for (int i = 0; i < 6; i++) { + list.add(Double.valueOf(5 + i)); + } + assertEquals(asList(0D, 1D, 4D, 2D, 3D, 5D, 6D, 7D, 8D, 9D, 10D), list); + + try { + list.add(-1, 5D); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.add(4, 5D); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAddInt() { + assertEquals(0, list.size()); + + list.addDouble(2); + assertEquals(asList(2D), list); + + list.addDouble(3); + assertEquals(asList(2D, 3D), list); + } + + public void testAddAll() { + assertEquals(0, list.size()); + + assertTrue(list.addAll(Collections.singleton(1D))); + assertEquals(1, list.size()); + assertEquals(1D, (double) list.get(0)); + assertEquals(1D, list.getDouble(0)); + + assertTrue(list.addAll(asList(2D, 3D, 4D, 5D, 6D))); + assertEquals(asList(1D, 2D, 3D, 4D, 5D, 6D), list); + + assertTrue(list.addAll(TERTIARY_LIST)); + assertEquals(asList(1D, 2D, 3D, 4D, 5D, 6D, 1D, 2D, 3D), list); + + assertFalse(list.addAll(Collections.<Double>emptyList())); + assertFalse(list.addAll(DoubleArrayList.emptyList())); + } + + public void testRemove() { + list.addAll(TERTIARY_LIST); + assertEquals(1D, (double) list.remove(0)); + assertEquals(asList(2D, 3D), list); + + assertTrue(list.remove(Double.valueOf(3))); + assertEquals(asList(2D), list); + + assertFalse(list.remove(Double.valueOf(3))); + assertEquals(asList(2D), list); + + assertEquals(2D, (double) list.remove(0)); + assertEquals(asList(), list); + + try { + list.remove(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.remove(0); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + private void assertImmutable(DoubleArrayList list) { + if (list.contains(1)) { + throw new RuntimeException("Cannot test the immutability of lists that contain 1."); + } + + try { + list.add(1D); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.add(0, 1D); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.<Double>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.singletonList(1D)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(new DoubleArrayList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.singleton(1D)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.<Double>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addDouble(0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.clear(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.<Double>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.<Double>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, 0D); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.setDouble(0, 0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + private static DoubleArrayList newImmutableDoubleArrayList(double... elements) { + DoubleArrayList list = new DoubleArrayList(); + for (double element : elements) { + list.addDouble(element); + } + list.makeImmutable(); + return list; + } +} diff --git a/java/src/test/java/com/google/protobuf/FloatArrayListTest.java b/java/src/test/java/com/google/protobuf/FloatArrayListTest.java new file mode 100644 index 00000000..8f3e93dc --- /dev/null +++ b/java/src/test/java/com/google/protobuf/FloatArrayListTest.java @@ -0,0 +1,473 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 static java.util.Arrays.asList; + +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; + +/** + * Tests for {@link FloatArrayList}. + * + * @author dweis@google.com (Daniel Weis) + */ +public class FloatArrayListTest extends TestCase { + + private static final FloatArrayList UNARY_LIST = newImmutableFloatArrayList(1); + private static final FloatArrayList TERTIARY_LIST = + newImmutableFloatArrayList(1, 2, 3); + + private FloatArrayList list; + + @Override + protected void setUp() throws Exception { + list = new FloatArrayList(); + } + + public void testEmptyListReturnsSameInstance() { + assertSame(FloatArrayList.emptyList(), FloatArrayList.emptyList()); + } + + public void testEmptyListIsImmutable() { + assertImmutable(FloatArrayList.emptyList()); + } + + public void testMakeImmutable() { + list.addFloat(2); + list.addFloat(4); + list.addFloat(6); + list.addFloat(8); + list.makeImmutable(); + assertImmutable(list); + } + + public void testCopyConstructor() { + FloatArrayList copy = new FloatArrayList(TERTIARY_LIST); + assertEquals(TERTIARY_LIST, copy); + + copy = new FloatArrayList(FloatArrayList.emptyList()); + assertEquals(FloatArrayList.emptyList(), copy); + + copy = new FloatArrayList(asList(1F, 2F, 3F)); + assertEquals(asList(1F, 2F, 3F), copy); + + copy = new FloatArrayList(Collections.<Float>emptyList()); + assertEquals(FloatArrayList.emptyList(), copy); + } + + public void testModificationWithIteration() { + list.addAll(asList(1F, 2F, 3F, 4F)); + Iterator<Float> iterator = list.iterator(); + assertEquals(4, list.size()); + assertEquals(1F, (float) list.get(0)); + assertEquals(1F, (float) iterator.next()); + list.set(0, 1F); + assertEquals(2F, (float) iterator.next()); + + list.remove(0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + + iterator = list.iterator(); + list.add(0, 0F); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + } + + public void testGet() { + assertEquals(1F, (float) TERTIARY_LIST.get(0)); + assertEquals(2F, (float) TERTIARY_LIST.get(1)); + assertEquals(3F, (float) TERTIARY_LIST.get(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testGetFloat() { + assertEquals(1F, TERTIARY_LIST.getFloat(0)); + assertEquals(2F, TERTIARY_LIST.getFloat(1)); + assertEquals(3F, TERTIARY_LIST.getFloat(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSize() { + assertEquals(0, FloatArrayList.emptyList().size()); + assertEquals(1, UNARY_LIST.size()); + assertEquals(3, TERTIARY_LIST.size()); + + list.addFloat(2); + list.addFloat(4); + list.addFloat(6); + list.addFloat(8); + assertEquals(4, list.size()); + + list.remove(0); + assertEquals(3, list.size()); + + list.add(16F); + assertEquals(4, list.size()); + } + + public void testSet() { + list.addFloat(2); + list.addFloat(4); + + assertEquals(2F, (float) list.set(0, 0F)); + assertEquals(0F, list.getFloat(0)); + + assertEquals(4F, (float) list.set(1, 0F)); + assertEquals(0F, list.getFloat(1)); + + try { + list.set(-1, 0F); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.set(2, 0F); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSetFloat() { + list.addFloat(2); + list.addFloat(4); + + assertEquals(2F, list.setFloat(0, 0)); + assertEquals(0F, list.getFloat(0)); + + assertEquals(4F, list.setFloat(1, 0)); + assertEquals(0F, list.getFloat(1)); + + try { + list.setFloat(-1, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.setFloat(2, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAdd() { + assertEquals(0, list.size()); + + assertTrue(list.add(2F)); + assertEquals(asList(2F), list); + + assertTrue(list.add(3F)); + list.add(0, 4F); + assertEquals(asList(4F, 2F, 3F), list); + + list.add(0, 1F); + list.add(0, 0F); + // Force a resize by getting up to 11 elements. + for (int i = 0; i < 6; i++) { + list.add(Float.valueOf(5 + i)); + } + assertEquals(asList(0F, 1F, 4F, 2F, 3F, 5F, 6F, 7F, 8F, 9F, 10F), list); + + try { + list.add(-1, 5F); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.add(4, 5F); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAddFloat() { + assertEquals(0, list.size()); + + list.addFloat(2); + assertEquals(asList(2F), list); + + list.addFloat(3); + assertEquals(asList(2F, 3F), list); + } + + public void testAddAll() { + assertEquals(0, list.size()); + + assertTrue(list.addAll(Collections.singleton(1F))); + assertEquals(1, list.size()); + assertEquals(1F, (float) list.get(0)); + assertEquals(1F, list.getFloat(0)); + + assertTrue(list.addAll(asList(2F, 3F, 4F, 5F, 6F))); + assertEquals(asList(1F, 2F, 3F, 4F, 5F, 6F), list); + + assertTrue(list.addAll(TERTIARY_LIST)); + assertEquals(asList(1F, 2F, 3F, 4F, 5F, 6F, 1F, 2F, 3F), list); + + assertFalse(list.addAll(Collections.<Float>emptyList())); + assertFalse(list.addAll(FloatArrayList.emptyList())); + } + + public void testRemove() { + list.addAll(TERTIARY_LIST); + assertEquals(1F, (float) list.remove(0)); + assertEquals(asList(2F, 3F), list); + + assertTrue(list.remove(Float.valueOf(3))); + assertEquals(asList(2F), list); + + assertFalse(list.remove(Float.valueOf(3))); + assertEquals(asList(2F), list); + + assertEquals(2F, (float) list.remove(0)); + assertEquals(asList(), list); + + try { + list.remove(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.remove(0); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + private void assertImmutable(FloatArrayList list) { + if (list.contains(1)) { + throw new RuntimeException("Cannot test the immutability of lists that contain 1."); + } + + try { + list.add(1F); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.add(0, 1F); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.<Float>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.singletonList(1F)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(new FloatArrayList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.singleton(1F)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.<Float>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addFloat(0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.clear(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.<Float>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.<Float>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, 0F); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.setFloat(0, 0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + private static FloatArrayList newImmutableFloatArrayList(int... elements) { + FloatArrayList list = new FloatArrayList(); + for (int element : elements) { + list.addFloat(element); + } + list.makeImmutable(); + return list; + } +} diff --git a/java/src/test/java/com/google/protobuf/IntArrayListTest.java b/java/src/test/java/com/google/protobuf/IntArrayListTest.java new file mode 100644 index 00000000..3733eb30 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/IntArrayListTest.java @@ -0,0 +1,473 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 static java.util.Arrays.asList; + +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; + +/** + * Tests for {@link IntArrayList}. + * + * @author dweis@google.com (Daniel Weis) + */ +public class IntArrayListTest extends TestCase { + + private static final IntArrayList UNARY_LIST = newImmutableIntArrayList(1); + private static final IntArrayList TERTIARY_LIST = + newImmutableIntArrayList(1, 2, 3); + + private IntArrayList list; + + @Override + protected void setUp() throws Exception { + list = new IntArrayList(); + } + + public void testEmptyListReturnsSameInstance() { + assertSame(IntArrayList.emptyList(), IntArrayList.emptyList()); + } + + public void testEmptyListIsImmutable() { + assertImmutable(IntArrayList.emptyList()); + } + + public void testMakeImmutable() { + list.addInt(2); + list.addInt(4); + list.addInt(6); + list.addInt(8); + list.makeImmutable(); + assertImmutable(list); + } + + public void testCopyConstructor() { + IntArrayList copy = new IntArrayList(TERTIARY_LIST); + assertEquals(TERTIARY_LIST, copy); + + copy = new IntArrayList(IntArrayList.emptyList()); + assertEquals(IntArrayList.emptyList(), copy); + + copy = new IntArrayList(asList(1, 2, 3)); + assertEquals(asList(1, 2, 3), copy); + + copy = new IntArrayList(Collections.<Integer>emptyList()); + assertEquals(IntArrayList.emptyList(), copy); + } + + public void testModificationWithIteration() { + list.addAll(asList(1, 2, 3, 4)); + Iterator<Integer> iterator = list.iterator(); + assertEquals(4, list.size()); + assertEquals(1, (int) list.get(0)); + assertEquals(1, (int) iterator.next()); + list.set(0, 1); + assertEquals(2, (int) iterator.next()); + + list.remove(0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + + iterator = list.iterator(); + list.add(0, 0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + } + + public void testGet() { + assertEquals(1, (int) TERTIARY_LIST.get(0)); + assertEquals(2, (int) TERTIARY_LIST.get(1)); + assertEquals(3, (int) TERTIARY_LIST.get(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testGetInt() { + assertEquals(1, TERTIARY_LIST.getInt(0)); + assertEquals(2, TERTIARY_LIST.getInt(1)); + assertEquals(3, TERTIARY_LIST.getInt(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSize() { + assertEquals(0, IntArrayList.emptyList().size()); + assertEquals(1, UNARY_LIST.size()); + assertEquals(3, TERTIARY_LIST.size()); + + list.addInt(2); + list.addInt(4); + list.addInt(6); + list.addInt(8); + assertEquals(4, list.size()); + + list.remove(0); + assertEquals(3, list.size()); + + list.add(16); + assertEquals(4, list.size()); + } + + public void testSet() { + list.addInt(2); + list.addInt(4); + + assertEquals(2, (int) list.set(0, 0)); + assertEquals(0, list.getInt(0)); + + assertEquals(4, (int) list.set(1, 0)); + assertEquals(0, list.getInt(1)); + + try { + list.set(-1, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.set(2, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSetInt() { + list.addInt(2); + list.addInt(4); + + assertEquals(2, list.setInt(0, 0)); + assertEquals(0, list.getInt(0)); + + assertEquals(4, list.setInt(1, 0)); + assertEquals(0, list.getInt(1)); + + try { + list.setInt(-1, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.setInt(2, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAdd() { + assertEquals(0, list.size()); + + assertTrue(list.add(2)); + assertEquals(asList(2), list); + + assertTrue(list.add(3)); + list.add(0, 4); + assertEquals(asList(4, 2, 3), list); + + list.add(0, 1); + list.add(0, 0); + // Force a resize by getting up to 11 elements. + for (int i = 0; i < 6; i++) { + list.add(5 + i); + } + assertEquals(asList(0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10), list); + + try { + list.add(-1, 5); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.add(4, 5); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAddInt() { + assertEquals(0, list.size()); + + list.addInt(2); + assertEquals(asList(2), list); + + list.addInt(3); + assertEquals(asList(2, 3), list); + } + + public void testAddAll() { + assertEquals(0, list.size()); + + assertTrue(list.addAll(Collections.singleton(1))); + assertEquals(1, list.size()); + assertEquals(1, (int) list.get(0)); + assertEquals(1, list.getInt(0)); + + assertTrue(list.addAll(asList(2, 3, 4, 5, 6))); + assertEquals(asList(1, 2, 3, 4, 5, 6), list); + + assertTrue(list.addAll(TERTIARY_LIST)); + assertEquals(asList(1, 2, 3, 4, 5, 6, 1, 2, 3), list); + + assertFalse(list.addAll(Collections.<Integer>emptyList())); + assertFalse(list.addAll(IntArrayList.emptyList())); + } + + public void testRemove() { + list.addAll(TERTIARY_LIST); + assertEquals(1, (int) list.remove(0)); + assertEquals(asList(2, 3), list); + + assertTrue(list.remove(Integer.valueOf(3))); + assertEquals(asList(2), list); + + assertFalse(list.remove(Integer.valueOf(3))); + assertEquals(asList(2), list); + + assertEquals(2, (int) list.remove(0)); + assertEquals(asList(), list); + + try { + list.remove(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.remove(0); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + private void assertImmutable(IntArrayList list) { + if (list.contains(1)) { + throw new RuntimeException("Cannot test the immutability of lists that contain 1."); + } + + try { + list.add(1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.add(0, 1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.<Integer>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.singletonList(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(new IntArrayList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.<Integer>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addInt(0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.clear(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.<Integer>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.<Integer>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, 0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.setInt(0, 0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + private static IntArrayList newImmutableIntArrayList(int... elements) { + IntArrayList list = new IntArrayList(); + for (int element : elements) { + list.addInt(element); + } + list.makeImmutable(); + return list; + } +} diff --git a/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java index f3012b96..0f42ac50 100644 --- a/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java +++ b/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java @@ -30,9 +30,13 @@ package com.google.protobuf; +import static java.util.Arrays.asList; + import junit.framework.TestCase; import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.Iterator; import java.util.List; /** @@ -171,4 +175,188 @@ public class LazyStringArrayListTest extends TestCase { assertSame(BYTE_STRING_B, list2.getByteString(1)); assertSame(BYTE_STRING_C, list2.getByteString(2)); } + + public void testModificationWithIteration() { + LazyStringArrayList list = new LazyStringArrayList(); + list.addAll(asList(STRING_A, STRING_B, STRING_C)); + Iterator<String> iterator = list.iterator(); + assertEquals(3, list.size()); + assertEquals(STRING_A, list.get(0)); + assertEquals(STRING_A, iterator.next()); + + // Does not structurally modify. + iterator = list.iterator(); + list.set(0, STRING_B); + iterator.next(); + + list.remove(0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + + iterator = list.iterator(); + list.add(0, STRING_C); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + } + + public void testMakeImmutable() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + list.add(STRING_B); + list.add(STRING_C); + list.makeImmutable(); + assertGenericListImmutable(list, STRING_A); + + // LazyStringArrayList has extra methods not covered in the generic + // assertion. + + try { + list.add(BYTE_STRING_A.toByteArray()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.add(BYTE_STRING_A); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAllByteArray(asList(BYTE_STRING_A.toByteArray())); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAllByteString(asList(BYTE_STRING_A)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.mergeFrom(new LazyStringArrayList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, BYTE_STRING_A.toByteArray()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, BYTE_STRING_A); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + public void testImmutabilityPropagation() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + list.makeImmutable(); + + assertGenericListImmutable(list.asByteStringList(), BYTE_STRING_A); + + // Arrays use reference equality so need to retrieve the underlying value + // to properly test deep immutability. + List<byte[]> byteArrayList = list.asByteArrayList(); + assertGenericListImmutable(byteArrayList, byteArrayList.get(0)); + } + + private static <T> void assertGenericListImmutable(List<T> list, T value) { + try { + list.add(value); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.add(0, value); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(asList(value)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, asList(value)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.clear(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(value); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(asList(value)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(asList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(asList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, value); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } } diff --git a/java/src/test/java/com/google/protobuf/LiteTest.java b/java/src/test/java/com/google/protobuf/LiteTest.java index 4d8037fc..8c3b5e5c 100644 --- a/java/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/src/test/java/com/google/protobuf/LiteTest.java @@ -30,9 +30,18 @@ package com.google.protobuf; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; + import com.google.protobuf.UnittestLite; -import com.google.protobuf.UnittestLite.TestAllTypesLite; +import com.google.protobuf.UnittestLite.ForeignEnumLite; +import com.google.protobuf.UnittestLite.ForeignMessageLite; import com.google.protobuf.UnittestLite.TestAllExtensionsLite; +import com.google.protobuf.UnittestLite.TestAllTypesLite; +import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage; +import com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase; +import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup; +import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup; import com.google.protobuf.UnittestLite.TestNestedExtensionLite; import junit.framework.TestCase; @@ -149,13 +158,1302 @@ public class LiteTest extends TestCase { public void testClone() { TestAllTypesLite.Builder expected = TestAllTypesLite.newBuilder() .setOptionalInt32(123); - assertEquals( - expected.getOptionalInt32(), expected.clone().getOptionalInt32()); + assertEquals( + expected.getOptionalInt32(), expected.clone().getOptionalInt32()); - TestAllExtensionsLite.Builder expected2 = TestAllExtensionsLite.newBuilder() - .setExtension(UnittestLite.optionalInt32ExtensionLite, 123); - assertEquals( - expected2.getExtension(UnittestLite.optionalInt32ExtensionLite), - expected2.clone().getExtension(UnittestLite.optionalInt32ExtensionLite)); + TestAllExtensionsLite.Builder expected2 = TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123); + assertEquals( + expected2.getExtension(UnittestLite.optionalInt32ExtensionLite), + expected2.clone().getExtension(UnittestLite.optionalInt32ExtensionLite)); + } + + public void testAddAll() { + try { + TestAllTypesLite.newBuilder() + .addAllRepeatedBytes(null); + fail(); + } catch (NullPointerException e) { + // expected. + } + } + + public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { + // Since builders are implemented as a thin wrapper around a message + // instance, we attempt to verify that we can't cause the builder to modify + // a produced message. + + TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder(); + TestAllTypesLite message = builder.build(); + TestAllTypesLite messageAfterBuild; + builder.setOptionalBool(true); + assertEquals(false, message.getOptionalBool()); + assertEquals(true, builder.getOptionalBool()); + messageAfterBuild = builder.build(); + assertEquals(true, messageAfterBuild.getOptionalBool()); + assertEquals(false, message.getOptionalBool()); + builder.clearOptionalBool(); + assertEquals(false, builder.getOptionalBool()); + assertEquals(true, messageAfterBuild.getOptionalBool()); + + message = builder.build(); + builder.setOptionalBytes(ByteString.copyFromUtf8("hi")); + assertEquals(ByteString.EMPTY, message.getOptionalBytes()); + assertEquals(ByteString.copyFromUtf8("hi"), builder.getOptionalBytes()); + messageAfterBuild = builder.build(); + assertEquals( + ByteString.copyFromUtf8("hi"), messageAfterBuild.getOptionalBytes()); + assertEquals(ByteString.EMPTY, message.getOptionalBytes()); + builder.clearOptionalBytes(); + assertEquals(ByteString.EMPTY, builder.getOptionalBytes()); + assertEquals( + ByteString.copyFromUtf8("hi"), messageAfterBuild.getOptionalBytes()); + + message = builder.build(); + builder.setOptionalCord("hi"); + assertEquals("", message.getOptionalCord()); + assertEquals("hi", builder.getOptionalCord()); + messageAfterBuild = builder.build(); + assertEquals("hi", messageAfterBuild.getOptionalCord()); + assertEquals("", message.getOptionalCord()); + builder.clearOptionalCord(); + assertEquals("", builder.getOptionalCord()); + assertEquals("hi", messageAfterBuild.getOptionalCord()); + + message = builder.build(); + builder.setOptionalCordBytes(ByteString.copyFromUtf8("no")); + assertEquals(ByteString.EMPTY, message.getOptionalCordBytes()); + assertEquals(ByteString.copyFromUtf8("no"), builder.getOptionalCordBytes()); + messageAfterBuild = builder.build(); + assertEquals( + ByteString.copyFromUtf8("no"), + messageAfterBuild.getOptionalCordBytes()); + assertEquals(ByteString.EMPTY, message.getOptionalCordBytes()); + builder.clearOptionalCord(); + assertEquals(ByteString.EMPTY, builder.getOptionalCordBytes()); + assertEquals( + ByteString.copyFromUtf8("no"), + messageAfterBuild.getOptionalCordBytes()); + + message = builder.build(); + builder.setOptionalDouble(1); + assertEquals(0D, message.getOptionalDouble()); + assertEquals(1D, builder.getOptionalDouble()); + messageAfterBuild = builder.build(); + assertEquals(1D, messageAfterBuild.getOptionalDouble()); + assertEquals(0D, message.getOptionalDouble()); + builder.clearOptionalDouble(); + assertEquals(0D, builder.getOptionalDouble()); + assertEquals(1D, messageAfterBuild.getOptionalDouble()); + + message = builder.build(); + builder.setOptionalFixed32(1); + assertEquals(0, message.getOptionalFixed32()); + assertEquals(1, builder.getOptionalFixed32()); + messageAfterBuild = builder.build(); + assertEquals(1, messageAfterBuild.getOptionalFixed32()); + assertEquals(0, message.getOptionalFixed32()); + builder.clearOptionalFixed32(); + assertEquals(0, builder.getOptionalFixed32()); + assertEquals(1, messageAfterBuild.getOptionalFixed32()); + + message = builder.build(); + builder.setOptionalFixed64(1); + assertEquals(0L, message.getOptionalFixed64()); + assertEquals(1L, builder.getOptionalFixed64()); + messageAfterBuild = builder.build(); + assertEquals(1L, messageAfterBuild.getOptionalFixed64()); + assertEquals(0L, message.getOptionalFixed64()); + builder.clearOptionalFixed64(); + assertEquals(0L, builder.getOptionalFixed64()); + assertEquals(1L, messageAfterBuild.getOptionalFixed64()); + + message = builder.build(); + builder.setOptionalFloat(1); + assertEquals(0F, message.getOptionalFloat()); + assertEquals(1F, builder.getOptionalFloat()); + messageAfterBuild = builder.build(); + assertEquals(1F, messageAfterBuild.getOptionalFloat()); + assertEquals(0F, message.getOptionalFloat()); + builder.clearOptionalFloat(); + assertEquals(0F, builder.getOptionalFloat()); + assertEquals(1F, messageAfterBuild.getOptionalFloat()); + + message = builder.build(); + builder.setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR); + assertEquals( + ForeignEnumLite.FOREIGN_LITE_FOO, message.getOptionalForeignEnum()); + assertEquals( + ForeignEnumLite.FOREIGN_LITE_BAR, builder.getOptionalForeignEnum()); + messageAfterBuild = builder.build(); + assertEquals( + ForeignEnumLite.FOREIGN_LITE_BAR, + messageAfterBuild.getOptionalForeignEnum()); + assertEquals( + ForeignEnumLite.FOREIGN_LITE_FOO, message.getOptionalForeignEnum()); + builder.clearOptionalForeignEnum(); + assertEquals( + ForeignEnumLite.FOREIGN_LITE_FOO, builder.getOptionalForeignEnum()); + assertEquals( + ForeignEnumLite.FOREIGN_LITE_BAR, + messageAfterBuild.getOptionalForeignEnum()); + + message = builder.build(); + ForeignMessageLite foreignMessage = ForeignMessageLite.newBuilder() + .setC(1) + .build(); + builder.setOptionalForeignMessage(foreignMessage); + assertEquals( + ForeignMessageLite.getDefaultInstance(), + message.getOptionalForeignMessage()); + assertEquals(foreignMessage, builder.getOptionalForeignMessage()); + messageAfterBuild = builder.build(); + assertEquals(foreignMessage, messageAfterBuild.getOptionalForeignMessage()); + assertEquals( + ForeignMessageLite.getDefaultInstance(), + message.getOptionalForeignMessage()); + builder.clearOptionalForeignMessage(); + assertEquals( + ForeignMessageLite.getDefaultInstance(), + builder.getOptionalForeignMessage()); + assertEquals(foreignMessage, messageAfterBuild.getOptionalForeignMessage()); + + message = builder.build(); + ForeignMessageLite.Builder foreignMessageBuilder = + ForeignMessageLite.newBuilder() + .setC(3); + builder.setOptionalForeignMessage(foreignMessageBuilder); + assertEquals( + ForeignMessageLite.getDefaultInstance(), + message.getOptionalForeignMessage()); + // LITE_RUNTIME doesn't implement equals so we compare on a property and + // ensure the property isn't set on foreignMessage. + assertEquals(3, builder.getOptionalForeignMessage().getC()); + messageAfterBuild = builder.build(); + assertEquals(3, messageAfterBuild.getOptionalForeignMessage().getC()); + assertEquals( + ForeignMessageLite.getDefaultInstance(), + message.getOptionalForeignMessage()); + builder.clearOptionalForeignMessage(); + assertEquals( + ForeignMessageLite.getDefaultInstance(), + builder.getOptionalForeignMessage()); + assertEquals(3, messageAfterBuild.getOptionalForeignMessage().getC()); + + message = builder.build(); + OptionalGroup optionalGroup = OptionalGroup.newBuilder() + .setA(1) + .build(); + builder.setOptionalGroup(optionalGroup); + assertEquals( + OptionalGroup.getDefaultInstance(), message.getOptionalGroup()); + assertEquals(optionalGroup, builder.getOptionalGroup()); + messageAfterBuild = builder.build(); + assertEquals(optionalGroup, messageAfterBuild.getOptionalGroup()); + assertEquals( + OptionalGroup.getDefaultInstance(), message.getOptionalGroup()); + builder.clearOptionalGroup(); + assertEquals( + OptionalGroup.getDefaultInstance(), builder.getOptionalGroup()); + assertEquals(optionalGroup, messageAfterBuild.getOptionalGroup()); + + message = builder.build(); + OptionalGroup.Builder optionalGroupBuilder = OptionalGroup.newBuilder() + .setA(3); + builder.setOptionalGroup(optionalGroupBuilder); + assertEquals( + OptionalGroup.getDefaultInstance(), message.getOptionalGroup()); + // LITE_RUNTIME doesn't implement equals so we compare on a property and + // ensure the property isn't set on optionalGroup. + assertEquals(3, builder.getOptionalGroup().getA()); + messageAfterBuild = builder.build(); + assertEquals(3, messageAfterBuild.getOptionalGroup().getA()); + assertEquals( + OptionalGroup.getDefaultInstance(), message.getOptionalGroup()); + builder.clearOptionalGroup(); + assertEquals( + OptionalGroup.getDefaultInstance(), builder.getOptionalGroup()); + assertEquals(3, messageAfterBuild.getOptionalGroup().getA()); + + message = builder.build(); + builder.setOptionalInt32(1); + assertEquals(0, message.getOptionalInt32()); + assertEquals(1, builder.getOptionalInt32()); + messageAfterBuild = builder.build(); + assertEquals(1, messageAfterBuild.getOptionalInt32()); + assertEquals(0, message.getOptionalInt32()); + builder.clearOptionalInt32(); + assertEquals(0, builder.getOptionalInt32()); + assertEquals(1, messageAfterBuild.getOptionalInt32()); + + message = builder.build(); + builder.setOptionalInt64(1); + assertEquals(0L, message.getOptionalInt64()); + assertEquals(1L, builder.getOptionalInt64()); + messageAfterBuild = builder.build(); + assertEquals(1L, messageAfterBuild.getOptionalInt64()); + assertEquals(0L, message.getOptionalInt64()); + builder.clearOptionalInt64(); + assertEquals(0L, builder.getOptionalInt64()); + assertEquals(1L, messageAfterBuild.getOptionalInt64()); + + message = builder.build(); + NestedMessage nestedMessage = NestedMessage.newBuilder() + .setBb(1) + .build(); + builder.setOptionalLazyMessage(nestedMessage); + assertEquals( + NestedMessage.getDefaultInstance(), + message.getOptionalLazyMessage()); + assertEquals(nestedMessage, builder.getOptionalLazyMessage()); + messageAfterBuild = builder.build(); + assertEquals(nestedMessage, messageAfterBuild.getOptionalLazyMessage()); + assertEquals( + NestedMessage.getDefaultInstance(), + message.getOptionalLazyMessage()); + builder.clearOptionalLazyMessage(); + assertEquals( + NestedMessage.getDefaultInstance(), builder.getOptionalLazyMessage()); + assertEquals(nestedMessage, messageAfterBuild.getOptionalLazyMessage()); + + message = builder.build(); + NestedMessage.Builder nestedMessageBuilder = + NestedMessage.newBuilder() + .setBb(3); + builder.setOptionalLazyMessage(nestedMessageBuilder); + assertEquals( + NestedMessage.getDefaultInstance(), + message.getOptionalLazyMessage()); + // LITE_RUNTIME doesn't implement equals so we compare on a property. + assertEquals(3, builder.getOptionalLazyMessage().getBb()); + messageAfterBuild = builder.build(); + assertEquals(3, messageAfterBuild.getOptionalLazyMessage().getBb()); + assertEquals( + NestedMessage.getDefaultInstance(), + message.getOptionalLazyMessage()); + builder.clearOptionalLazyMessage(); + assertEquals( + NestedMessage.getDefaultInstance(), builder.getOptionalLazyMessage()); + assertEquals(3, messageAfterBuild.getOptionalLazyMessage().getBb()); + + message = builder.build(); + builder.setOptionalSfixed32(1); + assertEquals(0, message.getOptionalSfixed32()); + assertEquals(1, builder.getOptionalSfixed32()); + messageAfterBuild = builder.build(); + assertEquals(1, messageAfterBuild.getOptionalSfixed32()); + assertEquals(0, message.getOptionalSfixed32()); + builder.clearOptionalSfixed32(); + assertEquals(0, builder.getOptionalSfixed32()); + assertEquals(1, messageAfterBuild.getOptionalSfixed32()); + + message = builder.build(); + builder.setOptionalSfixed64(1); + assertEquals(0L, message.getOptionalSfixed64()); + assertEquals(1L, builder.getOptionalSfixed64()); + messageAfterBuild = builder.build(); + assertEquals(1L, messageAfterBuild.getOptionalSfixed64()); + assertEquals(0L, message.getOptionalSfixed64()); + builder.clearOptionalSfixed64(); + assertEquals(0L, builder.getOptionalSfixed64()); + assertEquals(1L, messageAfterBuild.getOptionalSfixed64()); + + message = builder.build(); + builder.setOptionalSint32(1); + assertEquals(0, message.getOptionalSint32()); + assertEquals(1, builder.getOptionalSint32()); + messageAfterBuild = builder.build(); + assertEquals(1, messageAfterBuild.getOptionalSint32()); + builder.clearOptionalSint32(); + assertEquals(0, builder.getOptionalSint32()); + assertEquals(1, messageAfterBuild.getOptionalSint32()); + + message = builder.build(); + builder.setOptionalSint64(1); + assertEquals(0L, message.getOptionalSint64()); + assertEquals(1L, builder.getOptionalSint64()); + messageAfterBuild = builder.build(); + assertEquals(1L, messageAfterBuild.getOptionalSint64()); + assertEquals(0L, message.getOptionalSint64()); + builder.clearOptionalSint64(); + assertEquals(0L, builder.getOptionalSint64()); + assertEquals(1L, messageAfterBuild.getOptionalSint64()); + + message = builder.build(); + builder.setOptionalString("hi"); + assertEquals("", message.getOptionalString()); + assertEquals("hi", builder.getOptionalString()); + messageAfterBuild = builder.build(); + assertEquals("hi", messageAfterBuild.getOptionalString()); + assertEquals("", message.getOptionalString()); + builder.clearOptionalString(); + assertEquals("", builder.getOptionalString()); + assertEquals("hi", messageAfterBuild.getOptionalString()); + + message = builder.build(); + builder.setOptionalStringBytes(ByteString.copyFromUtf8("no")); + assertEquals(ByteString.EMPTY, message.getOptionalStringBytes()); + assertEquals( + ByteString.copyFromUtf8("no"), builder.getOptionalStringBytes()); + messageAfterBuild = builder.build(); + assertEquals( + ByteString.copyFromUtf8("no"), + messageAfterBuild.getOptionalStringBytes()); + assertEquals(ByteString.EMPTY, message.getOptionalStringBytes()); + builder.clearOptionalString(); + assertEquals(ByteString.EMPTY, builder.getOptionalStringBytes()); + assertEquals( + ByteString.copyFromUtf8("no"), + messageAfterBuild.getOptionalStringBytes()); + + message = builder.build(); + builder.setOptionalStringPiece("hi"); + assertEquals("", message.getOptionalStringPiece()); + assertEquals("hi", builder.getOptionalStringPiece()); + messageAfterBuild = builder.build(); + assertEquals("hi", messageAfterBuild.getOptionalStringPiece()); + assertEquals("", message.getOptionalStringPiece()); + builder.clearOptionalStringPiece(); + assertEquals("", builder.getOptionalStringPiece()); + assertEquals("hi", messageAfterBuild.getOptionalStringPiece()); + + message = builder.build(); + builder.setOptionalStringPieceBytes(ByteString.copyFromUtf8("no")); + assertEquals(ByteString.EMPTY, message.getOptionalStringPieceBytes()); + assertEquals( + ByteString.copyFromUtf8("no"), builder.getOptionalStringPieceBytes()); + messageAfterBuild = builder.build(); + assertEquals( + ByteString.copyFromUtf8("no"), + messageAfterBuild.getOptionalStringPieceBytes()); + assertEquals(ByteString.EMPTY, message.getOptionalStringPieceBytes()); + builder.clearOptionalStringPiece(); + assertEquals(ByteString.EMPTY, builder.getOptionalStringPieceBytes()); + assertEquals( + ByteString.copyFromUtf8("no"), + messageAfterBuild.getOptionalStringPieceBytes()); + + message = builder.build(); + builder.setOptionalUint32(1); + assertEquals(0, message.getOptionalUint32()); + assertEquals(1, builder.getOptionalUint32()); + messageAfterBuild = builder.build(); + assertEquals(1, messageAfterBuild.getOptionalUint32()); + assertEquals(0, message.getOptionalUint32()); + builder.clearOptionalUint32(); + assertEquals(0, builder.getOptionalUint32()); + assertEquals(1, messageAfterBuild.getOptionalUint32()); + + message = builder.build(); + builder.setOptionalUint64(1); + assertEquals(0L, message.getOptionalUint64()); + assertEquals(1L, builder.getOptionalUint64()); + messageAfterBuild = builder.build(); + assertEquals(1L, messageAfterBuild.getOptionalUint64()); + assertEquals(0L, message.getOptionalUint64()); + builder.clearOptionalUint64(); + assertEquals(0L, builder.getOptionalUint64()); + assertEquals(1L, messageAfterBuild.getOptionalUint64()); + + message = builder.build(); + builder.addAllRepeatedBool(singletonList(true)); + assertEquals(emptyList(), message.getRepeatedBoolList()); + assertEquals(singletonList(true), builder.getRepeatedBoolList()); + assertEquals(emptyList(), message.getRepeatedBoolList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedBool(); + assertEquals(emptyList(), builder.getRepeatedBoolList()); + assertEquals(singletonList(true), messageAfterBuild.getRepeatedBoolList()); + + message = builder.build(); + builder.addAllRepeatedBytes(singletonList(ByteString.copyFromUtf8("hi"))); + assertEquals(emptyList(), message.getRepeatedBytesList()); + assertEquals( + singletonList(ByteString.copyFromUtf8("hi")), + builder.getRepeatedBytesList()); + assertEquals(emptyList(), message.getRepeatedBytesList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedBytes(); + assertEquals(emptyList(), builder.getRepeatedBytesList()); + assertEquals( + singletonList(ByteString.copyFromUtf8("hi")), + messageAfterBuild.getRepeatedBytesList()); + + message = builder.build(); + builder.addAllRepeatedCord(singletonList("hi")); + assertEquals(emptyList(), message.getRepeatedCordList()); + assertEquals(singletonList("hi"), builder.getRepeatedCordList()); + assertEquals(emptyList(), message.getRepeatedCordList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedCord(); + assertEquals(emptyList(), builder.getRepeatedCordList()); + assertEquals(singletonList("hi"), messageAfterBuild.getRepeatedCordList()); + + message = builder.build(); + builder.addAllRepeatedDouble(singletonList(1D)); + assertEquals(emptyList(), message.getRepeatedDoubleList()); + assertEquals(singletonList(1D), builder.getRepeatedDoubleList()); + assertEquals(emptyList(), message.getRepeatedDoubleList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedDouble(); + assertEquals(emptyList(), builder.getRepeatedDoubleList()); + assertEquals(singletonList(1D), messageAfterBuild.getRepeatedDoubleList()); + + message = builder.build(); + builder.addAllRepeatedFixed32(singletonList(1)); + assertEquals(emptyList(), message.getRepeatedFixed32List()); + assertEquals(singletonList(1), builder.getRepeatedFixed32List()); + assertEquals(emptyList(), message.getRepeatedFixed32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedFixed32(); + assertEquals(emptyList(), builder.getRepeatedFixed32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedFixed32List()); + + message = builder.build(); + builder.addAllRepeatedFixed64(singletonList(1L)); + assertEquals(emptyList(), message.getRepeatedFixed64List()); + assertEquals(singletonList(1L), builder.getRepeatedFixed64List()); + assertEquals(emptyList(), message.getRepeatedFixed64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedFixed64(); + assertEquals(emptyList(), builder.getRepeatedFixed64List()); + assertEquals(singletonList(1L), messageAfterBuild.getRepeatedFixed64List()); + + message = builder.build(); + builder.addAllRepeatedFloat(singletonList(1F)); + assertEquals(emptyList(), message.getRepeatedFloatList()); + assertEquals(singletonList(1F), builder.getRepeatedFloatList()); + assertEquals(emptyList(), message.getRepeatedFloatList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedFloat(); + assertEquals(emptyList(), builder.getRepeatedFloatList()); + assertEquals(singletonList(1F), messageAfterBuild.getRepeatedFloatList()); + + message = builder.build(); + builder.addAllRepeatedForeignEnum( + singletonList(ForeignEnumLite.FOREIGN_LITE_BAR)); + assertEquals(emptyList(), message.getRepeatedForeignEnumList()); + assertEquals( + singletonList(ForeignEnumLite.FOREIGN_LITE_BAR), + builder.getRepeatedForeignEnumList()); + assertEquals(emptyList(), message.getRepeatedForeignEnumList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedForeignEnum(); + assertEquals(emptyList(), builder.getRepeatedForeignEnumList()); + assertEquals( + singletonList(ForeignEnumLite.FOREIGN_LITE_BAR), + messageAfterBuild.getRepeatedForeignEnumList()); + + message = builder.build(); + builder.addAllRepeatedForeignMessage(singletonList(foreignMessage)); + assertEquals(emptyList(), message.getRepeatedForeignMessageList()); + assertEquals( + singletonList(foreignMessage), builder.getRepeatedForeignMessageList()); + assertEquals(emptyList(), message.getRepeatedForeignMessageList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedForeignMessage(); + assertEquals(emptyList(), builder.getRepeatedForeignMessageList()); + assertEquals( + singletonList(foreignMessage), + messageAfterBuild.getRepeatedForeignMessageList()); + + message = builder.build(); + builder.addAllRepeatedGroup( + singletonList(RepeatedGroup.getDefaultInstance())); + assertEquals(emptyList(), message.getRepeatedGroupList()); + assertEquals( + singletonList(RepeatedGroup.getDefaultInstance()), + builder.getRepeatedGroupList()); + assertEquals(emptyList(), message.getRepeatedGroupList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedGroup(); + assertEquals(emptyList(), builder.getRepeatedGroupList()); + assertEquals( + singletonList(RepeatedGroup.getDefaultInstance()), + messageAfterBuild.getRepeatedGroupList()); + + message = builder.build(); + builder.addAllRepeatedInt32(singletonList(1)); + assertEquals(emptyList(), message.getRepeatedInt32List()); + assertEquals(singletonList(1), builder.getRepeatedInt32List()); + assertEquals(emptyList(), message.getRepeatedInt32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedInt32(); + assertEquals(emptyList(), builder.getRepeatedInt32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedInt32List()); + + message = builder.build(); + builder.addAllRepeatedInt64(singletonList(1L)); + assertEquals(emptyList(), message.getRepeatedInt64List()); + assertEquals(singletonList(1L), builder.getRepeatedInt64List()); + assertEquals(emptyList(), message.getRepeatedInt64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedInt64(); + assertEquals(emptyList(), builder.getRepeatedInt64List()); + assertEquals(singletonList(1L), messageAfterBuild.getRepeatedInt64List()); + + message = builder.build(); + builder.addAllRepeatedLazyMessage(singletonList(nestedMessage)); + assertEquals(emptyList(), message.getRepeatedLazyMessageList()); + assertEquals( + singletonList(nestedMessage), builder.getRepeatedLazyMessageList()); + assertEquals(emptyList(), message.getRepeatedLazyMessageList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedLazyMessage(); + assertEquals(emptyList(), builder.getRepeatedLazyMessageList()); + assertEquals( + singletonList(nestedMessage), + messageAfterBuild.getRepeatedLazyMessageList()); + + message = builder.build(); + builder.addAllRepeatedSfixed32(singletonList(1)); + assertEquals(emptyList(), message.getRepeatedSfixed32List()); + assertEquals(singletonList(1), builder.getRepeatedSfixed32List()); + assertEquals(emptyList(), message.getRepeatedSfixed32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedSfixed32(); + assertEquals(emptyList(), builder.getRepeatedSfixed32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedSfixed32List()); + + message = builder.build(); + builder.addAllRepeatedSfixed64(singletonList(1L)); + assertEquals(emptyList(), message.getRepeatedSfixed64List()); + assertEquals(singletonList(1L), builder.getRepeatedSfixed64List()); + assertEquals(emptyList(), message.getRepeatedSfixed64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedSfixed64(); + assertEquals(emptyList(), builder.getRepeatedSfixed64List()); + assertEquals( + singletonList(1L), messageAfterBuild.getRepeatedSfixed64List()); + + message = builder.build(); + builder.addAllRepeatedSint32(singletonList(1)); + assertEquals(emptyList(), message.getRepeatedSint32List()); + assertEquals(singletonList(1), builder.getRepeatedSint32List()); + assertEquals(emptyList(), message.getRepeatedSint32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedSint32(); + assertEquals(emptyList(), builder.getRepeatedSint32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedSint32List()); + + message = builder.build(); + builder.addAllRepeatedSint64(singletonList(1L)); + assertEquals(emptyList(), message.getRepeatedSint64List()); + assertEquals(singletonList(1L), builder.getRepeatedSint64List()); + assertEquals(emptyList(), message.getRepeatedSint64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedSint64(); + assertEquals(emptyList(), builder.getRepeatedSint64List()); + assertEquals(singletonList(1L), messageAfterBuild.getRepeatedSint64List()); + + message = builder.build(); + builder.addAllRepeatedString(singletonList("hi")); + assertEquals(emptyList(), message.getRepeatedStringList()); + assertEquals(singletonList("hi"), builder.getRepeatedStringList()); + assertEquals(emptyList(), message.getRepeatedStringList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedString(); + assertEquals(emptyList(), builder.getRepeatedStringList()); + assertEquals( + singletonList("hi"), messageAfterBuild.getRepeatedStringList()); + + message = builder.build(); + builder.addAllRepeatedStringPiece(singletonList("hi")); + assertEquals(emptyList(), message.getRepeatedStringPieceList()); + assertEquals(singletonList("hi"), builder.getRepeatedStringPieceList()); + assertEquals(emptyList(), message.getRepeatedStringPieceList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedStringPiece(); + assertEquals(emptyList(), builder.getRepeatedStringPieceList()); + assertEquals( + singletonList("hi"), messageAfterBuild.getRepeatedStringPieceList()); + + message = builder.build(); + builder.addAllRepeatedUint32(singletonList(1)); + assertEquals(emptyList(), message.getRepeatedUint32List()); + assertEquals(singletonList(1), builder.getRepeatedUint32List()); + assertEquals(emptyList(), message.getRepeatedUint32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedUint32(); + assertEquals(emptyList(), builder.getRepeatedUint32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedUint32List()); + + message = builder.build(); + builder.addAllRepeatedUint64(singletonList(1L)); + assertEquals(emptyList(), message.getRepeatedUint64List()); + assertEquals(singletonList(1L), builder.getRepeatedUint64List()); + assertEquals(emptyList(), message.getRepeatedUint64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedUint64(); + assertEquals(emptyList(), builder.getRepeatedUint64List()); + assertEquals(singletonList(1L), messageAfterBuild.getRepeatedUint64List()); + + message = builder.build(); + builder.addRepeatedBool(true); + assertEquals(emptyList(), message.getRepeatedBoolList()); + assertEquals(singletonList(true), builder.getRepeatedBoolList()); + assertEquals(emptyList(), message.getRepeatedBoolList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedBool(); + assertEquals(emptyList(), builder.getRepeatedBoolList()); + assertEquals(singletonList(true), messageAfterBuild.getRepeatedBoolList()); + + message = builder.build(); + builder.addRepeatedBytes(ByteString.copyFromUtf8("hi")); + assertEquals(emptyList(), message.getRepeatedBytesList()); + assertEquals( + singletonList(ByteString.copyFromUtf8("hi")), + builder.getRepeatedBytesList()); + assertEquals(emptyList(), message.getRepeatedBytesList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedBytes(); + assertEquals(emptyList(), builder.getRepeatedBytesList()); + assertEquals( + singletonList(ByteString.copyFromUtf8("hi")), + messageAfterBuild.getRepeatedBytesList()); + + message = builder.build(); + builder.addRepeatedCord("hi"); + assertEquals(emptyList(), message.getRepeatedCordList()); + assertEquals(singletonList("hi"), builder.getRepeatedCordList()); + assertEquals(emptyList(), message.getRepeatedCordList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedCord(); + assertEquals(emptyList(), builder.getRepeatedCordList()); + assertEquals(singletonList("hi"), messageAfterBuild.getRepeatedCordList()); + + message = builder.build(); + builder.addRepeatedDouble(1D); + assertEquals(emptyList(), message.getRepeatedDoubleList()); + assertEquals(singletonList(1D), builder.getRepeatedDoubleList()); + assertEquals(emptyList(), message.getRepeatedDoubleList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedDouble(); + assertEquals(emptyList(), builder.getRepeatedDoubleList()); + assertEquals(singletonList(1D), messageAfterBuild.getRepeatedDoubleList()); + + message = builder.build(); + builder.addRepeatedFixed32(1); + assertEquals(emptyList(), message.getRepeatedFixed32List()); + assertEquals(singletonList(1), builder.getRepeatedFixed32List()); + assertEquals(emptyList(), message.getRepeatedFixed32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedFixed32(); + assertEquals(emptyList(), builder.getRepeatedFixed32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedFixed32List()); + + message = builder.build(); + builder.addRepeatedFixed64(1L); + assertEquals(emptyList(), message.getRepeatedFixed64List()); + assertEquals(singletonList(1L), builder.getRepeatedFixed64List()); + assertEquals(emptyList(), message.getRepeatedFixed64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedFixed64(); + assertEquals(emptyList(), builder.getRepeatedFixed64List()); + assertEquals(singletonList(1L), messageAfterBuild.getRepeatedFixed64List()); + + message = builder.build(); + builder.addRepeatedFloat(1F); + assertEquals(emptyList(), message.getRepeatedFloatList()); + assertEquals(singletonList(1F), builder.getRepeatedFloatList()); + assertEquals(emptyList(), message.getRepeatedFloatList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedFloat(); + assertEquals(emptyList(), builder.getRepeatedFloatList()); + assertEquals(singletonList(1F), messageAfterBuild.getRepeatedFloatList()); + + message = builder.build(); + builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR); + assertEquals(emptyList(), message.getRepeatedForeignEnumList()); + assertEquals( + singletonList(ForeignEnumLite.FOREIGN_LITE_BAR), + builder.getRepeatedForeignEnumList()); + assertEquals(emptyList(), message.getRepeatedForeignEnumList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedForeignEnum(); + assertEquals(emptyList(), builder.getRepeatedForeignEnumList()); + assertEquals( + singletonList(ForeignEnumLite.FOREIGN_LITE_BAR), + messageAfterBuild.getRepeatedForeignEnumList()); + + message = builder.build(); + builder.addRepeatedForeignMessage(foreignMessage); + assertEquals(emptyList(), message.getRepeatedForeignMessageList()); + assertEquals( + singletonList(foreignMessage), builder.getRepeatedForeignMessageList()); + assertEquals(emptyList(), message.getRepeatedForeignMessageList()); + messageAfterBuild = builder.build(); + builder.removeRepeatedForeignMessage(0); + assertEquals(emptyList(), builder.getRepeatedForeignMessageList()); + assertEquals( + singletonList(foreignMessage), + messageAfterBuild.getRepeatedForeignMessageList()); + + message = builder.build(); + builder.addRepeatedGroup(RepeatedGroup.getDefaultInstance()); + assertEquals(emptyList(), message.getRepeatedGroupList()); + assertEquals( + singletonList(RepeatedGroup.getDefaultInstance()), + builder.getRepeatedGroupList()); + assertEquals(emptyList(), message.getRepeatedGroupList()); + messageAfterBuild = builder.build(); + builder.removeRepeatedGroup(0); + assertEquals(emptyList(), builder.getRepeatedGroupList()); + assertEquals( + singletonList(RepeatedGroup.getDefaultInstance()), + messageAfterBuild.getRepeatedGroupList()); + + message = builder.build(); + builder.addRepeatedInt32(1); + assertEquals(emptyList(), message.getRepeatedInt32List()); + assertEquals(singletonList(1), builder.getRepeatedInt32List()); + assertEquals(emptyList(), message.getRepeatedInt32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedInt32(); + assertEquals(emptyList(), builder.getRepeatedInt32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedInt32List()); + + message = builder.build(); + builder.addRepeatedInt64(1L); + assertEquals(emptyList(), message.getRepeatedInt64List()); + assertEquals(singletonList(1L), builder.getRepeatedInt64List()); + assertEquals(emptyList(), message.getRepeatedInt64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedInt64(); + assertEquals(emptyList(), builder.getRepeatedInt64List()); + assertEquals(singletonList(1L), messageAfterBuild.getRepeatedInt64List()); + + message = builder.build(); + builder.addRepeatedLazyMessage(nestedMessage); + assertEquals(emptyList(), message.getRepeatedLazyMessageList()); + assertEquals( + singletonList(nestedMessage), builder.getRepeatedLazyMessageList()); + assertEquals(emptyList(), message.getRepeatedLazyMessageList()); + messageAfterBuild = builder.build(); + builder.removeRepeatedLazyMessage(0); + assertEquals(emptyList(), builder.getRepeatedLazyMessageList()); + assertEquals( + singletonList(nestedMessage), + messageAfterBuild.getRepeatedLazyMessageList()); + + message = builder.build(); + builder.addRepeatedSfixed32(1); + assertEquals(emptyList(), message.getRepeatedSfixed32List()); + assertEquals(singletonList(1), builder.getRepeatedSfixed32List()); + assertEquals(emptyList(), message.getRepeatedSfixed32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedSfixed32(); + assertEquals(emptyList(), builder.getRepeatedSfixed32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedSfixed32List()); + + message = builder.build(); + builder.addRepeatedSfixed64(1L); + assertEquals(emptyList(), message.getRepeatedSfixed64List()); + assertEquals(singletonList(1L), builder.getRepeatedSfixed64List()); + assertEquals(emptyList(), message.getRepeatedSfixed64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedSfixed64(); + assertEquals(emptyList(), builder.getRepeatedSfixed64List()); + assertEquals( + singletonList(1L), messageAfterBuild.getRepeatedSfixed64List()); + + message = builder.build(); + builder.addRepeatedSint32(1); + assertEquals(emptyList(), message.getRepeatedSint32List()); + assertEquals(singletonList(1), builder.getRepeatedSint32List()); + assertEquals(emptyList(), message.getRepeatedSint32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedSint32(); + assertEquals(emptyList(), builder.getRepeatedSint32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedSint32List()); + + message = builder.build(); + builder.addRepeatedSint64(1L); + assertEquals(emptyList(), message.getRepeatedSint64List()); + assertEquals(singletonList(1L), builder.getRepeatedSint64List()); + assertEquals(emptyList(), message.getRepeatedSint64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedSint64(); + assertEquals(emptyList(), builder.getRepeatedSint64List()); + assertEquals(singletonList(1L), messageAfterBuild.getRepeatedSint64List()); + + message = builder.build(); + builder.addRepeatedString("hi"); + assertEquals(emptyList(), message.getRepeatedStringList()); + assertEquals(singletonList("hi"), builder.getRepeatedStringList()); + assertEquals(emptyList(), message.getRepeatedStringList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedString(); + assertEquals(emptyList(), builder.getRepeatedStringList()); + assertEquals( + singletonList("hi"), messageAfterBuild.getRepeatedStringList()); + + message = builder.build(); + builder.addRepeatedStringPiece("hi"); + assertEquals(emptyList(), message.getRepeatedStringPieceList()); + assertEquals(singletonList("hi"), builder.getRepeatedStringPieceList()); + assertEquals(emptyList(), message.getRepeatedStringPieceList()); + messageAfterBuild = builder.build(); + builder.clearRepeatedStringPiece(); + assertEquals(emptyList(), builder.getRepeatedStringPieceList()); + assertEquals( + singletonList("hi"), messageAfterBuild.getRepeatedStringPieceList()); + + message = builder.build(); + builder.addRepeatedUint32(1); + assertEquals(emptyList(), message.getRepeatedUint32List()); + assertEquals(singletonList(1), builder.getRepeatedUint32List()); + assertEquals(emptyList(), message.getRepeatedUint32List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedUint32(); + assertEquals(emptyList(), builder.getRepeatedUint32List()); + assertEquals(singletonList(1), messageAfterBuild.getRepeatedUint32List()); + + message = builder.build(); + builder.addRepeatedUint64(1L); + assertEquals(emptyList(), message.getRepeatedUint64List()); + assertEquals(singletonList(1L), builder.getRepeatedUint64List()); + assertEquals(emptyList(), message.getRepeatedUint64List()); + messageAfterBuild = builder.build(); + builder.clearRepeatedUint64(); + assertEquals(emptyList(), builder.getRepeatedUint64List()); + assertEquals(singletonList(1L), messageAfterBuild.getRepeatedUint64List()); + + message = builder.build(); + builder.addRepeatedBool(true); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedBoolCount()); + builder.setRepeatedBool(0, false); + assertEquals(true, messageAfterBuild.getRepeatedBool(0)); + assertEquals(false, builder.getRepeatedBool(0)); + builder.clearRepeatedBool(); + + message = builder.build(); + builder.addRepeatedBytes(ByteString.copyFromUtf8("hi")); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedBytesCount()); + builder.setRepeatedBytes(0, ByteString.EMPTY); + assertEquals( + ByteString.copyFromUtf8("hi"), messageAfterBuild.getRepeatedBytes(0)); + assertEquals(ByteString.EMPTY, builder.getRepeatedBytes(0)); + builder.clearRepeatedBytes(); + + message = builder.build(); + builder.addRepeatedCord("hi"); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedCordCount()); + builder.setRepeatedCord(0, ""); + assertEquals("hi", messageAfterBuild.getRepeatedCord(0)); + assertEquals("", builder.getRepeatedCord(0)); + builder.clearRepeatedCord(); + message = builder.build(); + + builder.addRepeatedCordBytes(ByteString.copyFromUtf8("hi")); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedCordCount()); + builder.setRepeatedCord(0, ""); + assertEquals( + ByteString.copyFromUtf8("hi"), messageAfterBuild.getRepeatedCordBytes(0)); + assertEquals(ByteString.EMPTY, builder.getRepeatedCordBytes(0)); + builder.clearRepeatedCord(); + + message = builder.build(); + builder.addRepeatedDouble(1D); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedDoubleCount()); + builder.setRepeatedDouble(0, 0D); + assertEquals(1D, messageAfterBuild.getRepeatedDouble(0)); + assertEquals(0D, builder.getRepeatedDouble(0)); + builder.clearRepeatedDouble(); + + message = builder.build(); + builder.addRepeatedFixed32(1); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedFixed32Count()); + builder.setRepeatedFixed32(0, 0); + assertEquals(1, messageAfterBuild.getRepeatedFixed32(0)); + assertEquals(0, builder.getRepeatedFixed32(0)); + builder.clearRepeatedFixed32(); + + message = builder.build(); + builder.addRepeatedFixed64(1L); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedFixed64Count()); + builder.setRepeatedFixed64(0, 0L); + assertEquals(1L, messageAfterBuild.getRepeatedFixed64(0)); + assertEquals(0L, builder.getRepeatedFixed64(0)); + builder.clearRepeatedFixed64(); + + message = builder.build(); + builder.addRepeatedFloat(1F); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedFloatCount()); + builder.setRepeatedFloat(0, 0F); + assertEquals(1F, messageAfterBuild.getRepeatedFloat(0)); + assertEquals(0F, builder.getRepeatedFloat(0)); + builder.clearRepeatedFloat(); + + message = builder.build(); + builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedForeignEnumCount()); + builder.setRepeatedForeignEnum(0, ForeignEnumLite.FOREIGN_LITE_FOO); + assertEquals( + ForeignEnumLite.FOREIGN_LITE_BAR, + messageAfterBuild.getRepeatedForeignEnum(0)); + assertEquals( + ForeignEnumLite.FOREIGN_LITE_FOO, builder.getRepeatedForeignEnum(0)); + builder.clearRepeatedForeignEnum(); + + message = builder.build(); + builder.addRepeatedForeignMessage(foreignMessage); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedForeignMessageCount()); + builder.setRepeatedForeignMessage( + 0, ForeignMessageLite.getDefaultInstance()); + assertEquals( + foreignMessage, messageAfterBuild.getRepeatedForeignMessage(0)); + assertEquals( + ForeignMessageLite.getDefaultInstance(), + builder.getRepeatedForeignMessage(0)); + builder.clearRepeatedForeignMessage(); + + message = builder.build(); + builder.addRepeatedForeignMessage(foreignMessageBuilder); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedForeignMessageCount()); + builder.setRepeatedForeignMessage( + 0, ForeignMessageLite.getDefaultInstance()); + // LITE_RUNTIME doesn't implement equals so we compare on a property. + assertEquals(3, messageAfterBuild.getRepeatedForeignMessage(0).getC()); + assertEquals( + ForeignMessageLite.getDefaultInstance(), + builder.getRepeatedForeignMessage(0)); + builder.clearRepeatedForeignMessage(); + + message = builder.build(); + builder.addRepeatedForeignMessage(0, foreignMessage); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedForeignMessageCount()); + builder.setRepeatedForeignMessage(0, foreignMessageBuilder); + assertEquals( + foreignMessage, messageAfterBuild.getRepeatedForeignMessage(0)); + // LITE_RUNTIME doesn't implement equals so we compare on a property. + assertEquals(3, builder.getRepeatedForeignMessage(0).getC()); + builder.clearRepeatedForeignMessage(); + + message = builder.build(); + RepeatedGroup repeatedGroup = RepeatedGroup.newBuilder() + .setA(1) + .build(); + builder.addRepeatedGroup(repeatedGroup); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedGroupCount()); + builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance()); + assertEquals(repeatedGroup, messageAfterBuild.getRepeatedGroup(0)); + assertEquals( + RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0)); + builder.clearRepeatedGroup(); + + message = builder.build(); + builder.addRepeatedGroup(0, repeatedGroup); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedGroupCount()); + builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance()); + assertEquals(repeatedGroup, messageAfterBuild.getRepeatedGroup(0)); + assertEquals( + RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0)); + builder.clearRepeatedGroup(); + + message = builder.build(); + RepeatedGroup.Builder repeatedGroupBuilder = RepeatedGroup.newBuilder() + .setA(3); + builder.addRepeatedGroup(repeatedGroupBuilder); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedGroupCount()); + builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance()); + // LITE_RUNTIME doesn't implement equals so we compare on a property and + // ensure the property isn't set on repeatedGroup. + assertEquals(3, messageAfterBuild.getRepeatedGroup(0).getA()); + assertEquals( + RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0)); + builder.clearRepeatedGroup(); + + message = builder.build(); + builder.addRepeatedGroup(0, repeatedGroupBuilder); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedGroupCount()); + builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance()); + // LITE_RUNTIME doesn't implement equals so we compare on a property and + // ensure the property isn't set on repeatedGroup. + assertEquals(3, messageAfterBuild.getRepeatedGroup(0).getA()); + assertEquals( + RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0)); + builder.clearRepeatedGroup(); + + message = builder.build(); + builder.addRepeatedInt32(1); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedInt32Count()); + builder.setRepeatedInt32(0, 0); + assertEquals(1, messageAfterBuild.getRepeatedInt32(0)); + assertEquals(0, builder.getRepeatedInt32(0)); + builder.clearRepeatedInt32(); + + message = builder.build(); + builder.addRepeatedInt64(1L); + messageAfterBuild = builder.build(); + assertEquals(0L, message.getRepeatedInt64Count()); + builder.setRepeatedInt64(0, 0L); + assertEquals(1L, messageAfterBuild.getRepeatedInt64(0)); + assertEquals(0L, builder.getRepeatedInt64(0)); + builder.clearRepeatedInt64(); + + message = builder.build(); + builder.addRepeatedLazyMessage(nestedMessage); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedLazyMessageCount()); + builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance()); + assertEquals(nestedMessage, messageAfterBuild.getRepeatedLazyMessage(0)); + assertEquals( + NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0)); + builder.clearRepeatedLazyMessage(); + + message = builder.build(); + builder.addRepeatedLazyMessage(0, nestedMessage); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedLazyMessageCount()); + builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance()); + assertEquals(nestedMessage, messageAfterBuild.getRepeatedLazyMessage(0)); + assertEquals( + NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0)); + builder.clearRepeatedLazyMessage(); + + message = builder.build(); + builder.addRepeatedLazyMessage(nestedMessageBuilder); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedLazyMessageCount()); + builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance()); + // LITE_RUNTIME doesn't implement equals so we compare on a property and + // ensure the property isn't set on repeatedGroup. + assertEquals(3, messageAfterBuild.getRepeatedLazyMessage(0).getBb()); + assertEquals( + NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0)); + builder.clearRepeatedLazyMessage(); + + message = builder.build(); + builder.addRepeatedLazyMessage(0, nestedMessageBuilder); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedLazyMessageCount()); + builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance()); + // LITE_RUNTIME doesn't implement equals so we compare on a property and + // ensure the property isn't set on repeatedGroup. + assertEquals(3, messageAfterBuild.getRepeatedLazyMessage(0).getBb()); + assertEquals( + NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0)); + builder.clearRepeatedLazyMessage(); + + message = builder.build(); + builder.addRepeatedSfixed32(1); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedSfixed32Count()); + builder.setRepeatedSfixed32(0, 0); + assertEquals(1, messageAfterBuild.getRepeatedSfixed32(0)); + assertEquals(0, builder.getRepeatedSfixed32(0)); + builder.clearRepeatedSfixed32(); + + message = builder.build(); + builder.addRepeatedSfixed64(1L); + messageAfterBuild = builder.build(); + assertEquals(0L, message.getRepeatedSfixed64Count()); + builder.setRepeatedSfixed64(0, 0L); + assertEquals(1L, messageAfterBuild.getRepeatedSfixed64(0)); + assertEquals(0L, builder.getRepeatedSfixed64(0)); + builder.clearRepeatedSfixed64(); + + message = builder.build(); + builder.addRepeatedSint32(1); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedSint32Count()); + builder.setRepeatedSint32(0, 0); + assertEquals(1, messageAfterBuild.getRepeatedSint32(0)); + assertEquals(0, builder.getRepeatedSint32(0)); + builder.clearRepeatedSint32(); + + message = builder.build(); + builder.addRepeatedSint64(1L); + messageAfterBuild = builder.build(); + assertEquals(0L, message.getRepeatedSint64Count()); + builder.setRepeatedSint64(0, 0L); + assertEquals(1L, messageAfterBuild.getRepeatedSint64(0)); + assertEquals(0L, builder.getRepeatedSint64(0)); + builder.clearRepeatedSint64(); + + message = builder.build(); + builder.addRepeatedString("hi"); + messageAfterBuild = builder.build(); + assertEquals(0L, message.getRepeatedStringCount()); + builder.setRepeatedString(0, ""); + assertEquals("hi", messageAfterBuild.getRepeatedString(0)); + assertEquals("", builder.getRepeatedString(0)); + builder.clearRepeatedString(); + + message = builder.build(); + builder.addRepeatedStringBytes(ByteString.copyFromUtf8("hi")); + messageAfterBuild = builder.build(); + assertEquals(0L, message.getRepeatedStringCount()); + builder.setRepeatedString(0, ""); + assertEquals( + ByteString.copyFromUtf8("hi"), + messageAfterBuild.getRepeatedStringBytes(0)); + assertEquals(ByteString.EMPTY, builder.getRepeatedStringBytes(0)); + builder.clearRepeatedString(); + + message = builder.build(); + builder.addRepeatedStringPiece("hi"); + messageAfterBuild = builder.build(); + assertEquals(0L, message.getRepeatedStringPieceCount()); + builder.setRepeatedStringPiece(0, ""); + assertEquals("hi", messageAfterBuild.getRepeatedStringPiece(0)); + assertEquals("", builder.getRepeatedStringPiece(0)); + builder.clearRepeatedStringPiece(); + + message = builder.build(); + builder.addRepeatedStringPieceBytes(ByteString.copyFromUtf8("hi")); + messageAfterBuild = builder.build(); + assertEquals(0L, message.getRepeatedStringPieceCount()); + builder.setRepeatedStringPiece(0, ""); + assertEquals( + ByteString.copyFromUtf8("hi"), + messageAfterBuild.getRepeatedStringPieceBytes(0)); + assertEquals(ByteString.EMPTY, builder.getRepeatedStringPieceBytes(0)); + builder.clearRepeatedStringPiece(); + + message = builder.build(); + builder.addRepeatedUint32(1); + messageAfterBuild = builder.build(); + assertEquals(0, message.getRepeatedUint32Count()); + builder.setRepeatedUint32(0, 0); + assertEquals(1, messageAfterBuild.getRepeatedUint32(0)); + assertEquals(0, builder.getRepeatedUint32(0)); + builder.clearRepeatedUint32(); + + message = builder.build(); + builder.addRepeatedUint64(1L); + messageAfterBuild = builder.build(); + assertEquals(0L, message.getRepeatedUint64Count()); + builder.setRepeatedUint64(0, 0L); + assertEquals(1L, messageAfterBuild.getRepeatedUint64(0)); + assertEquals(0L, builder.getRepeatedUint64(0)); + builder.clearRepeatedUint64(); + + message = builder.build(); + assertEquals(0, message.getSerializedSize()); + builder.mergeFrom(TestAllTypesLite.newBuilder() + .setOptionalBool(true) + .build()); + assertEquals(0, message.getSerializedSize()); + assertEquals(true, builder.build().getOptionalBool()); + builder.clearOptionalBool(); + + message = builder.build(); + assertEquals(0, message.getSerializedSize()); + builder.mergeFrom(TestAllTypesLite.newBuilder() + .setOptionalBool(true) + .build()); + assertEquals(0, message.getSerializedSize()); + assertEquals(true, builder.build().getOptionalBool()); + builder.clear(); + assertEquals(0, builder.build().getSerializedSize()); + + message = builder.build(); + assertEquals(0, message.getSerializedSize()); + builder.mergeOptionalForeignMessage(foreignMessage); + assertEquals(0, message.getSerializedSize()); + assertEquals( + foreignMessage.getC(), + builder.build().getOptionalForeignMessage().getC()); + builder.clearOptionalForeignMessage(); + + message = builder.build(); + assertEquals(0, message.getSerializedSize()); + builder.mergeOptionalLazyMessage(nestedMessage); + assertEquals(0, message.getSerializedSize()); + assertEquals( + nestedMessage.getBb(), + builder.build().getOptionalLazyMessage().getBb()); + builder.clearOptionalLazyMessage(); + + message = builder.build(); + builder.setOneofString("hi"); + assertEquals( + OneofFieldCase.ONEOFFIELD_NOT_SET, message.getOneofFieldCase()); + assertEquals(OneofFieldCase.ONEOF_STRING, builder.getOneofFieldCase()); + assertEquals("hi", builder.getOneofString()); + messageAfterBuild = builder.build(); + assertEquals( + OneofFieldCase.ONEOF_STRING, messageAfterBuild.getOneofFieldCase()); + assertEquals("hi", messageAfterBuild.getOneofString()); + builder.setOneofUint32(1); + assertEquals( + OneofFieldCase.ONEOF_STRING, messageAfterBuild.getOneofFieldCase()); + assertEquals("hi", messageAfterBuild.getOneofString()); + assertEquals(OneofFieldCase.ONEOF_UINT32, builder.getOneofFieldCase()); + assertEquals(1, builder.getOneofUint32()); + + TestAllExtensionsLite.Builder extendableMessageBuilder = + TestAllExtensionsLite.newBuilder(); + TestAllExtensionsLite extendableMessage = extendableMessageBuilder.build(); + extendableMessageBuilder.setExtension( + UnittestLite.optionalInt32ExtensionLite, 1); + assertFalse(extendableMessage.hasExtension( + UnittestLite.optionalInt32ExtensionLite)); + extendableMessage = extendableMessageBuilder.build(); + assertEquals( + 1, (int) extendableMessageBuilder.getExtension( + UnittestLite.optionalInt32ExtensionLite)); + assertEquals( + 1, (int) extendableMessage.getExtension( + UnittestLite.optionalInt32ExtensionLite)); + extendableMessageBuilder.setExtension( + UnittestLite.optionalInt32ExtensionLite, 3); + assertEquals( + 3, (int) extendableMessageBuilder.getExtension( + UnittestLite.optionalInt32ExtensionLite)); + assertEquals( + 1, (int) extendableMessage.getExtension( + UnittestLite.optionalInt32ExtensionLite)); + extendableMessage = extendableMessageBuilder.build(); + assertEquals( + 3, (int) extendableMessageBuilder.getExtension( + UnittestLite.optionalInt32ExtensionLite)); + assertEquals( + 3, (int) extendableMessage.getExtension( + UnittestLite.optionalInt32ExtensionLite)); + + // No extension registry, so it should be in unknown fields. + extendableMessage = + TestAllExtensionsLite.parseFrom(extendableMessage.toByteArray()); + assertFalse(extendableMessage.hasExtension( + UnittestLite.optionalInt32ExtensionLite)); + + extendableMessageBuilder = extendableMessage.toBuilder(); + extendableMessageBuilder.mergeFrom(TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalFixed32ExtensionLite, 11) + .build()); + + extendableMessage = extendableMessageBuilder.build(); + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + UnittestLite.registerAllExtensions(registry); + extendableMessage = TestAllExtensionsLite.parseFrom( + extendableMessage.toByteArray(), registry); + + // The unknown field was preserved. + assertEquals( + 3, (int) extendableMessage.getExtension( + UnittestLite.optionalInt32ExtensionLite)); + assertEquals( + 11, (int) extendableMessage.getExtension( + UnittestLite.optionalFixed32ExtensionLite)); } } diff --git a/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java index 7b201a9d..958b6a7e 100644 --- a/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java +++ b/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java @@ -307,7 +307,8 @@ public class LiteralByteStringTest extends TestCase { public void testToString_returnsCanonicalEmptyString() throws UnsupportedEncodingException{ assertSame(classUnderTest + " must be the same string references", - ByteString.EMPTY.toString(Internal.UTF_8), new LiteralByteString(new byte[]{}).toString(Internal.UTF_8)); + ByteString.EMPTY.toString(Internal.UTF_8), + new LiteralByteString(new byte[]{}).toString(Internal.UTF_8)); } public void testToString_raisesException() throws UnsupportedEncodingException{ diff --git a/java/src/test/java/com/google/protobuf/LongArrayListTest.java b/java/src/test/java/com/google/protobuf/LongArrayListTest.java new file mode 100644 index 00000000..3a52ec7f --- /dev/null +++ b/java/src/test/java/com/google/protobuf/LongArrayListTest.java @@ -0,0 +1,473 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 static java.util.Arrays.asList; + +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; + +/** + * Tests for {@link LongArrayList}. + * + * @author dweis@google.com (Daniel Weis) + */ +public class LongArrayListTest extends TestCase { + + private static final LongArrayList UNARY_LIST = newImmutableLongArrayList(1); + private static final LongArrayList TERTIARY_LIST = + newImmutableLongArrayList(1, 2, 3); + + private LongArrayList list; + + @Override + protected void setUp() throws Exception { + list = new LongArrayList(); + } + + public void testEmptyListReturnsSameInstance() { + assertSame(LongArrayList.emptyList(), LongArrayList.emptyList()); + } + + public void testEmptyListIsImmutable() { + assertImmutable(LongArrayList.emptyList()); + } + + public void testMakeImmutable() { + list.addLong(2); + list.addLong(4); + list.addLong(6); + list.addLong(8); + list.makeImmutable(); + assertImmutable(list); + } + + public void testCopyConstructor() { + LongArrayList copy = new LongArrayList(TERTIARY_LIST); + assertEquals(TERTIARY_LIST, copy); + + copy = new LongArrayList(LongArrayList.emptyList()); + assertEquals(LongArrayList.emptyList(), copy); + + copy = new LongArrayList(asList(1L, 2L, 3L)); + assertEquals(asList(1L, 2L, 3L), copy); + + copy = new LongArrayList(Collections.<Long>emptyList()); + assertEquals(LongArrayList.emptyList(), copy); + } + + public void testModificationWithIteration() { + list.addAll(asList(1L, 2L, 3L, 4L)); + Iterator<Long> iterator = list.iterator(); + assertEquals(4, list.size()); + assertEquals(1, (long) list.get(0)); + assertEquals(1, (long) iterator.next()); + list.set(0, 1L); + assertEquals(2, (long) iterator.next()); + + list.remove(0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + + iterator = list.iterator(); + list.add(0, 0L); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + } + + public void testGet() { + assertEquals(1, (long) TERTIARY_LIST.get(0)); + assertEquals(2, (long) TERTIARY_LIST.get(1)); + assertEquals(3, (long) TERTIARY_LIST.get(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testGetLong() { + assertEquals(1, TERTIARY_LIST.getLong(0)); + assertEquals(2, TERTIARY_LIST.getLong(1)); + assertEquals(3, TERTIARY_LIST.getLong(2)); + + try { + TERTIARY_LIST.get(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + TERTIARY_LIST.get(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSize() { + assertEquals(0, LongArrayList.emptyList().size()); + assertEquals(1, UNARY_LIST.size()); + assertEquals(3, TERTIARY_LIST.size()); + + list.addLong(2); + list.addLong(4); + list.addLong(6); + list.addLong(8); + assertEquals(4, list.size()); + + list.remove(0); + assertEquals(3, list.size()); + + list.add(16L); + assertEquals(4, list.size()); + } + + public void testSet() { + list.addLong(2); + list.addLong(4); + + assertEquals(2, (long) list.set(0, 0L)); + assertEquals(0, list.getLong(0)); + + assertEquals(4, (long) list.set(1, 0L)); + assertEquals(0, list.getLong(1)); + + try { + list.set(-1, 0L); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.set(2, 0L); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testSetLong() { + list.addLong(2); + list.addLong(4); + + assertEquals(2, list.setLong(0, 0)); + assertEquals(0, list.getLong(0)); + + assertEquals(4, list.setLong(1, 0)); + assertEquals(0, list.getLong(1)); + + try { + list.setLong(-1, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.setLong(2, 0); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAdd() { + assertEquals(0, list.size()); + + assertTrue(list.add(2L)); + assertEquals(asList(2L), list); + + assertTrue(list.add(3L)); + list.add(0, 4L); + assertEquals(asList(4L, 2L, 3L), list); + + list.add(0, 1L); + list.add(0, 0L); + // Force a resize by getting up to 11 elements. + for (int i = 0; i < 6; i++) { + list.add(Long.valueOf(5 + i)); + } + assertEquals(asList(0L, 1L, 4L, 2L, 3L, 5L, 6L, 7L, 8L, 9L, 10L), list); + + try { + list.add(-1, 5L); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.add(4, 5L); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testAddLong() { + assertEquals(0, list.size()); + + list.addLong(2); + assertEquals(asList(2L), list); + + list.addLong(3); + assertEquals(asList(2L, 3L), list); + } + + public void testAddAll() { + assertEquals(0, list.size()); + + assertTrue(list.addAll(Collections.singleton(1L))); + assertEquals(1, list.size()); + assertEquals(1, (long) list.get(0)); + assertEquals(1, list.getLong(0)); + + assertTrue(list.addAll(asList(2L, 3L, 4L, 5L, 6L))); + assertEquals(asList(1L, 2L, 3L, 4L, 5L, 6L), list); + + assertTrue(list.addAll(TERTIARY_LIST)); + assertEquals(asList(1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L), list); + + assertFalse(list.addAll(Collections.<Long>emptyList())); + assertFalse(list.addAll(LongArrayList.emptyList())); + } + + public void testRemove() { + list.addAll(TERTIARY_LIST); + assertEquals(1, (long) list.remove(0)); + assertEquals(asList(2L, 3L), list); + + assertTrue(list.remove(3L)); + assertEquals(asList(2L), list); + + assertFalse(list.remove(3L)); + assertEquals(asList(2L), list); + + assertEquals(2, (long) list.remove(0)); + assertEquals(asList(), list); + + try { + list.remove(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + list.remove(0); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + private void assertImmutable(LongArrayList list) { + if (list.contains(1)) { + throw new RuntimeException("Cannot test the immutability of lists that contain 1."); + } + + try { + list.add(1L); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.add(0, 1L); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.<Long>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.singletonList(1L)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(new LongArrayList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.singleton(1L)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.<Long>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addLong(0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.clear(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.<Long>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.<Long>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, 0L); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.setLong(0, 0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + private static LongArrayList newImmutableLongArrayList(long... elements) { + LongArrayList list = new LongArrayList(); + for (long element : elements) { + list.addLong(element); + } + list.makeImmutable(); + return list; + } +} diff --git a/java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java index 22dbeb76..6cff689f 100644 --- a/java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java +++ b/java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java @@ -36,6 +36,11 @@ import map_lite_test.MapForProto2TestProto.TestUnknownEnumValue; import junit.framework.TestCase; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + /** * Unit tests for map fields. */ @@ -170,6 +175,140 @@ public class MapForProto2LiteTest extends TestCase { assertEquals(0, message.getStringToInt32Field().size()); } + public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { + // Since builders are implemented as a thin wrapper around a message + // instance, we attempt to verify that we can't cause the builder to modify + // a produced message. + + TestMap.Builder builder = TestMap.newBuilder(); + TestMap message = builder.build(); + Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); + intMap.put(1, 2); + assertTrue(message.getInt32ToInt32Field().isEmpty()); + message = builder.build(); + try { + intMap.put(2, 3); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + builder.getMutableInt32ToInt32Field().put(2, 3); + assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + } + + public void testMutableMapLifecycle() { + TestMap.Builder builder = TestMap.newBuilder(); + Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); + intMap.put(1, 2); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + try { + intMap.put(2, 3); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + builder.getMutableInt32ToInt32Field().put(2, 3); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + + Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField(); + enumMap.put(1, TestMap.EnumValue.BAR); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); + try { + enumMap.put(2, TestMap.EnumValue.FOO); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.FOO); + assertEquals( + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumField()); + + Map<Integer, String> stringMap = builder.getMutableInt32ToStringField(); + stringMap.put(1, "1"); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); + try { + stringMap.put(2, "2"); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + builder.getMutableInt32ToStringField().put(2, "2"); + assertEquals( + newMap(1, "1", 2, "2"), + builder.getInt32ToStringField()); + + Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField(); + messageMap.put(1, TestMap.MessageValue.getDefaultInstance()); + assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), + builder.build().getInt32ToMessageField()); + try { + messageMap.put(2, TestMap.MessageValue.getDefaultInstance()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), + builder.getInt32ToMessageField()); + builder.getMutableInt32ToMessageField().put(2, TestMap.MessageValue.getDefaultInstance()); + assertEquals( + newMap(1, TestMap.MessageValue.getDefaultInstance(), + 2, TestMap.MessageValue.getDefaultInstance()), + builder.getInt32ToMessageField()); + } + + public void testMutableMapLifecycle_collections() { + TestMap.Builder builder = TestMap.newBuilder(); + Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); + intMap.put(1, 2); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + try { + intMap.remove(2); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.entrySet().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.entrySet().iterator().remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.keySet().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.values().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.values().iterator().remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, 2), intMap); + assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + } + public void testGettersAndSetters() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); @@ -274,4 +413,26 @@ public class MapForProto2LiteTest extends TestCase { assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue()); } + + public void testIterationOrder() throws Exception { + TestMap.Builder builder = TestMap.newBuilder(); + setMapValues(builder); + TestMap message = builder.build(); + + assertEquals(Arrays.asList("1", "2", "3"), + new ArrayList<String>(message.getStringToInt32Field().keySet())); + } + + private static <K, V> Map<K, V> newMap(K key1, V value1) { + Map<K, V> map = new HashMap<K, V>(); + map.put(key1, value1); + return map; + } + + private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) { + Map<K, V> map = new HashMap<K, V>(); + map.put(key1, value1); + map.put(key2, value2); + return map; + } } diff --git a/java/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/src/test/java/com/google/protobuf/MapForProto2Test.java index 78cba1b4..7e984040 100644 --- a/java/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/src/test/java/com/google/protobuf/MapForProto2Test.java @@ -40,6 +40,7 @@ import map_test.MapForProto2TestProto.TestUnknownEnumValue; import junit.framework.TestCase; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -177,6 +178,116 @@ public class MapForProto2Test extends TestCase { assertEquals(0, message.getInt32ToMessageField().size()); assertEquals(0, message.getStringToInt32Field().size()); } + + public void testMutableMapLifecycle() { + TestMap.Builder builder = TestMap.newBuilder(); + Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); + intMap.put(1, 2); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + try { + intMap.put(2, 3); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + builder.getMutableInt32ToInt32Field().put(2, 3); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + + Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField(); + enumMap.put(1, TestMap.EnumValue.BAR); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); + try { + enumMap.put(2, TestMap.EnumValue.FOO); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.FOO); + assertEquals( + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumField()); + + Map<Integer, String> stringMap = builder.getMutableInt32ToStringField(); + stringMap.put(1, "1"); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); + try { + stringMap.put(2, "2"); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + builder.getMutableInt32ToStringField().put(2, "2"); + assertEquals( + newMap(1, "1", 2, "2"), + builder.getInt32ToStringField()); + + Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField(); + messageMap.put(1, TestMap.MessageValue.getDefaultInstance()); + assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), + builder.build().getInt32ToMessageField()); + try { + messageMap.put(2, TestMap.MessageValue.getDefaultInstance()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), + builder.getInt32ToMessageField()); + builder.getMutableInt32ToMessageField().put(2, TestMap.MessageValue.getDefaultInstance()); + assertEquals( + newMap(1, TestMap.MessageValue.getDefaultInstance(), + 2, TestMap.MessageValue.getDefaultInstance()), + builder.getInt32ToMessageField()); + } + + public void testMutableMapLifecycle_collections() { + TestMap.Builder builder = TestMap.newBuilder(); + Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); + intMap.put(1, 2); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + try { + intMap.remove(2); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.entrySet().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.entrySet().iterator().remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.keySet().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.values().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.values().iterator().remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, 2), intMap); + assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + } public void testGettersAndSetters() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); @@ -513,4 +624,41 @@ public class MapForProto2Test extends TestCase { assertEquals(2, message.getRecursiveMapField().get(1).getValue()); assertEquals(4, message.getRecursiveMapField().get(3).getValue()); } + + public void testIterationOrder() throws Exception { + TestMap.Builder builder = TestMap.newBuilder(); + setMapValues(builder); + TestMap message = builder.build(); + + assertEquals(Arrays.asList("1", "2", "3"), + new ArrayList<String>(message.getStringToInt32Field().keySet())); + } + + // Regression test for b/20494788 + public void testMapInitializationOrder() throws Exception { + assertEquals("RedactAllTypes", map_test.RedactAllTypes + .getDefaultInstance().getDescriptorForType().getName()); + + map_test.Message1.Builder builder = + map_test.Message1.newBuilder(); + builder.getMutableMapField().put("key", true); + map_test.Message1 message = builder.build(); + Message mapEntry = (Message) message.getRepeatedField( + message.getDescriptorForType().findFieldByName("map_field"), 0); + assertEquals(2, mapEntry.getAllFields().size()); + } + + private static <K, V> Map<K, V> newMap(K key1, V value1) { + Map<K, V> map = new HashMap<K, V>(); + map.put(key1, value1); + return map; + } + + private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) { + Map<K, V> map = new HashMap<K, V>(); + map.put(key1, value1); + map.put(key2, value2); + return map; + } } + diff --git a/java/src/test/java/com/google/protobuf/MapTest.java b/java/src/test/java/com/google/protobuf/MapTest.java index b8e67b7c..0509be15 100644 --- a/java/src/test/java/com/google/protobuf/MapTest.java +++ b/java/src/test/java/com/google/protobuf/MapTest.java @@ -41,6 +41,7 @@ import map_test.MapTestProto.TestOnChangeEventPropagation; import junit.framework.TestCase; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -178,7 +179,117 @@ public class MapTest extends TestCase { assertEquals(0, message.getInt32ToMessageField().size()); assertEquals(0, message.getStringToInt32Field().size()); } + + public void testMutableMapLifecycle() { + TestMap.Builder builder = TestMap.newBuilder(); + Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); + intMap.put(1, 2); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + try { + intMap.put(2, 3); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + builder.getMutableInt32ToInt32Field().put(2, 3); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + + Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField(); + enumMap.put(1, TestMap.EnumValue.BAR); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); + try { + enumMap.put(2, TestMap.EnumValue.FOO); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.FOO); + assertEquals( + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumField()); + + Map<Integer, String> stringMap = builder.getMutableInt32ToStringField(); + stringMap.put(1, "1"); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); + try { + stringMap.put(2, "2"); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + builder.getMutableInt32ToStringField().put(2, "2"); + assertEquals( + newMap(1, "1", 2, "2"), + builder.getInt32ToStringField()); + + Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField(); + messageMap.put(1, TestMap.MessageValue.getDefaultInstance()); + assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), + builder.build().getInt32ToMessageField()); + try { + messageMap.put(2, TestMap.MessageValue.getDefaultInstance()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), + builder.getInt32ToMessageField()); + builder.getMutableInt32ToMessageField().put(2, TestMap.MessageValue.getDefaultInstance()); + assertEquals( + newMap(1, TestMap.MessageValue.getDefaultInstance(), + 2, TestMap.MessageValue.getDefaultInstance()), + builder.getInt32ToMessageField()); + } + public void testMutableMapLifecycle_collections() { + TestMap.Builder builder = TestMap.newBuilder(); + Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); + intMap.put(1, 2); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + try { + intMap.remove(2); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.entrySet().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.entrySet().iterator().remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.keySet().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.values().remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + try { + intMap.values().iterator().remove(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + assertEquals(newMap(1, 2), intMap); + assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + } + public void testGettersAndSetters() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); @@ -611,4 +722,26 @@ public class MapTest extends TestCase { assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue()); } } + + public void testIterationOrder() throws Exception { + TestMap.Builder builder = TestMap.newBuilder(); + setMapValues(builder); + TestMap message = builder.build(); + + assertEquals(Arrays.asList("1", "2", "3"), + new ArrayList<String>(message.getStringToInt32Field().keySet())); + } + + private static <K, V> Map<K, V> newMap(K key1, V value1) { + Map<K, V> map = new HashMap<K, V>(); + map.put(key1, value1); + return map; + } + + private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) { + Map<K, V> map = new HashMap<K, V>(); + map.put(key1, value1); + map.put(key2, value2); + return map; + } } diff --git a/java/src/test/java/com/google/protobuf/ProtobufArrayListTest.java b/java/src/test/java/com/google/protobuf/ProtobufArrayListTest.java new file mode 100644 index 00000000..f9f5e9c7 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/ProtobufArrayListTest.java @@ -0,0 +1,303 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 static java.util.Arrays.asList; + +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.List; + +/** + * Tests for {@link ProtobufArrayList}. + */ +public class ProtobufArrayListTest extends TestCase { + + private static final ProtobufArrayList<Integer> UNARY_LIST = newImmutableProtoArrayList(1); + private static final ProtobufArrayList<Integer> TERTIARY_LIST = + newImmutableProtoArrayList(1, 2, 3); + + private ProtobufArrayList<Integer> list; + + @Override + protected void setUp() throws Exception { + list = new ProtobufArrayList<Integer>(); + } + + public void testEmptyListReturnsSameInstance() { + assertSame(ProtobufArrayList.emptyList(), ProtobufArrayList.emptyList()); + } + + public void testEmptyListIsImmutable() { + assertImmutable(ProtobufArrayList.<Integer>emptyList()); + } + + public void testCopyConstructor() { + ProtobufArrayList<Integer> copy = new ProtobufArrayList<Integer>(TERTIARY_LIST); + assertEquals(TERTIARY_LIST, copy); + + copy = new ProtobufArrayList<Integer>(IntArrayList.emptyList()); + assertEquals(ProtobufArrayList.emptyList(), copy); + + copy = new ProtobufArrayList<Integer>(asList(1, 2, 3)); + assertEquals(asList(1, 2, 3), copy); + + copy = new ProtobufArrayList<Integer>(Collections.<Integer>emptyList()); + assertEquals(ProtobufArrayList.emptyList(), copy); + } + + public void testModificationWithIteration() { + list.addAll(asList(1, 2, 3, 4)); + Iterator<Integer> iterator = list.iterator(); + assertEquals(4, list.size()); + assertEquals(1, (int) list.get(0)); + assertEquals(1, (int) iterator.next()); + + list.remove(0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + + iterator = list.iterator(); + list.set(0, 1); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + + iterator = list.iterator(); + list.add(0, 0); + try { + iterator.next(); + fail(); + } catch (ConcurrentModificationException e) { + // expected + } + } + + public void testMakeImmutable() { + list.add(2); + list.add(4); + list.add(6); + list.add(8); + list.makeImmutable(); + assertImmutable(list); + } + + public void testRemove() { + list.add(2); + list.add(4); + list.add(6); + + list.remove(1); + assertEquals(asList(2, 6), list); + + list.remove(1); + assertEquals(asList(2), list); + + list.remove(0); + assertEquals(asList(), list); + } + + public void testGet() { + list.add(2); + list.add(6); + + assertEquals(2, (int) list.get(0)); + assertEquals(6, (int) list.get(1)); + } + + public void testSet() { + list.add(2); + list.add(6); + + list.set(0, 1); + assertEquals(1, (int) list.get(0)); + list.set(1, 2); + assertEquals(2, (int) list.get(1)); + } + + private void assertImmutable(List<Integer> list) { + if (list.contains(1)) { + throw new RuntimeException("Cannot test the immutability of lists that contain 1."); + } + + try { + list.add(1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.add(0, 1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.<Integer>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(Collections.singletonList(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(new ProtobufArrayList<Integer>()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.addAll(0, Collections.<Integer>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.clear(); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(1); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.remove(new Object()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.<Double>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.removeAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.<Double>emptyList()); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(Collections.singleton(1)); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.retainAll(UNARY_LIST); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, 0); + fail(); + } catch (UnsupportedOperationException e) { + // expected + } + } + + private static ProtobufArrayList<Integer> newImmutableProtoArrayList(int... elements) { + ProtobufArrayList<Integer> list = new ProtobufArrayList<Integer>(); + for (int element : elements) { + list.add(element); + } + list.makeImmutable(); + return list; + } +} diff --git a/java/src/test/java/com/google/protobuf/field_presence_test.proto b/java/src/test/java/com/google/protobuf/field_presence_test.proto index 8d8ea8ef..8f3ca8c6 100644 --- a/java/src/test/java/com/google/protobuf/field_presence_test.proto +++ b/java/src/test/java/com/google/protobuf/field_presence_test.proto @@ -45,15 +45,15 @@ message TestAllTypes { BAZ = 2; } message NestedMessage { - optional int32 value = 1; + int32 value = 1; } - optional int32 optional_int32 = 1; - optional string optional_string = 2; - optional bytes optional_bytes = 3; - optional NestedEnum optional_nested_enum = 4; - optional NestedMessage optional_nested_message = 5; - optional protobuf_unittest.TestRequired optional_proto2_message = 6; + int32 optional_int32 = 1; + string optional_string = 2; + bytes optional_bytes = 3; + NestedEnum optional_nested_enum = 4; + NestedMessage optional_nested_message = 5; + protobuf_unittest.TestRequired optional_proto2_message = 6; oneof oneof_field { int32 oneof_int32 = 11; @@ -75,12 +75,12 @@ message TestAllTypes { } message TestOptionalFieldsOnly { - optional int32 optional_int32 = 1; - optional string optional_string = 2; - optional bytes optional_bytes = 3; - optional TestAllTypes.NestedEnum optional_nested_enum = 4; - optional TestAllTypes.NestedMessage optional_nested_message = 5; - optional protobuf_unittest.TestRequired optional_proto2_message = 6; + int32 optional_int32 = 1; + string optional_string = 2; + bytes optional_bytes = 3; + TestAllTypes.NestedEnum optional_nested_enum = 4; + TestAllTypes.NestedMessage optional_nested_message = 5; + protobuf_unittest.TestRequired optional_proto2_message = 6; } message TestRepeatedFieldsOnly { diff --git a/java/src/test/java/com/google/protobuf/map_initialization_order_test.proto b/java/src/test/java/com/google/protobuf/map_initialization_order_test.proto new file mode 100644 index 00000000..b02ac599 --- /dev/null +++ b/java/src/test/java/com/google/protobuf/map_initialization_order_test.proto @@ -0,0 +1,61 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +// Regression test for a map initilaization order bug. The bug only manifests +// when: +// 1. A message contains map fields and is also extendable. +// 2. There is a file-level extension defined in the same file referencing +// the above message as the extension type. +// 3. The program executes in the following order: +// a. getDescriptor() is called on another message in the same file. +// b. use protobuf reflection to access the map field. +// The symptom is a NullPointerException being thrown. +syntax = "proto2"; + +package map_test; + +option java_package = "map_test"; +option java_outer_classname = "MapInitializationOrderTest"; +option java_multiple_files = true; + +// Mirrors the structure of +// javatests/com/google/cloud/common/logging/logging_test.proto. + +message Message1 { + map<string, bool> map_field = 1; + extensions 1000 to max; +} + +extend Message1 { + optional Message1 recursive_extension = 1001; +} + +message RedactAllTypes { +} diff --git a/java/src/test/java/com/google/protobuf/map_test.proto b/java/src/test/java/com/google/protobuf/map_test.proto index bf692c22..2f7709be 100644 --- a/java/src/test/java/com/google/protobuf/map_test.proto +++ b/java/src/test/java/com/google/protobuf/map_test.proto @@ -39,7 +39,7 @@ option java_generate_equals_and_hash = true; message TestMap { message MessageValue { - optional int32 value = 1; + int32 value = 1; } enum EnumValue { FOO = 0; @@ -60,5 +60,5 @@ message TestMap { // propagate the onChange event and mark its parent dirty when a change // is made to a map field. message TestOnChangeEventPropagation { - optional TestMap optional_message = 1; + TestMap optional_message = 1; } |