/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.collect; import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES; import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE; import static java.util.Arrays.asList; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.Helpers; import com.google.common.collect.testing.ListTestSuiteBuilder; import com.google.common.collect.testing.MinimalCollection; import com.google.common.collect.testing.MinimalIterable; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.google.ListGenerators.BuilderAddAllListGenerator; import com.google.common.collect.testing.google.ListGenerators.BuilderReversedListGenerator; import com.google.common.collect.testing.google.ListGenerators.ImmutableListHeadSubListGenerator; import com.google.common.collect.testing.google.ListGenerators.ImmutableListMiddleSubListGenerator; import com.google.common.collect.testing.google.ListGenerators.ImmutableListOfGenerator; import com.google.common.collect.testing.google.ListGenerators.ImmutableListTailSubListGenerator; import com.google.common.collect.testing.google.ListGenerators.UnhashableElementsImmutableListGenerator; import com.google.common.collect.testing.testers.ListHashCodeTester; import com.google.common.testing.CollectorTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Unit test for {@link ImmutableList}. * * @author Kevin Bourrillion * @author George van den Driessche * @author Jared Levy */ @GwtCompatible(emulated = true) public class ImmutableListTest extends TestCase { @GwtIncompatible // suite public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest( ListTestSuiteBuilder.using(new ImmutableListOfGenerator()) .named("ImmutableList") .withFeatures(CollectionSize.ANY, SERIALIZABLE, ALLOWS_NULL_QUERIES) .createTestSuite()); suite.addTest( ListTestSuiteBuilder.using(new BuilderAddAllListGenerator()) .named("ImmutableList, built with Builder.add") .withFeatures(CollectionSize.ANY, SERIALIZABLE, ALLOWS_NULL_QUERIES) .createTestSuite()); suite.addTest( ListTestSuiteBuilder.using(new BuilderAddAllListGenerator()) .named("ImmutableList, built with Builder.addAll") .withFeatures(CollectionSize.ANY, SERIALIZABLE, ALLOWS_NULL_QUERIES) .createTestSuite()); suite.addTest( ListTestSuiteBuilder.using(new BuilderReversedListGenerator()) .named("ImmutableList, reversed") .withFeatures(CollectionSize.ANY, SERIALIZABLE, ALLOWS_NULL_QUERIES) .createTestSuite()); suite.addTest( ListTestSuiteBuilder.using(new ImmutableListHeadSubListGenerator()) .named("ImmutableList, head subList") .withFeatures(CollectionSize.ANY, SERIALIZABLE, ALLOWS_NULL_QUERIES) .createTestSuite()); suite.addTest( ListTestSuiteBuilder.using(new ImmutableListTailSubListGenerator()) .named("ImmutableList, tail subList") .withFeatures(CollectionSize.ANY, SERIALIZABLE, ALLOWS_NULL_QUERIES) .createTestSuite()); suite.addTest( ListTestSuiteBuilder.using(new ImmutableListMiddleSubListGenerator()) .named("ImmutableList, middle subList") .withFeatures(CollectionSize.ANY, SERIALIZABLE, ALLOWS_NULL_QUERIES) .createTestSuite()); suite.addTest( ListTestSuiteBuilder.using(new UnhashableElementsImmutableListGenerator()) .suppressing(ListHashCodeTester.getHashCodeMethod()) .named("ImmutableList, unhashable values") .withFeatures(CollectionSize.ANY, ALLOWS_NULL_QUERIES) .createTestSuite()); return suite; } // Creation tests public void testCreation_noArgs() { List list = ImmutableList.of(); assertEquals(Collections.emptyList(), list); } public void testCreation_oneElement() { List list = ImmutableList.of("a"); assertEquals(Collections.singletonList("a"), list); } public void testCreation_twoElements() { List list = ImmutableList.of("a", "b"); assertEquals(Lists.newArrayList("a", "b"), list); } public void testCreation_threeElements() { List list = ImmutableList.of("a", "b", "c"); assertEquals(Lists.newArrayList("a", "b", "c"), list); } public void testCreation_fourElements() { List list = ImmutableList.of("a", "b", "c", "d"); assertEquals(Lists.newArrayList("a", "b", "c", "d"), list); } public void testCreation_fiveElements() { List list = ImmutableList.of("a", "b", "c", "d", "e"); assertEquals(Lists.newArrayList("a", "b", "c", "d", "e"), list); } public void testCreation_sixElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f"); assertEquals(Lists.newArrayList("a", "b", "c", "d", "e", "f"), list); } public void testCreation_sevenElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g"); assertEquals(Lists.newArrayList("a", "b", "c", "d", "e", "f", "g"), list); } public void testCreation_eightElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g", "h"); assertEquals(Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h"), list); } public void testCreation_nineElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g", "h", "i"); assertEquals(Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h", "i"), list); } public void testCreation_tenElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"); assertEquals(Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"), list); } public void testCreation_elevenElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"); assertEquals(Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"), list); } // Varargs versions public void testCreation_twelveElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"); assertEquals( Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"), list); } public void testCreation_thirteenElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"); assertEquals( Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"), list); } public void testCreation_fourteenElements() { List list = ImmutableList.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"); assertEquals( Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"), list); } public void testCreation_singletonNull() { try { ImmutableList.of((String) null); fail(); } catch (NullPointerException expected) { } } public void testCreation_withNull() { try { ImmutableList.of("a", null, "b"); fail(); } catch (NullPointerException expected) { } } public void testCreation_generic() { List a = ImmutableList.of("a"); // only verify that there is no compile warning ImmutableList> unused = ImmutableList.of(a, a); } public void testCreation_arrayOfArray() { String[] array = new String[] {"a"}; List list = ImmutableList.of(array); assertEquals(Collections.singletonList(array), list); } public void testCopyOf_emptyArray() { String[] array = new String[0]; List list = ImmutableList.copyOf(array); assertEquals(Collections.emptyList(), list); } public void testCopyOf_arrayOfOneElement() { String[] array = new String[] {"a"}; List list = ImmutableList.copyOf(array); assertEquals(Collections.singletonList("a"), list); } public void testCopyOf_nullArray() { try { ImmutableList.copyOf((String[]) null); fail(); } catch (NullPointerException expected) { } } public void testCopyOf_arrayContainingOnlyNull() { String[] array = new String[] {null}; try { ImmutableList.copyOf(array); fail(); } catch (NullPointerException expected) { } } public void testCopyOf_collection_empty() { // "" is required to work around a javac 1.5 bug. Collection c = MinimalCollection.of(); List list = ImmutableList.copyOf(c); assertEquals(Collections.emptyList(), list); } public void testCopyOf_collection_oneElement() { Collection c = MinimalCollection.of("a"); List list = ImmutableList.copyOf(c); assertEquals(Collections.singletonList("a"), list); } public void testCopyOf_collection_general() { Collection c = MinimalCollection.of("a", "b", "a"); List list = ImmutableList.copyOf(c); assertEquals(asList("a", "b", "a"), list); List mutableList = asList("a", "b"); list = ImmutableList.copyOf(mutableList); mutableList.set(0, "c"); assertEquals(asList("a", "b"), list); } public void testCopyOf_collectionContainingNull() { Collection c = MinimalCollection.of("a", null, "b"); try { ImmutableList.copyOf(c); fail(); } catch (NullPointerException expected) { } } public void testCopyOf_iterator_empty() { Iterator iterator = Iterators.emptyIterator(); List list = ImmutableList.copyOf(iterator); assertEquals(Collections.emptyList(), list); } public void testCopyOf_iterator_oneElement() { Iterator iterator = Iterators.singletonIterator("a"); List list = ImmutableList.copyOf(iterator); assertEquals(Collections.singletonList("a"), list); } public void testCopyOf_iterator_general() { Iterator iterator = asList("a", "b", "a").iterator(); List list = ImmutableList.copyOf(iterator); assertEquals(asList("a", "b", "a"), list); } public void testCopyOf_iteratorContainingNull() { Iterator iterator = asList("a", null, "b").iterator(); try { ImmutableList.copyOf(iterator); fail(); } catch (NullPointerException expected) { } } public void testCopyOf_iteratorNull() { try { ImmutableList.copyOf((Iterator) null); fail(); } catch (NullPointerException expected) { } } public void testCopyOf_concurrentlyMutating() { List sample = Lists.newArrayList("a", "b", "c"); for (int delta : new int[] {-1, 0, 1}) { for (int i = 0; i < sample.size(); i++) { Collection misleading = Helpers.misleadingSizeCollection(delta); List expected = sample.subList(0, i); misleading.addAll(expected); assertEquals(expected, ImmutableList.copyOf(misleading)); assertEquals(expected, ImmutableList.copyOf((Iterable) misleading)); } } } private static class CountingIterable implements Iterable { int count = 0; @Override public Iterator iterator() { count++; return asList("a", "b", "a").iterator(); } } public void testCopyOf_plainIterable() { CountingIterable iterable = new CountingIterable(); List list = ImmutableList.copyOf(iterable); assertEquals(asList("a", "b", "a"), list); } public void testCopyOf_plainIterable_iteratesOnce() { CountingIterable iterable = new CountingIterable(); ImmutableList unused = ImmutableList.copyOf(iterable); assertEquals(1, iterable.count); } public void testCopyOf_shortcut_empty() { Collection c = ImmutableList.of(); assertSame(c, ImmutableList.copyOf(c)); } public void testCopyOf_shortcut_singleton() { Collection c = ImmutableList.of("a"); assertSame(c, ImmutableList.copyOf(c)); } public void testCopyOf_shortcut_immutableList() { Collection c = ImmutableList.of("a", "b", "c"); assertSame(c, ImmutableList.copyOf(c)); } public void testBuilderAddArrayHandlesNulls() { String[] elements = {"a", null, "b"}; ImmutableList.Builder builder = ImmutableList.builder(); try { builder.add(elements); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } ImmutableList result = builder.build(); /* * Maybe it rejects all elements, or maybe it adds "a" before failing. * Either way is fine with us. */ if (result.isEmpty()) { return; } assertTrue(ImmutableList.of("a").equals(result)); assertEquals(1, result.size()); } public void testBuilderAddCollectionHandlesNulls() { List elements = Arrays.asList("a", null, "b"); ImmutableList.Builder builder = ImmutableList.builder(); try { builder.addAll(elements); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } ImmutableList result = builder.build(); assertEquals(ImmutableList.of("a"), result); assertEquals(1, result.size()); } public void testSortedCopyOf_natural() { Collection c = MinimalCollection.of(4, 16, 10, -1, 5); ImmutableList list = ImmutableList.sortedCopyOf(c); assertEquals(asList(-1, 4, 5, 10, 16), list); } public void testSortedCopyOf_natural_empty() { Collection c = MinimalCollection.of(); ImmutableList list = ImmutableList.sortedCopyOf(c); assertEquals(asList(), list); } public void testSortedCopyOf_natural_singleton() { Collection c = MinimalCollection.of(100); ImmutableList list = ImmutableList.sortedCopyOf(c); assertEquals(asList(100), list); } public void testSortedCopyOf_natural_containsNull() { Collection c = MinimalCollection.of(1, 3, null, 2); try { ImmutableList.sortedCopyOf(c); fail("Expected NPE"); } catch (NullPointerException expected) { } } public void testSortedCopyOf() { Collection c = MinimalCollection.of("a", "b", "A", "c"); List list = ImmutableList.sortedCopyOf(String.CASE_INSENSITIVE_ORDER, c); assertEquals(asList("a", "A", "b", "c"), list); } public void testSortedCopyOf_empty() { Collection c = MinimalCollection.of(); List list = ImmutableList.sortedCopyOf(String.CASE_INSENSITIVE_ORDER, c); assertEquals(asList(), list); } public void testSortedCopyOf_singleton() { Collection c = MinimalCollection.of("a"); List list = ImmutableList.sortedCopyOf(String.CASE_INSENSITIVE_ORDER, c); assertEquals(asList("a"), list); } public void testSortedCopyOf_containsNull() { Collection c = MinimalCollection.of("a", "b", "A", null, "c"); try { ImmutableList.sortedCopyOf(String.CASE_INSENSITIVE_ORDER, c); fail("Expected NPE"); } catch (NullPointerException expected) { } } public void testToImmutableList() { CollectorTester.of(ImmutableList.toImmutableList()) .expectCollects(ImmutableList.of("a", "b", "c", "d"), "a", "b", "c", "d"); } // Basic tests @GwtIncompatible // NullPointerTester @AndroidIncompatible // see ImmutableTableTest.testNullPointerInstance public void testNullPointers() { NullPointerTester tester = new NullPointerTester(); tester.testAllPublicStaticMethods(ImmutableList.class); tester.testAllPublicInstanceMethods(ImmutableList.of(1, 2, 3)); } @GwtIncompatible // SerializableTester public void testSerialization_empty() { Collection c = ImmutableList.of(); assertSame(c, SerializableTester.reserialize(c)); } @GwtIncompatible // SerializableTester public void testSerialization_singleton() { Collection c = ImmutableList.of("a"); SerializableTester.reserializeAndAssert(c); } @GwtIncompatible // SerializableTester public void testSerialization_multiple() { Collection c = ImmutableList.of("a", "b", "c"); SerializableTester.reserializeAndAssert(c); } public void testEquals_immutableList() { Collection c = ImmutableList.of("a", "b", "c"); assertTrue(c.equals(ImmutableList.of("a", "b", "c"))); assertFalse(c.equals(ImmutableList.of("a", "c", "b"))); assertFalse(c.equals(ImmutableList.of("a", "b"))); assertFalse(c.equals(ImmutableList.of("a", "b", "c", "d"))); } public void testBuilderAdd() { ImmutableList list = new ImmutableList.Builder().add("a").add("b").add("a").add("c").build(); assertEquals(asList("a", "b", "a", "c"), list); } @GwtIncompatible("Builder impl") public void testBuilderForceCopy() { ImmutableList.Builder builder = ImmutableList.builder(); Object[] prevArray = null; for (int i = 0; i < 10; i++) { builder.add(i); assertNotSame(builder.contents, prevArray); prevArray = builder.contents; ImmutableList unused = builder.build(); } } @GwtIncompatible public void testBuilderExactlySizedReusesArray() { ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(10); Object[] builderArray = builder.contents; for (int i = 0; i < 10; i++) { builder.add(i); } Object[] builderArrayAfterAdds = builder.contents; RegularImmutableList list = (RegularImmutableList) builder.build(); Object[] listInternalArray = list.array; assertSame(builderArray, builderArrayAfterAdds); assertSame(builderArray, listInternalArray); } public void testBuilderAdd_varargs() { ImmutableList list = new ImmutableList.Builder().add("a", "b", "a", "c").build(); assertEquals(asList("a", "b", "a", "c"), list); } public void testBuilderAddAll_iterable() { List a = asList("a", "b"); List b = asList("c", "d"); ImmutableList list = new ImmutableList.Builder().addAll(a).addAll(b).build(); assertEquals(asList("a", "b", "c", "d"), list); b.set(0, "f"); assertEquals(asList("a", "b", "c", "d"), list); } public void testBuilderAddAll_iterator() { List a = asList("a", "b"); List b = asList("c", "d"); ImmutableList list = new ImmutableList.Builder().addAll(a.iterator()).addAll(b.iterator()).build(); assertEquals(asList("a", "b", "c", "d"), list); b.set(0, "f"); assertEquals(asList("a", "b", "c", "d"), list); } public void testComplexBuilder() { List colorElem = asList(0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF); ImmutableList.Builder webSafeColorsBuilder = ImmutableList.builder(); for (Integer red : colorElem) { for (Integer green : colorElem) { for (Integer blue : colorElem) { webSafeColorsBuilder.add((red << 16) + (green << 8) + blue); } } } ImmutableList webSafeColors = webSafeColorsBuilder.build(); assertEquals(216, webSafeColors.size()); Integer[] webSafeColorArray = webSafeColors.toArray(new Integer[webSafeColors.size()]); assertEquals(0x000000, (int) webSafeColorArray[0]); assertEquals(0x000033, (int) webSafeColorArray[1]); assertEquals(0x000066, (int) webSafeColorArray[2]); assertEquals(0x003300, (int) webSafeColorArray[6]); assertEquals(0x330000, (int) webSafeColorArray[36]); assertEquals(0x000066, (int) webSafeColors.get(2)); assertEquals(0x003300, (int) webSafeColors.get(6)); ImmutableList addedColor = webSafeColorsBuilder.add(0x00BFFF).build(); assertEquals( "Modifying the builder should not have changed any already" + " built sets", 216, webSafeColors.size()); assertEquals("the new array should be one bigger than webSafeColors", 217, addedColor.size()); Integer[] appendColorArray = addedColor.toArray(new Integer[addedColor.size()]); assertEquals(0x00BFFF, (int) appendColorArray[216]); } public void testBuilderAddHandlesNullsCorrectly() { ImmutableList.Builder builder = ImmutableList.builder(); try { builder.add((String) null); fail("expected NullPointerException"); } catch (NullPointerException expected) { } try { builder.add((String[]) null); fail("expected NullPointerException"); } catch (NullPointerException expected) { } try { builder.add("a", null, "b"); fail("expected NullPointerException"); } catch (NullPointerException expected) { } } public void testBuilderAddAllHandlesNullsCorrectly() { ImmutableList.Builder builder = ImmutableList.builder(); try { builder.addAll((Iterable) null); fail("expected NullPointerException"); } catch (NullPointerException expected) { } try { builder.addAll((Iterator) null); fail("expected NullPointerException"); } catch (NullPointerException expected) { } builder = ImmutableList.builder(); List listWithNulls = asList("a", null, "b"); try { builder.addAll(listWithNulls); fail("expected NullPointerException"); } catch (NullPointerException expected) { } builder = ImmutableList.builder(); Iterator iteratorWithNulls = asList("a", null, "b").iterator(); try { builder.addAll(iteratorWithNulls); fail("expected NullPointerException"); } catch (NullPointerException expected) { } Iterable iterableWithNulls = MinimalIterable.of("a", null, "b"); try { builder.addAll(iterableWithNulls); fail("expected NullPointerException"); } catch (NullPointerException expected) { } } public void testAsList() { ImmutableList list = ImmutableList.of("a", "b"); assertSame(list, list.asList()); } }