View Javadoc
1   package org.djutils.immutablecollections;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertFalse;
5   import static org.junit.Assert.assertTrue;
6   
7   import java.util.Arrays;
8   import java.util.Collection;
9   import java.util.HashSet;
10  import java.util.Iterator;
11  import java.util.Set;
12  import java.util.function.Consumer;
13  
14  import org.junit.Test;
15  
16  /**
17   * Test immutable list.
18   * <p>
19   * Copyright (c) 2013-2022 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
20   * BSD-style license. See <a href="https://djutils.org/docs/current/djutils/licenses.html">DJUTILS License</a>.
21   * <p>
22   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Feb 26, 2019 <br>
23   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
24   * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
25   */
26  public class TestImmutableList
27  {
28      /** Accumulator for forEach test. */
29      @SuppressWarnings("checkstyle:visibilitymodifier")
30      int sum;
31  
32      /**
33       * Test the immutable list class.
34       */
35      @SuppressWarnings({"unchecked", "unlikely-arg-type"})
36      @Test
37      public void testImmutableList()
38      {
39          Integer[] values = new Integer[] {2, 5, 1, 2, 4, 9};
40          ImmutableList<Integer> il = new ImmutableArrayList<>(Arrays.asList(values));
41          assertTrue("toString returns something descriptive", il.toString().startsWith("ImmutableArrayList ["));
42          assertTrue("default is to copy", il.isCopy());
43          assertFalse("default is not to wrap", il.isWrap());
44          ImmutableList<Integer> il2 = new ImmutableArrayList<>(Arrays.asList(values), Immutable.COPY);
45          assertTrue("COPY means copy", il2.isCopy());
46          il2 = new ImmutableArrayList<>(Arrays.asList(values), Immutable.WRAP);
47          assertTrue("COPY means copy", il2.isWrap());
48          il2 = new ImmutableArrayList<Integer>((ImmutableAbstractCollection<Integer>) il);
49          assertTrue("default is to copy", il2.isCopy());
50          assertEquals("has same size", il.size(), il2.size());
51          il2 = new ImmutableArrayList<Integer>((ImmutableAbstractList<Integer>) il);
52          assertTrue("default is to copy", il2.isCopy());
53          assertEquals("has same size", il.size(), il2.size());
54          il2 = new ImmutableArrayList<Integer>((ImmutableAbstractList<Integer>) il, Immutable.COPY);
55          assertTrue("COPY means copy", il2.isCopy());
56          assertEquals("has same size", il.size(), il2.size());
57          il2 = new ImmutableArrayList<Integer>((ImmutableAbstractList<Integer>) il, Immutable.WRAP);
58          assertTrue("WRAP means wrap", il2.isWrap());
59          assertFalse("WRAP is not copy", il2.isCopy());
60          assertTrue("Wrap is wrap", il2.isWrap());
61          assertEquals("has same size", il.size(), il2.size());
62          il2 = il.subList(2, 4);
63          assertEquals("sublist has length 2", 2, il2.size());
64          for (int index = 0; index < il2.size(); index++)
65          {
66              assertEquals("sub list element matches", values[index + 2], il2.get(index));
67          }
68          assertEquals("position of first 2", 0, il.indexOf(Integer.valueOf(2)));
69          assertEquals("position of first (and only) 4", 4, il.indexOf(Integer.valueOf(4)));
70          assertEquals("position of last 2", 3, il.lastIndexOf(Integer.valueOf(2)));
71          assertTrue("contains 1", il.contains(Integer.valueOf(1)));
72          assertFalse("does not contain 123", il.contains(Integer.valueOf(123)));
73          Object[] outObject = il.toArray();
74          assertEquals("length of toArray matches size of what went in", values.length, outObject.length);
75          for (int index = 0; index < outObject.length; index++)
76          {
77              assertEquals("objects in out match what went in", values[index], outObject[index]);
78          }
79          Integer[] outInteger = il.toArray(new Integer[0]);
80          assertEquals("length of toArray matches size of what went in", values.length, outInteger.length);
81          for (int index = 0; index < outInteger.length; index++)
82          {
83              assertEquals("objects in out match what went in", values[index], outInteger[index]);
84          }
85          for (int index = 0; index < values.length; index++)
86          {
87              assertEquals("values can be retrieved one by one", values[index], il.get(index));
88          }
89          ImmutableIterator<Integer> ii = il.iterator();
90          assertTrue("toString method of iterator returns something descriptive",
91                  ii.toString().startsWith("ImmutableIterator ["));
92          for (int index = 0; index < values.length; index++)
93          {
94              assertTrue(ii.hasNext());
95              Integer got = ii.next();
96              assertEquals("iterator returned next value", values[index], got);
97          }
98          assertFalse("iterator has run out", ii.hasNext());
99          this.sum = 0;
100         il.forEach(new Consumer<Integer>()
101         {
102 
103             @Override
104             public void accept(final Integer t)
105             {
106                 TestImmutableList.this.sum += t;
107             }
108         });
109         // compute the result the old fashioned way
110         int expectedSum = 0;
111         for (int index = 0; index < values.length; index++)
112         {
113             expectedSum += values[index];
114         }
115         assertEquals("sum matches", expectedSum, this.sum);
116         assertTrue("contains all", il.containsAll(Arrays.asList(values)));
117         assertFalse("not contains all", il.containsAll(Arrays.asList(new Integer[] {1, 2, 3})));
118         assertTrue("contains all", il.containsAll(new ImmutableArrayList<Integer>(Arrays.asList(values))));
119         assertFalse("not contains all",
120                 il.containsAll(new ImmutableArrayList<Integer>(Arrays.asList(new Integer[] {1, 2, 3}))));
121         outObject = il.stream().toArray();
122         assertEquals("length of toArray matches size of what went in", values.length, outObject.length);
123         for (int index = 0; index < outObject.length; index++)
124         {
125             assertEquals("objects in out match what went in", values[index], outObject[index]);
126         }
127         assertTrue("toString returns something descriptive", il.toString().startsWith("ImmutableArrayList ["));
128         assertEquals("size returns correct value", values.length, il.size());
129         assertFalse("list is not empty", il.isEmpty());
130         assertTrue("emty list reports it is empty", new ImmutableArrayList<Integer>(Arrays.asList(new Integer[] {})).isEmpty());
131         assertTrue("equal to itself", il.equals(il));
132         assertFalse("not equal to null", il.equals(null));
133         assertFalse("not equal to some string", il.equals("abc"));
134         assertFalse("not equal to a (shorter) sub list of itself", il.equals(il2));
135         il2 = new ImmutableArrayList<Integer>(Arrays.asList(values));
136         assertTrue("equal to another one that has the exact same contents", il.equals(il2));
137         assertEquals("hashcodes should match", il.hashCode(), il2.hashCode());
138 
139         // Testing the spliterator and parallelstream will have to wait until I understand how to write a unit test for that
140     }
141 
142     /**
143      * Test the ImmutableHashMap class.
144      */
145     @SuppressWarnings({"unchecked", "unlikely-arg-type"})
146     @Test
147     public void testImmutableHashSet()
148     {
149         Integer[] values = new Integer[] {2, 5, 1, 12, 4, 9}; // all different
150         ImmutableSet<Integer> is = new ImmutableHashSet<>(Arrays.asList(values));
151         assertTrue("default is to copy", is.isCopy());
152         assertFalse("default is not to wrap", is.isWrap());
153         ImmutableSet<Integer> is2 = new ImmutableHashSet<>(new HashSet<Integer>(Arrays.asList(values)), Immutable.COPY);
154         assertTrue("COPY means copy", is2.isCopy());
155         is2 = new ImmutableHashSet<>(new HashSet<Integer>(Arrays.asList(values)), Immutable.WRAP);
156         assertTrue("COPY means copy", is2.isWrap());
157         is2 = new ImmutableHashSet<Integer>((ImmutableAbstractCollection<Integer>) is);
158         assertTrue("default is to copy", is2.isCopy());
159         assertEquals("has same size", is.size(), is2.size());
160         is2 = new ImmutableHashSet<Integer>((ImmutableAbstractSet<Integer>) is);
161         assertTrue("default is to copy", is2.isCopy());
162         assertEquals("has same size", is.size(), is2.size());
163         is2 = new ImmutableHashSet<Integer>((ImmutableAbstractSet<Integer>) is, Immutable.COPY);
164         assertTrue("COPY means copy", is2.isCopy());
165         assertEquals("has same size", is.size(), is2.size());
166         is2 = new ImmutableHashSet<Integer>((ImmutableAbstractSet<Integer>) is, Immutable.WRAP);
167         assertTrue("WRAP means wrap", is2.isWrap());
168         assertEquals("has same size", is.size(), is2.size());
169         assertTrue("contains 1", is.contains(Integer.valueOf(1)));
170         assertFalse("does not contain 123", is.contains(Integer.valueOf(123)));
171         Object[] outObject = is.toArray();
172         assertEquals("length of toArray matches size of what went in", values.length, outObject.length);
173         Set<Integer> verify = new HashSet<>(Arrays.asList(values));
174         for (int index = 0; index < outObject.length; index++)
175         {
176             assertTrue("Each object matches an object that went in", verify.remove(outObject[index]));
177         }
178         assertTrue("All objects were matched", verify.isEmpty());
179         Integer[] outInteger = is.toArray(new Integer[0]);
180         assertEquals("length of toArray matches size of what went in", values.length, outInteger.length);
181         verify = new HashSet<>(Arrays.asList(values));
182         for (int index = 0; index < outInteger.length; index++)
183         {
184             assertTrue("Each object matches an object that went in", verify.remove(outInteger[index]));
185         }
186         assertTrue("All objects were matched", verify.isEmpty());
187         verify = new HashSet<>(Arrays.asList(values));
188         ImmutableIterator<Integer> ii = is.iterator();
189         for (int index = 0; index < values.length; index++)
190         {
191             assertTrue(ii.hasNext());
192             Integer got = ii.next();
193             assertTrue("Each object matches an object that went in", verify.remove(got));
194         }
195         assertFalse("iterator has run out", ii.hasNext());
196         assertTrue("All objects were matched", verify.isEmpty());
197         this.sum = 0;
198         is.forEach(new Consumer<Integer>()
199         {
200 
201             @Override
202             public void accept(final Integer t)
203             {
204                 TestImmutableList.this.sum += t;
205             }
206         });
207         // compute the result the old fashioned way
208         int expectedSum = 0;
209         for (int index = 0; index < values.length; index++)
210         {
211             expectedSum += values[index];
212         }
213         assertEquals("sum matches", expectedSum, this.sum);
214         assertTrue("contains all", is.containsAll(Arrays.asList(values)));
215         assertFalse("not contains all", is.containsAll(Arrays.asList(new Integer[] {1, 2, 3})));
216         assertTrue("contains all", is.containsAll(new ImmutableArrayList<Integer>(Arrays.asList(values))));
217         assertFalse("not contains all",
218                 is.containsAll(new ImmutableArrayList<Integer>(Arrays.asList(new Integer[] {1, 2, 3}))));
219         outObject = is.stream().toArray();
220         assertEquals("length of toArray matches size of what went in", values.length, outObject.length);
221         verify = new HashSet<>(Arrays.asList(values));
222         for (int index = 0; index < outObject.length; index++)
223         {
224             assertTrue("Each object matches an object that went in", verify.remove(outObject[index]));
225         }
226         assertTrue("All objects were matched", verify.isEmpty());
227         assertTrue("toString returns something descriptive", is.toString().startsWith("ImmutableHashSet ["));
228         assertEquals("size returns correct value", values.length, is.size());
229         assertFalse("list is not empty", is.isEmpty());
230         assertTrue("emty list reports it is empty", new ImmutableArrayList<Integer>(Arrays.asList(new Integer[] {})).isEmpty());
231         assertTrue("equal to itself", is.equals(is));
232         assertFalse("not equal to null", is.equals(null));
233         assertFalse("not equal to some string", is.equals("abc"));
234         is2 = new ImmutableHashSet<Integer>(Arrays.asList(Arrays.copyOfRange(values, 2, 4)));
235         assertFalse("not equal to a (smaller) sub set of itself", is.equals(is2));
236         is2 = new ImmutableHashSet<Integer>(new HashSet<>(Arrays.asList(values)));
237         assertTrue("equal to another one that has the exact same contents", is.equals(is2));
238         assertEquals("hashcodes should match", is.hashCode(), is2.hashCode());
239         Collection<Integer> collection = is.toCollection();
240         assertEquals("to collection result has correct number of values", is.size(), collection.size());
241         verify = new HashSet<>(Arrays.asList(values));
242         Iterator<Integer> i = collection.iterator();
243         while (i.hasNext())
244         {
245             assertTrue("Each object matches an object that went in", verify.remove(i.next()));
246         }
247         assertTrue("All objects were matched", verify.isEmpty());
248 
249         // Testing the spliterator and parallelstream will have to wait until I understand how to write a unit test for that
250     }
251 
252     /** test the of() methods. */
253     @Test
254     public void testOf()
255     {
256         ImmutableList<Integer> list = ImmutableList.of();
257         assertTrue(list.isEmpty());
258 
259         list = ImmutableList.of(1);
260         assertEquals(1, list.size());
261         assertEquals(1, list.get(0).intValue());
262 
263         list = ImmutableList.of(1, 2);
264         assertEquals(2, list.size());
265         assertEquals(1, list.get(0).intValue());
266         assertEquals(2, list.get(1).intValue());
267 
268         list = ImmutableList.of(1, 2, 3);
269         assertEquals(3, list.size());
270         assertEquals(1, list.get(0).intValue());
271         assertEquals(2, list.get(1).intValue());
272         assertEquals(3, list.get(2).intValue());
273 
274         list = ImmutableList.of(1, 2, 3, 4);
275         assertEquals(4, list.size());
276         assertEquals(1, list.get(0).intValue());
277         assertEquals(2, list.get(1).intValue());
278         assertEquals(3, list.get(2).intValue());
279         assertEquals(4, list.get(3).intValue());
280 
281         list = ImmutableList.of(1, 2, 3, 4, 5);
282         assertEquals(5, list.size());
283         assertEquals(1, list.get(0).intValue());
284         assertEquals(2, list.get(1).intValue());
285         assertEquals(3, list.get(2).intValue());
286         assertEquals(4, list.get(3).intValue());
287         assertEquals(5, list.get(4).intValue());
288 
289         list = ImmutableList.of(1, 2, 3, 4, 5, 6);
290         assertEquals(6, list.size());
291         assertEquals(1, list.get(0).intValue());
292         assertEquals(2, list.get(1).intValue());
293         assertEquals(3, list.get(2).intValue());
294         assertEquals(4, list.get(3).intValue());
295         assertEquals(5, list.get(4).intValue());
296         assertEquals(6, list.get(5).intValue());
297     }
298 }