| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.harmony.tests.java.util; |
| |
| import java.util.AbstractList; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.ConcurrentModificationException; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.NoSuchElementException; |
| import java.util.RandomAccess; |
| |
| public class AbstractListTest extends junit.framework.TestCase { |
| |
| static class SimpleList extends AbstractList { |
| ArrayList arrayList; |
| |
| SimpleList() { |
| this.arrayList = new ArrayList(); |
| } |
| |
| public Object get(int index) { |
| return this.arrayList.get(index); |
| } |
| |
| public void add(int i, Object o) { |
| this.arrayList.add(i, o); |
| } |
| |
| public Object remove(int i) { |
| return this.arrayList.remove(i); |
| } |
| |
| public int size() { |
| return this.arrayList.size(); |
| } |
| } |
| |
| /** |
| * java.util.AbstractList#hashCode() |
| */ |
| public void test_hashCode() { |
| List list = new ArrayList(); |
| list.add(new Integer(3)); |
| list.add(new Integer(15)); |
| list.add(new Integer(5)); |
| list.add(new Integer(1)); |
| list.add(new Integer(7)); |
| int hashCode = 1; |
| Iterator i = list.iterator(); |
| while (i.hasNext()) { |
| Object obj = i.next(); |
| hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); |
| } |
| assertTrue("Incorrect hashCode returned. Wanted: " + hashCode |
| + " got: " + list.hashCode(), hashCode == list.hashCode()); |
| } |
| |
| /** |
| * java.util.AbstractList#iterator() |
| */ |
| public void test_iterator() { |
| SimpleList list = new SimpleList(); |
| list.add(new Object()); |
| list.add(new Object()); |
| Iterator it = list.iterator(); |
| it.next(); |
| it.remove(); |
| it.next(); |
| } |
| |
| /** |
| * java.util.AbstractList#listIterator() |
| */ |
| public void test_listIterator() { |
| Integer tempValue; |
| List list = new ArrayList(); |
| list.add(new Integer(3)); |
| list.add(new Integer(15)); |
| list.add(new Integer(5)); |
| list.add(new Integer(1)); |
| list.add(new Integer(7)); |
| ListIterator lit = list.listIterator(); |
| assertTrue("Should not have previous", !lit.hasPrevious()); |
| assertTrue("Should have next", lit.hasNext()); |
| tempValue = (Integer) lit.next(); |
| assertTrue("next returned wrong value. Wanted 3, got: " + tempValue, |
| tempValue.intValue() == 3); |
| tempValue = (Integer) lit.previous(); |
| |
| SimpleList list2 = new SimpleList(); |
| list2.add(new Object()); |
| ListIterator lit2 = list2.listIterator(); |
| lit2.add(new Object()); |
| lit2.next(); |
| |
| //Regression test for Harmony-5808 |
| list = new MockArrayList(); |
| ListIterator it = list.listIterator(); |
| it.add("one"); |
| it.add("two"); |
| assertEquals(2, list.size()); |
| } |
| |
| /** |
| * java.util.AbstractList#subList(int, int) |
| */ |
| public void test_subListII() { |
| // Test each of the SubList operations to ensure a |
| // ConcurrentModificationException does not occur on an AbstractList |
| // which does not update modCount |
| SimpleList mList = new SimpleList(); |
| mList.add(new Object()); |
| mList.add(new Object()); |
| List sList = mList.subList(0, 2); |
| sList.add(new Object()); // calls add(int, Object) |
| sList.get(0); |
| |
| sList.add(0, new Object()); |
| sList.get(0); |
| |
| sList.addAll(Arrays.asList(new String[] { "1", "2" })); |
| sList.get(0); |
| |
| sList.addAll(0, Arrays.asList(new String[] { "3", "4" })); |
| sList.get(0); |
| |
| sList.remove(0); |
| sList.get(0); |
| |
| ListIterator lit = sList.listIterator(); |
| lit.add(new Object()); |
| lit.next(); |
| lit.remove(); |
| lit.next(); |
| |
| sList.clear(); // calls removeRange() |
| sList.add(new Object()); |
| |
| // test the type of sublist that is returned |
| List al = new ArrayList(); |
| for (int i = 0; i < 10; i++) { |
| al.add(new Integer(i)); |
| } |
| assertTrue( |
| "Sublist returned should have implemented Random Access interface", |
| al.subList(3, 7) instanceof RandomAccess); |
| |
| List ll = new LinkedList(); |
| for (int i = 0; i < 10; i++) { |
| ll.add(new Integer(i)); |
| } |
| assertTrue( |
| "Sublist returned should not have implemented Random Access interface", |
| !(ll.subList(3, 7) instanceof RandomAccess)); |
| |
| } |
| |
| /** |
| * java.util.AbstractList#subList(int, int) |
| */ |
| public void test_subList_empty() { |
| // Regression for HARMONY-389 |
| List al = new ArrayList(); |
| al.add("one"); |
| List emptySubList = al.subList(0, 0); |
| |
| try { |
| emptySubList.get(0); |
| fail("emptySubList.get(0) should throw IndexOutOfBoundsException"); |
| } catch (IndexOutOfBoundsException e) { |
| // expected |
| } |
| |
| try { |
| emptySubList.set(0, "one"); |
| fail("emptySubList.set(0,Object) should throw IndexOutOfBoundsException"); |
| } catch (IndexOutOfBoundsException e) { |
| // expected |
| } |
| |
| try { |
| emptySubList.remove(0); |
| fail("emptySubList.remove(0) should throw IndexOutOfBoundsException"); |
| } catch (IndexOutOfBoundsException e) { |
| // expected |
| } |
| } |
| |
| class MockArrayList<E> extends AbstractList<E> { |
| /** |
| * |
| */ |
| private static final long serialVersionUID = 1L; |
| |
| ArrayList<E> list = new ArrayList<E>(); |
| |
| public E remove(int idx) { |
| modCount++; |
| return list.remove(idx); |
| } |
| |
| @Override |
| public E get(int index) { |
| return list.get(index); |
| } |
| |
| @Override |
| public int size() { |
| return list.size(); |
| } |
| |
| public void add(int idx, E o) { |
| modCount += 10; |
| list.add(idx, o); |
| } |
| } |
| |
| /* |
| * Regression test for HY-4398 |
| */ |
| public void test_iterator_next() { |
| MockArrayList<String> t = new MockArrayList<String>(); |
| t.list.add("a"); |
| t.list.add("b"); |
| |
| Iterator it = t.iterator(); |
| |
| while (it.hasNext()) { |
| it.next(); |
| } |
| try { |
| it.next(); |
| fail("Should throw NoSuchElementException"); |
| } catch (NoSuchElementException cme) { |
| // expected |
| } |
| |
| t.add("c"); |
| try { |
| it.remove(); |
| fail("Should throw NoSuchElementException"); |
| } catch (ConcurrentModificationException cme) { |
| // expected |
| } |
| |
| it = t.iterator(); |
| try { |
| it.remove(); |
| fail("Should throw IllegalStateException"); |
| } catch (IllegalStateException ise) { |
| // expected |
| } |
| |
| Object value = it.next(); |
| assertEquals("a", value); |
| } |
| |
| /** |
| * java.util.AbstractList#subList(int, int) |
| */ |
| public void test_subList_addAll() { |
| // Regression for HARMONY-390 |
| List mainList = new ArrayList(); |
| Object[] mainObjects = { "a", "b", "c" }; |
| mainList.addAll(Arrays.asList(mainObjects)); |
| List subList = mainList.subList(1, 2); |
| assertFalse("subList should not contain \"a\"", subList.contains("a")); |
| assertFalse("subList should not contain \"c\"", subList.contains("c")); |
| assertTrue("subList should contain \"b\"", subList.contains("b")); |
| |
| Object[] subObjects = { "one", "two", "three" }; |
| subList.addAll(Arrays.asList(subObjects)); |
| assertFalse("subList should not contain \"a\"", subList.contains("a")); |
| assertFalse("subList should not contain \"c\"", subList.contains("c")); |
| |
| Object[] expected = { "b", "one", "two", "three" }; |
| ListIterator iter = subList.listIterator(); |
| for (int i = 0; i < expected.length; i++) { |
| assertTrue("subList should contain " + expected[i], subList |
| .contains(expected[i])); |
| assertTrue("should be more elements", iter.hasNext()); |
| assertEquals("element in incorrect position", expected[i], iter |
| .next()); |
| } |
| } |
| |
| public void test_indexOfLjava_lang_Object() { |
| AbstractList al = new ArrayList(); |
| al.add(0); |
| al.add(1); |
| al.add(2); |
| al.add(3); |
| al.add(4); |
| |
| assertEquals(-1, al.indexOf(5)); |
| assertEquals(2, al.indexOf(2)); |
| } |
| |
| public void test_lastIndexOfLjava_lang_Object() { |
| AbstractList al = new ArrayList(); |
| al.add(0); |
| al.add(1); |
| al.add(2); |
| al.add(2); |
| al.add(2); |
| al.add(2); |
| al.add(2); |
| al.add(3); |
| al.add(4); |
| |
| assertEquals(-1, al.lastIndexOf(5)); |
| assertEquals(6, al.lastIndexOf(2)); |
| } |
| |
| public void test_listIteratorI() { |
| AbstractList al1 = new ArrayList(); |
| AbstractList al2 = new ArrayList(); |
| al1.add(0); |
| al1.add(1); |
| al1.add(2); |
| al1.add(3); |
| al1.add(4); |
| al2.add(2); |
| al2.add(3); |
| al2.add(4); |
| |
| Iterator li1 = al1.listIterator(2); |
| Iterator li2 = al2.listIterator(); |
| |
| while(li1.hasNext()&&li2.hasNext()) { |
| assertEquals(li1.next(), li2.next()); |
| } |
| assertSame(li1.hasNext(),li2.hasNext()); |
| |
| try { |
| al1.listIterator(-1); |
| fail("IndexOutOfBoundsException expected"); |
| } catch (IndexOutOfBoundsException ee) { |
| //expected |
| } |
| |
| try { |
| al1.listIterator(al1.size() + 1); |
| fail("IndexOutOfBoundsException expected"); |
| } catch (IndexOutOfBoundsException ee) { |
| //expected |
| } |
| } |
| |
| protected void doneSuite() { |
| } |
| |
| class MockRemoveFailureArrayList<E> extends AbstractList<E> { |
| |
| @Override |
| public E get(int location) { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public int size() { |
| // TODO Auto-generated method stub |
| return 0; |
| } |
| |
| public E remove(int idx) { |
| modCount += 2; |
| return null; |
| } |
| |
| public int getModCount() { |
| return modCount; |
| } |
| } |
| |
| //test remove for failure by inconsistency of modCount and expectedModCount |
| public void test_remove() { |
| MockRemoveFailureArrayList<String> mrfal = new MockRemoveFailureArrayList<String>(); |
| Iterator<String> imrfal = mrfal.iterator(); |
| imrfal.next(); |
| imrfal.remove(); |
| try { |
| imrfal.remove(); |
| } catch (ConcurrentModificationException e) { |
| fail("Excepted to catch IllegalStateException not ConcurrentModificationException"); |
| } catch (IllegalStateException e) { |
| //Excepted to catch IllegalStateException here |
| } |
| } |
| |
| public void test_subListII2() { |
| List<Integer> holder = new ArrayList<Integer>(16); |
| for (int i = 0; i < 10; i++) { |
| holder.add(i); |
| } |
| |
| // parent change should cause sublist concurrentmodification fail |
| List<Integer> sub = holder.subList(0, holder.size()); |
| holder.add(11); |
| try { |
| sub.size(); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.add(12); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.add(0, 11); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.clear(); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.contains(11); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.get(9); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.indexOf(10); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.isEmpty(); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.iterator(); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.lastIndexOf(10); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.listIterator(); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.listIterator(0); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.remove(0); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.remove(9); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.set(0, 0); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.size(); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.toArray(); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| try { |
| sub.toString(); |
| fail("Should throw ConcurrentModificationException."); |
| } catch (ConcurrentModificationException e) { |
| } |
| |
| holder.clear(); |
| } |
| |
| public void test_indexOf_Ljava_lang_Object() { |
| AbstractList<Integer> list = new MockArrayList<Integer>(); |
| Integer[] array = { 1, 2, 3, 4, 5 }; |
| list.addAll(Arrays.asList(array)); |
| |
| assertEquals("find 0 in the list do not contain 0", -1, list |
| .indexOf(new Integer(0))); |
| assertEquals("did not return the right location of element 3", 2, list |
| .indexOf(new Integer(3))); |
| assertEquals("find null in the list do not contain null element", -1, |
| list.indexOf(null)); |
| list.add(null); |
| assertEquals("did not return the right location of element null", 5, |
| list.indexOf(null)); |
| } |
| |
| public void test_lastIndexOf_Ljava_lang_Object() { |
| AbstractList<Integer> list = new MockArrayList<Integer>(); |
| Integer[] array = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 }; |
| list.addAll(Arrays.asList(array)); |
| |
| assertEquals("find 6 in the list do not contain 6", -1, list |
| .lastIndexOf(new Integer(6))); |
| assertEquals("did not return the right location of element 4", 6, list |
| .lastIndexOf(new Integer(4))); |
| assertEquals("find null in the list do not contain null element", -1, |
| list.lastIndexOf(null)); |
| list.add(null); |
| assertEquals("did not return the right location of element null", 10, |
| list.lastIndexOf(null)); |
| } |
| |
| public void test_remove_I() { |
| class MockList<E> extends AbstractList<E> { |
| private ArrayList<E> list; |
| |
| @Override |
| public E get(int location) { |
| return list.get(location); |
| } |
| |
| @Override |
| public int size() { |
| return list.size(); |
| } |
| |
| } |
| AbstractList<Integer> list = new MockList<Integer>(); |
| try { |
| list.remove(0); |
| fail("should throw UnsupportedOperationException"); |
| } catch (UnsupportedOperationException e) { |
| // expected |
| } |
| |
| try { |
| list.set(0, null); |
| fail("should throw UnsupportedOperationException"); |
| } catch (UnsupportedOperationException e) { |
| // expected |
| } |
| } |
| } |