blob: 553b693584a4decbeea917b6c37cee7765e4c378 [file] [log] [blame]
/*
* Copyright (C) 2008 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.testing.testers;
import static com.google.common.collect.testing.Helpers.getMethod;
import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_REMOVE_WITH_INDEX;
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SET;
import static java.util.Collections.emptyList;
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.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.ListFeature;
import com.google.common.testing.SerializableTester;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.junit.Ignore;
/**
* A generic JUnit test which tests {@code subList()} operations on a list. Can't be invoked
* directly; please see {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
*
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
@GwtCompatible(emulated = true)
@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
public class ListSubListTester<E> extends AbstractListTester<E> {
public void testSubList_startNegative() {
try {
getList().subList(-1, 0);
fail("subList(-1, 0) should throw");
} catch (IndexOutOfBoundsException expected) {
}
}
public void testSubList_endTooLarge() {
try {
getList().subList(0, getNumElements() + 1);
fail("subList(0, size + 1) should throw");
} catch (IndexOutOfBoundsException expected) {
}
}
public void testSubList_startGreaterThanEnd() {
try {
getList().subList(1, 0);
fail("subList(1, 0) should throw");
} catch (IndexOutOfBoundsException expected) {
} catch (IllegalArgumentException expected) {
/*
* The subList() docs claim that this should be an
* IndexOutOfBoundsException, but many JDK implementations throw
* IllegalArgumentException:
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4506427
*/
}
}
public void testSubList_empty() {
assertEquals("subList(0, 0) should be empty", emptyList(), getList().subList(0, 0));
}
public void testSubList_entireList() {
assertEquals(
"subList(0, size) should be equal to the original list",
getList(),
getList().subList(0, getNumElements()));
}
@ListFeature.Require(SUPPORTS_REMOVE_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
public void testSubList_subListRemoveAffectsOriginal() {
List<E> subList = getList().subList(0, 1);
subList.remove(0);
List<E> expected = Arrays.asList(createSamplesArray()).subList(1, getNumElements());
expectContents(expected);
}
@ListFeature.Require(SUPPORTS_REMOVE_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
public void testSubList_subListClearAffectsOriginal() {
List<E> subList = getList().subList(0, 1);
subList.clear();
List<E> expected = Arrays.asList(createSamplesArray()).subList(1, getNumElements());
expectContents(expected);
}
@ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
public void testSubList_subListAddAffectsOriginal() {
List<E> subList = getList().subList(0, 0);
subList.add(e3());
expectAdded(0, e3());
}
@ListFeature.Require(SUPPORTS_SET)
@CollectionSize.Require(absent = ZERO)
public void testSubList_subListSetAffectsOriginal() {
List<E> subList = getList().subList(0, 1);
subList.set(0, e3());
List<E> expected = Helpers.copyToList(createSamplesArray());
expected.set(0, e3());
expectContents(expected);
}
@ListFeature.Require(SUPPORTS_SET)
@CollectionSize.Require(absent = ZERO)
public void testSubList_originalListSetAffectsSubList() {
List<E> subList = getList().subList(0, 1);
getList().set(0, e3());
assertEquals(
"A set() call to a list after a sublist has been created "
+ "should be reflected in the sublist",
Collections.singletonList(e3()),
subList);
}
@ListFeature.Require(SUPPORTS_REMOVE_WITH_INDEX)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_subListRemoveAffectsOriginalLargeList() {
List<E> subList = getList().subList(1, 3);
subList.remove(e2());
List<E> expected = Helpers.copyToList(createSamplesArray());
expected.remove(2);
expectContents(expected);
}
@ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_subListAddAtIndexAffectsOriginalLargeList() {
List<E> subList = getList().subList(2, 3);
subList.add(0, e3());
expectAdded(2, e3());
}
@ListFeature.Require(SUPPORTS_SET)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_subListSetAffectsOriginalLargeList() {
List<E> subList = getList().subList(1, 2);
subList.set(0, e3());
List<E> expected = Helpers.copyToList(createSamplesArray());
expected.set(1, e3());
expectContents(expected);
}
@ListFeature.Require(SUPPORTS_SET)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_originalListSetAffectsSubListLargeList() {
List<E> subList = getList().subList(1, 3);
getList().set(1, e3());
assertEquals(
"A set() call to a list after a sublist has been created "
+ "should be reflected in the sublist",
Arrays.asList(e3(), e2()),
subList);
}
public void testSubList_ofSubListEmpty() {
List<E> subList = getList().subList(0, 0).subList(0, 0);
assertEquals("subList(0, 0).subList(0, 0) should be an empty list", emptyList(), subList);
}
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_ofSubListNonEmpty() {
List<E> subList = getList().subList(0, 2).subList(1, 2);
assertEquals(
"subList(0, 2).subList(1, 2) "
+ "should be a single-element list of the element at index 1",
Collections.singletonList(getOrderedElements().get(1)),
subList);
}
@CollectionSize.Require(absent = {ZERO})
public void testSubList_size() {
List<E> list = getList();
int size = getNumElements();
assertEquals(size, list.subList(0, size).size());
assertEquals(size - 1, list.subList(0, size - 1).size());
assertEquals(size - 1, list.subList(1, size).size());
assertEquals(0, list.subList(size, size).size());
assertEquals(0, list.subList(0, 0).size());
}
@CollectionSize.Require(absent = {ZERO})
public void testSubList_isEmpty() {
List<E> list = getList();
int size = getNumElements();
for (List<E> subList :
Arrays.asList(
list.subList(0, size),
list.subList(0, size - 1),
list.subList(1, size),
list.subList(0, 0),
list.subList(size, size))) {
assertEquals(subList.size() == 0, subList.isEmpty());
}
}
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_get() {
List<E> list = getList();
int size = getNumElements();
List<E> copy = list.subList(0, size);
List<E> head = list.subList(0, size - 1);
List<E> tail = list.subList(1, size);
assertEquals(list.get(0), copy.get(0));
assertEquals(list.get(size - 1), copy.get(size - 1));
assertEquals(list.get(1), tail.get(0));
assertEquals(list.get(size - 1), tail.get(size - 2));
assertEquals(list.get(0), head.get(0));
assertEquals(list.get(size - 2), head.get(size - 2));
for (List<E> subList : Arrays.asList(copy, head, tail)) {
for (int index : Arrays.asList(-1, subList.size())) {
try {
subList.get(index);
fail("expected IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException expected) {
}
}
}
}
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_contains() {
List<E> list = getList();
int size = getNumElements();
List<E> copy = list.subList(0, size);
List<E> head = list.subList(0, size - 1);
List<E> tail = list.subList(1, size);
assertTrue(copy.contains(list.get(0)));
assertTrue(head.contains(list.get(0)));
assertTrue(tail.contains(list.get(1)));
// The following assumes all elements are distinct.
assertTrue(copy.contains(list.get(size - 1)));
assertTrue(head.contains(list.get(size - 2)));
assertTrue(tail.contains(list.get(size - 1)));
assertFalse(head.contains(list.get(size - 1)));
assertFalse(tail.contains(list.get(0)));
}
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_indexOf() {
List<E> list = getList();
int size = getNumElements();
List<E> copy = list.subList(0, size);
List<E> head = list.subList(0, size - 1);
List<E> tail = list.subList(1, size);
assertEquals(0, copy.indexOf(list.get(0)));
assertEquals(0, head.indexOf(list.get(0)));
assertEquals(0, tail.indexOf(list.get(1)));
// The following assumes all elements are distinct.
assertEquals(size - 1, copy.indexOf(list.get(size - 1)));
assertEquals(size - 2, head.indexOf(list.get(size - 2)));
assertEquals(size - 2, tail.indexOf(list.get(size - 1)));
assertEquals(-1, head.indexOf(list.get(size - 1)));
assertEquals(-1, tail.indexOf(list.get(0)));
}
@CollectionSize.Require(absent = {ZERO, ONE})
public void testSubList_lastIndexOf() {
List<E> list = getList();
int size = list.size();
List<E> copy = list.subList(0, size);
List<E> head = list.subList(0, size - 1);
List<E> tail = list.subList(1, size);
assertEquals(size - 1, copy.lastIndexOf(list.get(size - 1)));
assertEquals(size - 2, head.lastIndexOf(list.get(size - 2)));
assertEquals(size - 2, tail.lastIndexOf(list.get(size - 1)));
// The following assumes all elements are distinct.
assertEquals(0, copy.lastIndexOf(list.get(0)));
assertEquals(0, head.lastIndexOf(list.get(0)));
assertEquals(0, tail.lastIndexOf(list.get(1)));
assertEquals(-1, head.lastIndexOf(list.get(size - 1)));
assertEquals(-1, tail.lastIndexOf(list.get(0)));
}
@CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
public void testReserializeWholeSubList() {
SerializableTester.reserializeAndAssert(getList().subList(0, getNumElements()));
}
@CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
public void testReserializeEmptySubList() {
SerializableTester.reserializeAndAssert(getList().subList(0, 0));
}
@CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testReserializeSubList() {
SerializableTester.reserializeAndAssert(getList().subList(0, 2));
}
/**
* Returns the {@link Method} instance for {@link #testSubList_originalListSetAffectsSubList()} so
* that tests of {@link CopyOnWriteArrayList} can suppress them with {@code
* FeatureSpecificTestSuiteBuilder.suppressing()} until <a
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570631">Sun bug 6570631</a> is fixed.
*/
@GwtIncompatible // reflection
public static Method getSubListOriginalListSetAffectsSubListMethod() {
return getMethod(ListSubListTester.class, "testSubList_originalListSetAffectsSubList");
}
/**
* Returns the {@link Method} instance for {@link
* #testSubList_originalListSetAffectsSubListLargeList()} ()} so that tests of {@link
* CopyOnWriteArrayList} can suppress them with {@code
* FeatureSpecificTestSuiteBuilder.suppressing()} until <a
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570631">Sun bug 6570631</a> is fixed.
*/
@GwtIncompatible // reflection
public static Method getSubListOriginalListSetAffectsSubListLargeListMethod() {
return getMethod(ListSubListTester.class, "testSubList_originalListSetAffectsSubListLargeList");
}
/**
* Returns the {@link Method} instance for {@link
* #testSubList_subListRemoveAffectsOriginalLargeList()} so that tests of {@link
* CopyOnWriteArrayList} can suppress it with {@code
* FeatureSpecificTestSuiteBuilder.suppressing()} until <a
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570575">Sun bug 6570575</a> is fixed.
*/
@GwtIncompatible // reflection
public static Method getSubListSubListRemoveAffectsOriginalLargeListMethod() {
return getMethod(ListSubListTester.class, "testSubList_subListRemoveAffectsOriginalLargeList");
}
/*
* TODO: perform all List tests on subList(), but beware infinite recursion
*/
}