/** * Copyright (c) 2009 - 2017 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package org.candlepin.util; import static org.junit.Assert.*; import junitparams.JUnitParamsRunner; import junitparams.Parameters; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; /** * Test suite for the ListView class */ @RunWith(JUnitParamsRunner.class) public class ListViewTest extends SetViewTest { @Rule public ExpectedException thrown = ExpectedException.none(); @Before @Override public void init() { this.source = new LinkedList(); this.testobj = new ListView((List) this.source); } @Test(expected = UnsupportedOperationException.class) public void testAddFromIndex() { ((ListView) this.testobj).add(0, new Object()); } @Test(expected = UnsupportedOperationException.class) public void testAddAllFromIndex() { List collection = new LinkedList(); collection.add(new Object()); collection.add(new Object()); collection.add(new Object()); ((ListView) this.testobj).addAll(0, collection); } @Test @Override public void testEquals() { List comp = new LinkedList(); assertTrue(this.testobj.equals(comp)); for (int i = 0; i < 5; ++i) { this.source.add(String.valueOf(i)); assertFalse(this.testobj.equals(comp)); comp.add(String.valueOf(i)); assertTrue(this.testobj.equals(comp)); } this.source.clear(); assertFalse(this.testobj.equals(comp)); comp.clear(); assertTrue(this.testobj.equals(comp)); } @Test public void testGet() { for (int i = 0; i < 10; ++i) { this.source.add(String.valueOf(i)); } for (int i = 9; i >= 0; --i) { Object fetched = ((ListView) this.testobj).get(i); assertEquals(String.valueOf(i), fetched); } } @Test(expected = IndexOutOfBoundsException.class) @Parameters({ "-1", "4" }) public void testGetWithBadIndexes(int index) { this.source.addAll(Arrays.asList("1", "2", "3")); ((ListView) this.testobj).get(index); } @Test @Override public void testHashCode() { List comp = new LinkedList(); assertEquals(comp.hashCode(), this.testobj.hashCode()); for (int i = 0; i < 5; ++i) { this.source.add(String.valueOf(i)); assertNotEquals(comp.hashCode(), this.testobj.hashCode()); comp.add(String.valueOf(i)); assertEquals(comp.hashCode(), this.testobj.hashCode()); } this.source.clear(); assertNotEquals(comp.hashCode(), this.testobj.hashCode()); comp.clear(); assertEquals(comp.hashCode(), this.testobj.hashCode()); } @Test public void testIndexOf() { this.source.addAll(Arrays.asList("1", "1", "2", "2", "3", "3")); assertEquals(-1, ((ListView) this.testobj).indexOf("0")); assertEquals(0, ((ListView) this.testobj).indexOf("1")); assertEquals(2, ((ListView) this.testobj).indexOf("2")); assertEquals(4, ((ListView) this.testobj).indexOf("3")); assertEquals(-1, ((ListView) this.testobj).indexOf("4")); } @Test public void testLastIndexOf() { this.source.addAll(Arrays.asList("1", "1", "2", "2", "3", "3")); assertEquals(-1, ((ListView) this.testobj).lastIndexOf("0")); assertEquals(1, ((ListView) this.testobj).lastIndexOf("1")); assertEquals(3, ((ListView) this.testobj).lastIndexOf("2")); assertEquals(5, ((ListView) this.testobj).lastIndexOf("3")); assertEquals(-1, ((ListView) this.testobj).lastIndexOf("4")); } @Test public void testListIterator() { for (int i = 0; i < 3; ++i) { this.testListIteratorAscending(-1); this.testListIteratorDescending(-1); this.source.add(new Object()); this.source.add(new Object()); this.source.add(new Object()); this.source.add(new Object()); this.source.add(new Object()); this.testListIteratorAscending(-1); this.testListIteratorDescending(-1); } } @Test public void testListIteratorWithOffset() { for (int i = 0; i < 3; ++i) { this.testListIteratorAscending(0); this.testListIteratorDescending(0); this.source.add(new Object()); this.source.add(new Object()); this.source.add(new Object()); this.source.add(new Object()); this.source.add(new Object()); for (int j = 0; j < this.source.size(); ++j) { this.testListIteratorAscending(j); this.testListIteratorDescending(j); } } } private void testListIteratorAscending(int offset) { ListIterator iterator = offset > -1 ? ((ListView) this.testobj).listIterator(offset) : ((ListView) this.testobj).listIterator(); int expectedRemoved = offset > -1 ? this.source.size() - offset : this.source.size(); int expectedRemaining = this.source.size() - expectedRemoved; int expectedNextIndex = offset > -1 ? offset : 0; List found = new LinkedList(); List expected = new LinkedList( ((List) this.source).subList(offset > -1 ? offset : 0, this.source.size()) ); while (iterator.hasNext()) { assertEquals(expectedNextIndex++, iterator.nextIndex()); Object obj = iterator.next(); found.add(obj); } iterator = offset > -1 ? ((ListView) this.testobj).listIterator(offset) : ((ListView) this.testobj).listIterator(); expectedNextIndex = offset > -1 ? offset : 0; while (iterator.hasNext()) { assertEquals(expectedNextIndex, iterator.nextIndex()); iterator.next(); iterator.remove(); } assertEquals(expectedRemaining, this.source.size()); assertEquals(expectedRemoved, found.size()); assertTrue(found.containsAll(expected)); assertTrue(expected.containsAll(found)); } private void testListIteratorDescending(int offset) { ListIterator iterator = offset > -1 ? ((ListView) this.testobj).listIterator(offset) : ((ListView) this.testobj).listIterator(); int expectedRemoved = offset > -1 ? offset : 0; int expectedRemaining = this.source.size() - expectedRemoved; int expectedPrevIndex = offset > -1 ? offset - 1 : -1; List found = new LinkedList(); List expected = offset > -1 ? new LinkedList(((List) this.source).subList(0, offset)) : new LinkedList(this.source); while (iterator.hasPrevious()) { assertEquals(expectedPrevIndex--, iterator.previousIndex()); Object obj = iterator.previous(); found.add(obj); } iterator = offset > -1 ? ((ListView) this.testobj).listIterator(offset) : ((ListView) this.testobj).listIterator(); expectedPrevIndex = offset > -1 ? offset : 0; while (iterator.hasPrevious()) { assertEquals(expectedPrevIndex, iterator.previousIndex()); iterator.previous(); iterator.remove(); } assertEquals(expectedRemaining, this.source.size()); assertEquals(expectedRemoved, found.size()); assertTrue(found.containsAll(expected)); assertTrue(expected.containsAll(found)); } @Test(expected = UnsupportedOperationException.class) public void testListIteratorAddition() { this.source.addAll(Arrays.asList("1", "2", "3")); ListIterator iterator = ((ListView) this.testobj).listIterator(); iterator.add("A"); } @Test(expected = UnsupportedOperationException.class) public void testListIteratorReplace() { this.source.addAll(Arrays.asList("1", "2", "3")); ListIterator iterator = ((ListView) this.testobj).listIterator(); iterator.next(); iterator.set("A"); } @Test(expected = IndexOutOfBoundsException.class) @Parameters({ "-1", "4" }) public void testListIteratorWithBadIndexes(int index) { this.source.addAll(Arrays.asList("1", "2", "3")); ((ListView) this.testobj).listIterator(index); } @Test public void testRemoveFromIndex() { // Ascending for (int i = 0; i < 10; ++i) { this.source.add(String.valueOf(i)); } for (int i = 0; i < 10; ++i) { Object fetched = ((ListView) this.testobj).remove(0); assertEquals(String.valueOf(i), fetched); } assertEquals(0, this.source.size()); assertEquals(0, this.testobj.size()); // Descending for (int i = 0; i < 10; ++i) { this.source.add(String.valueOf(i)); } for (int i = 9; i >= 0; --i) { Object fetched = ((ListView) this.testobj).remove(i); assertEquals(String.valueOf(i), fetched); } assertEquals(0, this.source.size()); assertEquals(0, this.testobj.size()); // Pseudo-random for (int i = 0; i < 10; ++i) { this.source.add(String.valueOf(i)); } assertEquals("0", ((ListView) this.testobj).remove(0)); assertEquals("3", ((ListView) this.testobj).remove(2)); assertEquals("6", ((ListView) this.testobj).remove(4)); assertEquals("9", ((ListView) this.testobj).remove(6)); assertEquals(6, this.source.size()); assertEquals(6, this.testobj.size()); assertEquals("1", ((List) this.source).get(0)); assertEquals("2", ((List) this.source).get(1)); assertEquals("4", ((List) this.source).get(2)); assertEquals("5", ((List) this.source).get(3)); assertEquals("7", ((List) this.source).get(4)); assertEquals("8", ((List) this.source).get(5)); } @Test(expected = IndexOutOfBoundsException.class) @Parameters({ "-1", "4" }) public void testRemoveWithBadIndexes(int index) { this.source.addAll(Arrays.asList("1", "2", "3")); ((ListView) this.testobj).remove(index); } @Test public void testSet() { this.source.add("1"); try { ((ListView) this.testobj).set(0, "2"); fail("Expected an UnsupportedOperationException, but no exception was raised."); } catch (UnsupportedOperationException e) { // This is what we want. } assertTrue(this.source.contains("1")); assertFalse(this.source.contains("2")); } @Test public void testSubList() { for (int i = 0; i < 10; ++i) { this.source.add(String.valueOf(i)); } for (int i = 0; i < this.source.size() - 3; ++i) { List sublist = ((ListView) this.testobj).subList(i, i + 3); // We can get away with not testing every method on the sublist if we verify that it's // also a ListView instance (and, thus, already tested) assertTrue(sublist instanceof ListView); assertEquals(3, sublist.size()); for (int j = i; j < i + 3; ++j) { assertTrue(sublist.contains(String.valueOf(j))); } } for (int i = 0; i < this.source.size(); ++i) { List sublist = ((ListView) this.testobj).subList(i, i); assertTrue(sublist instanceof ListView); assertEquals(0, sublist.size()); } } protected Object[] paramsForSubListIndexOutOfBoundsTest() { return new Object[] { new Object[] { -1, 0, IndexOutOfBoundsException.class }, new Object[] { 0, -1, IllegalArgumentException.class }, new Object[] { 2, 1, IllegalArgumentException.class }, new Object[] { 4, 5, IndexOutOfBoundsException.class }, new Object[] { 1, 5, IndexOutOfBoundsException.class } }; } @Test @Parameters(method = "paramsForSubListIndexOutOfBoundsTest") public void testSubListIndexOutOfBounds(int begin, int end, Class<? extends Throwable> expected) { thrown.expect(expected); this.source.addAll(Arrays.asList("1", "2", "3")); ((ListView) this.testobj).subList(begin, end); } }