AbstractListTest.java revision 561ee011997c6c2f1befbfaa9d5f0a99771c1d63
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.luni.tests.java.util;
19
20import java.util.AbstractList;
21import java.util.ArrayList;
22import java.util.Arrays;
23import java.util.ConcurrentModificationException;
24import java.util.Iterator;
25import java.util.LinkedList;
26import java.util.List;
27import java.util.ListIterator;
28import java.util.NoSuchElementException;
29import java.util.RandomAccess;
30
31public class AbstractListTest extends junit.framework.TestCase {
32
33	static class SimpleList extends AbstractList {
34		ArrayList arrayList;
35
36		SimpleList() {
37			this.arrayList = new ArrayList();
38		}
39
40		public Object get(int index) {
41			return this.arrayList.get(index);
42		}
43
44		public void add(int i, Object o) {
45			this.arrayList.add(i, o);
46		}
47
48		public Object remove(int i) {
49			return this.arrayList.remove(i);
50		}
51
52		public int size() {
53			return this.arrayList.size();
54		}
55	}
56
57	/**
58	 * @tests java.util.AbstractList#hashCode()
59	 */
60	public void test_hashCode() {
61		List list = new ArrayList();
62		list.add(new Integer(3));
63		list.add(new Integer(15));
64		list.add(new Integer(5));
65		list.add(new Integer(1));
66		list.add(new Integer(7));
67		int hashCode = 1;
68		Iterator i = list.iterator();
69		while (i.hasNext()) {
70			Object obj = i.next();
71			hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
72		}
73		assertTrue("Incorrect hashCode returned.  Wanted: " + hashCode
74				+ " got: " + list.hashCode(), hashCode == list.hashCode());
75	}
76
77	/**
78	 * @tests java.util.AbstractList#iterator()
79	 */
80	public void test_iterator() {
81		SimpleList list = new SimpleList();
82		list.add(new Object());
83		list.add(new Object());
84		Iterator it = list.iterator();
85		it.next();
86		it.remove();
87		it.next();
88	}
89
90	/**
91	 * @tests java.util.AbstractList#listIterator()
92	 */
93	public void test_listIterator() {
94		Integer tempValue;
95		List list = new ArrayList();
96		list.add(new Integer(3));
97		list.add(new Integer(15));
98		list.add(new Integer(5));
99		list.add(new Integer(1));
100		list.add(new Integer(7));
101		ListIterator lit = list.listIterator();
102		assertTrue("Should not have previous", !lit.hasPrevious());
103		assertTrue("Should have next", lit.hasNext());
104		tempValue = (Integer) lit.next();
105		assertTrue("next returned wrong value.  Wanted 3, got: " + tempValue,
106				tempValue.intValue() == 3);
107		tempValue = (Integer) lit.previous();
108
109		SimpleList list2 = new SimpleList();
110		list2.add(new Object());
111		ListIterator lit2 = list2.listIterator();
112		lit2.add(new Object());
113		lit2.next();
114
115        //Regression test for Harmony-5808
116        list = new MockArrayList();
117        ListIterator it = list.listIterator();
118        it.add("one");
119        it.add("two");
120        assertEquals(2,list.size());
121	}
122
123	/**
124	 * @tests java.util.AbstractList#subList(int, int)
125	 */
126	public void test_subListII() {
127		// Test each of the SubList operations to ensure a
128		// ConcurrentModificationException does not occur on an AbstractList
129		// which does not update modCount
130		SimpleList mList = new SimpleList();
131		mList.add(new Object());
132		mList.add(new Object());
133		List sList = mList.subList(0, 2);
134		sList.add(new Object()); // calls add(int, Object)
135		sList.get(0);
136
137		sList.add(0, new Object());
138		sList.get(0);
139
140		sList.addAll(Arrays.asList(new String[] { "1", "2" }));
141		sList.get(0);
142
143		sList.addAll(0, Arrays.asList(new String[] { "3", "4" }));
144		sList.get(0);
145
146		sList.remove(0);
147		sList.get(0);
148
149		ListIterator lit = sList.listIterator();
150		lit.add(new Object());
151		lit.next();
152		lit.remove();
153		lit.next();
154
155		sList.clear(); // calls removeRange()
156		sList.add(new Object());
157
158		// test the type of sublist that is returned
159		List al = new ArrayList();
160		for (int i = 0; i < 10; i++) {
161			al.add(new Integer(i));
162		}
163		assertTrue(
164				"Sublist returned should have implemented Random Access interface",
165				al.subList(3, 7) instanceof RandomAccess);
166
167		List ll = new LinkedList();
168		for (int i = 0; i < 10; i++) {
169			ll.add(new Integer(i));
170		}
171		assertTrue(
172				"Sublist returned should not have implemented Random Access interface",
173				!(ll.subList(3, 7) instanceof RandomAccess));
174
175        }
176
177	/**
178     * @tests java.util.AbstractList#subList(int, int)
179     */
180    public void test_subList_empty() {
181        // Regression for HARMONY-389
182        List al = new ArrayList();
183        al.add("one");
184        List emptySubList = al.subList(0, 0);
185
186        try {
187            emptySubList.get(0);
188            fail("emptySubList.get(0) should throw IndexOutOfBoundsException");
189        } catch (IndexOutOfBoundsException e) {
190            // expected
191        }
192
193        try {
194            emptySubList.set(0, "one");
195            fail("emptySubList.set(0,Object) should throw IndexOutOfBoundsException");
196        } catch (IndexOutOfBoundsException e) {
197            // expected
198        }
199
200        try {
201            emptySubList.remove(0);
202            fail("emptySubList.remove(0) should throw IndexOutOfBoundsException");
203        } catch (IndexOutOfBoundsException e) {
204            // expected
205        }
206    }
207
208    class MockArrayList<E> extends AbstractList<E> {
209    	/**
210    	 *
211    	 */
212    	private static final long serialVersionUID = 1L;
213
214    	ArrayList<E> list = new ArrayList<E>();
215
216    	public E remove(int idx) {
217    		modCount++;
218    		return list.remove(idx);
219    	}
220
221    	@Override
222    	public E get(int index) {
223    		return list.get(index);
224    	}
225
226    	@Override
227    	public int size() {
228    		return list.size();
229    	}
230
231    	public void add(int idx, E o) {
232    		modCount += 10;
233    		list.add(idx, o);
234    	}
235    }
236
237    /*
238     * Regression test for HY-4398
239     */
240    public void test_iterator_next() {
241		MockArrayList<String> t = new MockArrayList<String>();
242		t.list.add("a");
243		t.list.add("b");
244
245		Iterator it = t.iterator();
246
247		while (it.hasNext()) {
248			it.next();
249		}
250		try {
251            it.next();
252            fail("Should throw NoSuchElementException");
253        } catch (NoSuchElementException cme) {
254            // expected
255        }
256
257        t.add("c");
258        try {
259            it.remove();
260            fail("Should throw NoSuchElementException");
261        } catch (ConcurrentModificationException cme) {
262            // expected
263		}
264
265		it = t.iterator();
266		try {
267			it.remove();
268			fail("Should throw IllegalStateException");
269		} catch (IllegalStateException ise) {
270			// expected
271		}
272
273		Object value = it.next();
274		assertEquals("a", value);
275	}
276
277    /**
278     * @tests java.util.AbstractList#subList(int, int)
279     */
280    public void test_subList_addAll() {
281        // Regression for HARMONY-390
282        List mainList = new ArrayList();
283        Object[] mainObjects = { "a", "b", "c" };
284        mainList.addAll(Arrays.asList(mainObjects));
285        List subList = mainList.subList(1, 2);
286        assertFalse("subList should not contain \"a\"", subList.contains("a"));
287        assertFalse("subList should not contain \"c\"", subList.contains("c"));
288        assertTrue("subList should contain \"b\"", subList.contains("b"));
289
290        Object[] subObjects = { "one", "two", "three" };
291        subList.addAll(Arrays.asList(subObjects));
292        assertFalse("subList should not contain \"a\"", subList.contains("a"));
293        assertFalse("subList should not contain \"c\"", subList.contains("c"));
294
295        Object[] expected = { "b", "one", "two", "three" };
296        ListIterator iter = subList.listIterator();
297        for (int i = 0; i < expected.length; i++) {
298            assertTrue("subList should contain " + expected[i], subList
299                    .contains(expected[i]));
300            assertTrue("should be more elements", iter.hasNext());
301            assertEquals("element in incorrect position", expected[i], iter
302                    .next());
303        }
304    }
305
306    protected void doneSuite() {}
307
308    class MockRemoveFailureArrayList<E> extends AbstractList<E> {
309
310		@Override
311		public E get(int location) {
312			// TODO Auto-generated method stub
313			return null;
314		}
315
316		@Override
317		public int size() {
318			// TODO Auto-generated method stub
319			return 0;
320		}
321
322		public E remove(int idx) {
323    		modCount+=2;
324    		return null;
325    	}
326
327		public int getModCount(){
328			return modCount;
329		}
330    }
331
332    //test remove for failure by inconsistency of modCount and expectedModCount
333    public void test_remove(){
334    	MockRemoveFailureArrayList<String> mrfal = new MockRemoveFailureArrayList<String>();
335    	Iterator<String> imrfal= mrfal.iterator();
336    	imrfal.next();
337    	imrfal.remove();
338    	try{
339    		imrfal.remove();
340    	}
341    	catch(ConcurrentModificationException e){
342    		fail("Excepted to catch IllegalStateException not ConcurrentModificationException");
343    	}
344    	catch(IllegalStateException e){
345    		//Excepted to catch IllegalStateException here
346    	}
347    }
348
349    public void test_subListII2() {
350        List<Integer> holder = new ArrayList<Integer>(16);
351        for (int i=0; i<10; i++) {
352            holder.add(i);
353        }
354
355        // parent change should cause sublist concurrentmodification fail
356        List<Integer> sub = holder.subList(0, holder.size());
357        holder.add(11);
358        try {
359            sub.size();
360            fail("Should throw ConcurrentModificationException.");
361        } catch (ConcurrentModificationException e) {}
362        try {
363            sub.add(12);
364            fail("Should throw ConcurrentModificationException.");
365        } catch (ConcurrentModificationException e) {}
366        try {
367            sub.add(0, 11);
368            fail("Should throw ConcurrentModificationException.");
369        } catch (ConcurrentModificationException e) {}
370        try {
371            sub.clear();
372            fail("Should throw ConcurrentModificationException.");
373        } catch (ConcurrentModificationException e) {}
374        try {
375            sub.contains(11);
376            fail("Should throw ConcurrentModificationException.");
377        } catch (ConcurrentModificationException e) {}
378        try {
379            sub.get(9);
380            fail("Should throw ConcurrentModificationException.");
381        } catch (ConcurrentModificationException e) {}
382        try {
383            sub.indexOf(10);
384            fail("Should throw ConcurrentModificationException.");
385        } catch (ConcurrentModificationException e) {}
386        try {
387            sub.isEmpty();
388            fail("Should throw ConcurrentModificationException.");
389        } catch (ConcurrentModificationException e) {}
390        try {
391            sub.iterator();
392            fail("Should throw ConcurrentModificationException.");
393        } catch (ConcurrentModificationException e) {}
394        try {
395            sub.lastIndexOf(10);
396            fail("Should throw ConcurrentModificationException.");
397        } catch (ConcurrentModificationException e) {}
398        try {
399            sub.listIterator();
400            fail("Should throw ConcurrentModificationException.");
401        } catch (ConcurrentModificationException e) {}
402        try {
403            sub.listIterator(0);
404            fail("Should throw ConcurrentModificationException.");
405        } catch (ConcurrentModificationException e) {}
406        try {
407            sub.remove(0);
408            fail("Should throw ConcurrentModificationException.");
409        } catch (ConcurrentModificationException e) {}
410        try {
411            sub.remove(9);
412            fail("Should throw ConcurrentModificationException.");
413        } catch (ConcurrentModificationException e) {}
414        try {
415            sub.set(0, 0);
416            fail("Should throw ConcurrentModificationException.");
417        } catch (ConcurrentModificationException e) {}
418        try {
419            sub.size();
420            fail("Should throw ConcurrentModificationException.");
421        } catch (ConcurrentModificationException e) {}
422        try {
423            sub.toArray();
424            fail("Should throw ConcurrentModificationException.");
425        } catch (ConcurrentModificationException e) {}
426        try {
427            sub.toString();
428            fail("Should throw ConcurrentModificationException.");
429        } catch (ConcurrentModificationException e) {}
430
431        holder.clear();
432    }
433
434    /**
435     * @tests {@link java.util.AbstractList#indexOf(Object)}
436     */
437    public void test_indexOf_Ljava_lang_Object() {
438        AbstractList<Integer> list = new MockArrayList<Integer>();
439        Integer[] array = { 1, 2, 3, 4, 5 };
440        list.addAll(Arrays.asList(array));
441
442        assertEquals("find 0 in the list do not contain 0", -1, list
443                .indexOf(new Integer(0)));
444        assertEquals("did not return the right location of element 3", 2, list
445                .indexOf(new Integer(3)));
446        assertEquals("find null in the list do not contain null element", -1,
447                list.indexOf(null));
448        list.add(null);
449        assertEquals("did not return the right location of element null", 5,
450                list.indexOf(null));
451    }
452
453    /**
454     * @add tests {@link java.util.AbstractList#lastIndexOf(Object)}
455     */
456    public void test_lastIndexOf_Ljava_lang_Object() {
457        AbstractList<Integer> list = new MockArrayList<Integer>();
458        Integer[] array = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
459        list.addAll(Arrays.asList(array));
460
461        assertEquals("find 6 in the list do not contain 6", -1, list
462                .lastIndexOf(new Integer(6)));
463        assertEquals("did not return the right location of element 4", 6, list
464                .lastIndexOf(new Integer(4)));
465        assertEquals("find null in the list do not contain null element", -1,
466                list.lastIndexOf(null));
467        list.add(null);
468        assertEquals("did not return the right location of element null", 10,
469                list.lastIndexOf(null));
470    }
471
472    /**
473     * @add tests {@link java.util.AbstractList#remove(int)}
474     * @add tests {@link java.util.AbstractList#set(int, Object)}
475     */
476    public void test_remove_I() {
477        class MockList<E> extends AbstractList<E> {
478            private ArrayList<E> list;
479
480            @Override
481            public E get(int location) {
482                return list.get(location);
483            }
484
485            @Override
486            public int size() {
487                return list.size();
488            }
489
490        }
491        AbstractList<Integer> list = new MockList<Integer>();
492        try {
493            list.remove(0);
494            fail("should throw UnsupportedOperationException");
495        } catch (UnsupportedOperationException e) {
496            // expected
497        }
498
499        try {
500            list.set(0, null);
501            fail("should throw UnsupportedOperationException");
502        } catch (UnsupportedOperationException e) {
503            // expected
504        }
505    }
506}
507