001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.collections.primitives;
018
019import java.io.Serializable;
020import java.util.ArrayList;
021import java.util.ConcurrentModificationException;
022import java.util.List;
023
024import org.apache.commons.collections.primitives.adapters.BaseTestList;
025import org.apache.commons.collections.primitives.adapters.CharListList;
026import org.apache.commons.collections.primitives.adapters.ListCharList;
027
028/**
029 * @version $Revision: 480451 $ $Date: 2006-11-29 02:45:08 -0500 (Wed, 29 Nov 2006) $
030 * @author Rodney Waldhoff
031 */
032public abstract class TestCharList extends BaseTestList {
033
034    // conventional
035    // ------------------------------------------------------------------------
036
037    public TestCharList(String testName) {
038        super(testName);
039    }
040
041    // collections testing framework
042    // ------------------------------------------------------------------------
043
044    // collections testing framework: char list
045    // ------------------------------------------------------------------------
046
047    protected abstract CharList makeEmptyCharList();
048
049    protected CharList makeFullCharList() {
050        CharList list = makeEmptyCharList();
051        char[] values = getFullChars();
052        for(int i=0;i<values.length;i++) {
053            list.add(values[i]);
054        }
055        return list;
056    }
057
058    protected char[] getFullChars() {
059        char[] result = new char[19];
060        for(int i = 0; i < result.length; i++) {
061            result[i] = (char)(i);
062        }
063        return result;
064    }
065
066    protected char[] getOtherChars() {
067        char[] result = new char[16];
068        for(int i = 0; i < result.length; i++) {
069            result[i] = (char)(i + 43);
070        }
071        return result;
072    }
073    
074    // collections testing framework: inherited
075    // ------------------------------------------------------------------------
076
077    public List makeEmptyList() {
078        return new CharListList(makeEmptyCharList());
079    }
080        
081    public Object[] getFullElements() {
082        return wrapArray(getFullChars());
083    }
084
085    public Object[] getOtherElements() {
086        return wrapArray(getOtherChars());
087    }
088
089    // private utils
090    // ------------------------------------------------------------------------
091
092    private Character[] wrapArray(char[] primitives) {
093        Character[] result = new Character[primitives.length];
094        for(int i=0;i<result.length;i++) {
095            result[i] = new Character(primitives[i]);            
096        }
097        return result;
098    }
099
100    // tests
101    // ------------------------------------------------------------------------
102
103    public void testExceptionOnConcurrentModification() {
104        CharList list = makeFullCharList();
105        CharIterator iter = list.iterator();
106        iter.next();
107        list.add((char)3);
108        try {
109            iter.next();
110            fail("Expected ConcurrentModificationException");
111        } catch(ConcurrentModificationException e) {
112            // expected
113        }
114    }
115    
116    public void testAddAllCharListAtIndex() {
117        CharList source = makeFullCharList();
118        CharList dest = makeFullCharList();
119        dest.addAll(1,source);
120        
121        CharIterator iter = dest.iterator();
122        assertTrue(iter.hasNext());
123        assertEquals(source.get(0),iter.next());
124        for(int i=0;i<source.size();i++) {
125            assertTrue(iter.hasNext());
126            assertEquals(source.get(i),iter.next());
127        }
128        for(int i=1;i<source.size();i++) {
129            assertTrue(iter.hasNext());
130            assertEquals(source.get(i),iter.next());
131        }
132        assertFalse(iter.hasNext());
133    }
134
135    public void testToJustBigEnoughCharArray() {
136        CharList list = makeFullCharList();
137        char[] dest = new char[list.size()];
138        assertSame(dest,list.toArray(dest));
139        int i=0;
140        for(CharIterator iter = list.iterator(); iter.hasNext();i++) {
141            assertEquals(iter.next(),dest[i], 0f);
142        }
143    }
144    
145    public void testToLargerThanNeededCharArray() {
146        CharList list = makeFullCharList();
147        char[] dest = new char[list.size()*2];
148        for(int i=0;i<dest.length;i++) {
149            dest[i] = Character.MAX_VALUE;
150        }       
151        assertSame(dest,list.toArray(dest));
152        int i=0;
153        for(CharIterator iter = list.iterator(); iter.hasNext();i++) {
154            assertEquals(iter.next(),dest[i]);
155        }
156        for(;i<dest.length;i++) {
157            assertEquals(Character.MAX_VALUE,dest[i]);
158        }
159    }
160    
161    public void testToSmallerThanNeededCharArray() {
162        CharList list = makeFullCharList();
163        char[] dest = new char[list.size()/2];
164        char[] dest2 = list.toArray(dest);
165        assertTrue(dest != dest2);
166        int i=0;
167        for(CharIterator iter = list.iterator(); iter.hasNext();i++) {
168            assertEquals(iter.next(),dest2[i], 0f);
169        }
170    }
171    
172    public void testHashCodeSpecification() {
173        CharList list = makeFullCharList();
174        int hash = 1;
175        for(CharIterator iter = list.iterator(); iter.hasNext(); ) {
176            hash = 31*hash + ((int)iter.next());
177        }
178        assertEquals(hash,list.hashCode());
179    }
180
181    public void testEqualsWithTwoCharLists() {
182        CharList one = makeEmptyCharList();
183        assertEquals("Equals is reflexive on empty list",one,one);
184        CharList two = makeEmptyCharList();
185        assertEquals("Empty lists are equal",one,two);
186        assertEquals("Equals is symmetric on empty lists",two,one);
187        
188        one.add((char)1);
189        assertEquals("Equals is reflexive on non empty list",one,one);
190        assertTrue(!one.equals(two));
191        assertTrue(!two.equals(one));
192
193        two.add((char)1);
194        assertEquals("Non empty lists are equal",one,two);
195        assertEquals("Equals is symmetric on non empty list",one,two);
196        
197        one.add((char)1); one.add((char)2); one.add((char)3); one.add((char)5); one.add((char)8);
198        assertEquals("Equals is reflexive on larger non empty list",one,one);
199        assertTrue(!one.equals(two));
200        assertTrue(!two.equals(one));
201        
202        two.add((char)1); two.add((char)2); two.add((char)3); two.add((char)5); two.add((char)8);
203        assertEquals("Larger non empty lists are equal",one,two);
204        assertEquals("Equals is symmetric on larger non empty list",two,one);
205
206        one.add((char)9);
207        two.add((char)10);
208        assertTrue(!one.equals(two));
209        assertTrue(!two.equals(one));
210
211    }
212
213    public void testCharSubListEquals() {
214        CharList one = makeEmptyCharList();
215        assertEquals(one,one.subList(0,0));
216        assertEquals(one.subList(0,0),one);
217        
218        one.add((char)1);
219        assertEquals(one,one.subList(0,1));
220        assertEquals(one.subList(0,1),one);
221
222        one.add((char)1); one.add((char)2); one.add((char)3); one.add((char)5); one.add((char)8);
223        assertEquals(one.subList(0,4),one.subList(0,4));
224        assertEquals(one.subList(3,5),one.subList(3,5));
225    }
226    
227    public void testEqualsWithCharListAndList() {
228        CharList ilist = makeEmptyCharList();
229        List list = new ArrayList();
230        
231        assertTrue("Unwrapped, empty List should not be equal to empty CharList.",!ilist.equals(list));
232        assertTrue("Unwrapped, empty CharList should not be equal to empty List.",!list.equals(ilist));
233        
234        assertEquals(new ListCharList(list),ilist);
235        assertEquals(ilist,new ListCharList(list));
236        assertEquals(new CharListList(ilist),list);
237        assertEquals(list,new CharListList(ilist));
238        
239        ilist.add((char)1);
240        list.add(new Character((char)1));
241
242        assertTrue("Unwrapped, non-empty List is not equal to non-empty CharList.",!ilist.equals(list));
243        assertTrue("Unwrapped, non-empty CharList is not equal to non-empty List.",!list.equals(ilist));
244        
245        assertEquals(new ListCharList(list),ilist);
246        assertEquals(ilist,new ListCharList(list));
247        assertEquals(new CharListList(ilist),list);
248        assertEquals(list,new CharListList(ilist));
249                
250        ilist.add((char)1); ilist.add((char)2); ilist.add((char)3); ilist.add((char)5); ilist.add((char)8);
251        list.add(new Character((char)1)); list.add(new Character((char)2)); list.add(new Character((char)3)); list.add(new Character((char)5)); list.add(new Character((char)8));
252
253        assertTrue("Unwrapped, non-empty List is not equal to non-empty CharList.",!ilist.equals(list));
254        assertTrue("Unwrapped, non-empty CharList is not equal to non-empty List.",!list.equals(ilist));
255        
256        assertEquals(new ListCharList(list),ilist);
257        assertEquals(ilist,new ListCharList(list));
258        assertEquals(new CharListList(ilist),list);
259        assertEquals(list,new CharListList(ilist));
260        
261    }
262
263    public void testClearAndSize() {
264        CharList list = makeEmptyCharList();
265        assertEquals(0, list.size());
266        for(int i = 0; i < 100; i++) {
267            list.add((char)i);
268        }
269        assertEquals(100, list.size());
270        list.clear();
271        assertEquals(0, list.size());
272    }
273
274    public void testRemoveViaSubList() {
275        CharList list = makeEmptyCharList();
276        for(int i = 0; i < 100; i++) {
277            list.add((char)i);
278        }
279        CharList sub = list.subList(25,75);
280        assertEquals(50,sub.size());
281        for(int i = 0; i < 50; i++) {
282            assertEquals(100-i,list.size());
283            assertEquals(50-i,sub.size());
284            assertEquals((char)(25+i),sub.removeElementAt(0), 0f);
285            assertEquals(50-i-1,sub.size());
286            assertEquals(100-i-1,list.size());
287        }
288        assertEquals(0,sub.size());
289        assertEquals(50,list.size());        
290    }
291    
292    public void testAddGet() {
293        CharList list = makeEmptyCharList();
294        for (int i = 0; i < 255; i++) {
295            list.add((char)i);
296        }
297        for (int i = 0; i < 255; i++) {
298            assertEquals((char)i, list.get(i), 0f);
299        }
300    }
301
302    public void testAddAndShift() {
303        CharList list = makeEmptyCharList();
304        list.add(0, (char)1);
305        assertEquals("Should have one entry", 1, list.size());
306        list.add((char)3);
307        list.add((char)4);
308        list.add(1, (char)2);
309        for(int i = 0; i < 4; i++) {
310            assertEquals("Should get entry back", (char)(i + 1), list.get(i), 0f);
311        }
312        list.add(0, (char)0);
313        for (int i = 0; i < 5; i++) {
314            assertEquals("Should get entry back", (char)i, list.get(i), 0f);
315        }
316    }
317
318    public void testIsSerializable() throws Exception {
319        CharList list = makeFullCharList();
320        assertTrue(list instanceof Serializable);
321        byte[] ser = writeExternalFormToBytes((Serializable)list);
322        CharList deser = (CharList)(readExternalFormFromBytes(ser));
323        assertEquals(list,deser);
324        assertEquals(deser,list);
325    }
326
327    public void testCharListSerializeDeserializeThenCompare() throws Exception {
328        CharList list = makeFullCharList();
329        if(list instanceof Serializable) {
330            byte[] ser = writeExternalFormToBytes((Serializable)list);
331            CharList deser = (CharList)(readExternalFormFromBytes(ser));
332            assertEquals("obj != deserialize(serialize(obj))",list,deser);
333        }
334    }
335
336    public void testSubListsAreNotSerializable() throws Exception {
337        CharList list = makeFullCharList().subList(2,3);
338        assertTrue( ! (list instanceof Serializable) );
339    }
340
341    public void testSubListOutOfBounds() throws Exception {
342        try {
343            makeEmptyCharList().subList(2,3);
344            fail("Expected IndexOutOfBoundsException");
345        } catch(IndexOutOfBoundsException e) {
346            // expected
347        }
348
349        try {
350            makeFullCharList().subList(-1,3);
351            fail("Expected IndexOutOfBoundsException");
352        } catch(IndexOutOfBoundsException e) {
353            // expected
354        }
355
356
357        try {
358            makeFullCharList().subList(5,2);
359            fail("Expected IllegalArgumentException");
360        } catch(IllegalArgumentException e) {
361            // expected
362        }
363
364        try {
365            makeFullCharList().subList(2,makeFullCharList().size()+2);
366            fail("Expected IndexOutOfBoundsException");
367        } catch(IndexOutOfBoundsException e) {
368            // expected
369        }
370    }
371
372    public void testListIteratorOutOfBounds() throws Exception {
373        try {
374            makeEmptyCharList().listIterator(2);
375            fail("Expected IndexOutOfBoundsException");
376        } catch(IndexOutOfBoundsException e) {
377            // expected
378        }
379
380        try {
381            makeFullCharList().listIterator(-1);
382            fail("Expected IndexOutOfBoundsException");
383        } catch(IndexOutOfBoundsException e) {
384            // expected
385        }
386
387        try {
388            makeFullCharList().listIterator(makeFullCharList().size()+2);
389            fail("Expected IndexOutOfBoundsException");
390        } catch(IndexOutOfBoundsException e) {
391            // expected
392        }
393    }
394
395    public void testListIteratorSetWithoutNext() throws Exception {
396        CharListIterator iter = makeFullCharList().listIterator();
397        try {
398            iter.set((char)3);
399            fail("Expected IllegalStateException");
400        } catch(IllegalStateException e) {
401            // expected
402        }
403    }
404
405    public void testListIteratorSetAfterRemove() throws Exception {
406        CharListIterator iter = makeFullCharList().listIterator();
407        iter.next();
408        iter.remove();
409        try {            
410            iter.set((char)3);
411            fail("Expected IllegalStateException");
412        } catch(IllegalStateException e) {
413            // expected
414        }
415    }
416
417    public void testCharListToString() throws Exception {
418        String expected = "The quick brown fox jumped over the lazy dogs.";
419        CharList list = makeEmptyCharList();
420        for(int i=0;i<expected.length();i++) {
421            list.add(expected.charAt(i));
422        }
423        assertEquals(expected,list.toString());
424    }
425}