View Javadoc
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  package org.apache.commons.collections4.collection;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collection;
27  import java.util.HashSet;
28  import java.util.Iterator;
29  import java.util.List;
30  import java.util.function.Predicate;
31  
32  import org.junit.jupiter.api.Test;
33  
34  /**
35   * Extension of {@link AbstractCollectionTest} for exercising the
36   * {@link CompositeCollection} implementation.
37   */
38  public class CompositeCollectionTest<E> extends AbstractCollectionTest<E> {
39  
40      protected CompositeCollection<E> c;
41  
42      protected Collection<E> one;
43  
44      protected Collection<E> two;
45  
46      public CompositeCollectionTest() {
47          super(CompositeCollectionTest.class.getSimpleName());
48      }
49  
50      @Override
51      public String getCompatibilityVersion() {
52          return "4";
53      }
54  
55      @Override
56      @SuppressWarnings("unchecked")
57      public E[] getFullElements() {
58          return (E[]) new Object[] { "1", "2", "3", "4" };
59      }
60  
61      /**
62       * Run stock collection tests without Mutator, so turn off add, remove
63       */
64      @Override
65      public boolean isAddSupported() {
66          return false;
67      }
68  
69      @Override
70      public boolean isRemoveSupported() {
71          return false;
72      }
73  
74      @Override
75      public Collection<E> makeConfirmedCollection() {
76          return new HashSet<>();
77      }
78  
79      /**
80       * Full collection should look like a collection with 4 elements
81       */
82      @Override
83      public Collection<E> makeConfirmedFullCollection() {
84          return new HashSet<>(Arrays.asList(getFullElements()));
85      }
86      /**
87       * Full collection consists of 4 collections, each with one element
88       */
89      @Override
90      public Collection<E> makeFullCollection() {
91          final CompositeCollection<E> compositeCollection = new CompositeCollection<>();
92          final E[] elements = getFullElements();
93          for (final E element : elements) {
94              final Collection<E> summand = new HashSet<>();
95              summand.add(element);
96              compositeCollection.addComposited(summand);
97          }
98          return compositeCollection;
99      }
100     /**
101      * Empty collection is empty composite
102      */
103     @Override
104     public Collection<E> makeObject() {
105         return new CompositeCollection<>();
106     }
107 
108     @SuppressWarnings("serial")
109     protected void setUpMutatorTest() {
110         setUpTest();
111         c.setMutator(new CompositeCollection.CollectionMutator<E>() {
112 
113             private static final long serialVersionUID = 1L;
114 
115             @Override
116             public boolean add(final CompositeCollection<E> composite, final List<Collection<E>> collections, final E obj) {
117                 for (final Collection<E> coll : collections) {
118                     coll.add(obj);
119                 }
120                 return true;
121             }
122 
123             @Override
124             public boolean addAll(final CompositeCollection<E> composite,
125                     final List<Collection<E>> collections, final Collection<? extends E> coll) {
126                 for (final Collection<E> collection : collections) {
127                     collection.addAll(coll);
128                 }
129                 return true;
130             }
131 
132             @Override
133             public boolean remove(final CompositeCollection<E> composite,
134                     final List<Collection<E>> collections, final Object obj) {
135                 for (final Collection<E> collection : collections) {
136                     collection.remove(obj);
137                 }
138                 return true;
139             }
140         });
141     }
142 
143     protected void setUpTest() {
144         c = new CompositeCollection<>();
145         one = new HashSet<>();
146         two = new HashSet<>();
147     }
148 
149     @Test
150     @SuppressWarnings({ "unchecked", "serial" })
151     public void testAddAllMutator() {
152         setUpTest();
153         c.setMutator(new CompositeCollection.CollectionMutator<E>() {
154             private static final long serialVersionUID = 1L;
155 
156             @Override
157             public boolean add(final CompositeCollection<E> composite,
158                     final List<Collection<E>> collections, final E obj) {
159                 for (final Collection<E> collection : collections) {
160                     collection.add(obj);
161                 }
162                 return true;
163             }
164 
165             @Override
166             public boolean addAll(final CompositeCollection<E> composite,
167                     final List<Collection<E>> collections, final Collection<? extends E> coll) {
168                 for (final Collection<E> collection : collections) {
169                     collection.addAll(coll);
170                 }
171                 return true;
172             }
173 
174             @Override
175             public boolean remove(final CompositeCollection<E> composite,
176                     final List<Collection<E>> collections, final Object obj) {
177                 return false;
178             }
179         });
180 
181         c.addComposited(one);
182         two.add((E) "foo");
183         c.addAll(two);
184         assertTrue(c.contains("foo"));
185         assertTrue(one.contains("foo"));
186     }
187 
188     @Test
189     @SuppressWarnings("unchecked")
190     public void testAddAllToCollection() {
191         setUpTest();
192         one.add((E) "1");
193         two.add((E) "2");
194         c.addComposited(one, two);
195         final Collection<E> toCollection = new HashSet<>(c);
196         assertTrue(toCollection.containsAll(c));
197         assertEquals(c.size(), toCollection.size());
198     }
199 
200     @Test
201     @SuppressWarnings({ "unchecked", "serial" })
202     public void testAddMutator() {
203         setUpTest();
204         c.setMutator(new CompositeCollection.CollectionMutator<E>() {
205             private static final long serialVersionUID = 1L;
206 
207             @Override
208             public boolean add(final CompositeCollection<E> composite,
209                     final List<Collection<E>> collections, final E obj) {
210                 for (final Collection<E> collection : collections) {
211                     collection.add(obj);
212                 }
213                 return true;
214             }
215 
216             @Override
217             public boolean addAll(final CompositeCollection<E> composite,
218                     final List<Collection<E>> collections, final Collection<? extends E> coll) {
219                 for (final Collection<E> collection : collections) {
220                     collection.addAll(coll);
221                 }
222                 return true;
223             }
224 
225             @Override
226             public boolean remove(final CompositeCollection<E> composite,
227                     final List<Collection<E>> collections, final Object obj) {
228                 return false;
229             }
230         });
231 
232         c.addComposited(one);
233         c.add((E) "foo");
234         assertTrue(c.contains("foo"));
235         assertTrue(one.contains("foo"));
236     }
237 
238     @Test
239     public void testAddNullList() {
240         final ArrayList<String> nullList = null;
241         final CompositeCollection<String> cc = new CompositeCollection<>();
242         cc.addComposited(nullList);
243         assertEquals(0, cc.size());
244     }
245 
246     @Test
247     public void testAddNullLists2Args() {
248         final ArrayList<String> nullList = null;
249         final CompositeCollection<String> cc = new CompositeCollection<>();
250         cc.addComposited(nullList, nullList);
251         assertEquals(0, cc.size());
252     }
253 
254     @Test
255     public void testAddNullListsVarArgs() {
256         final ArrayList<String> nullList = null;
257         final CompositeCollection<String> cc = new CompositeCollection<>();
258         cc.addComposited(nullList, nullList, nullList);
259         assertEquals(0, cc.size());
260     }
261 
262     @Test
263     @SuppressWarnings("unchecked")
264     public void testClear() {
265         setUpTest();
266         one.add((E) "1");
267         two.add((E) "2");
268         c.addComposited(one, two);
269         c.clear();
270         assertTrue(one.isEmpty());
271         assertTrue(two.isEmpty());
272         assertTrue(c.isEmpty());
273     }
274 
275     @Test
276     @SuppressWarnings("unchecked")
277     public void testContainsAll() {
278         setUpTest();
279         one.add((E) "1");
280         two.add((E) "1");
281         c.addComposited(one);
282         assertTrue(c.containsAll(two));
283         assertFalse(c.containsAll(null));
284     }
285 
286     @Test
287     @SuppressWarnings("unchecked")
288     public void testIsEmpty() {
289         setUpTest();
290         assertTrue(c.isEmpty());
291         final HashSet<E> empty = new HashSet<>();
292         c.addComposited(empty);
293         assertTrue(c.isEmpty());
294         empty.add((E) "a");
295         assertFalse(c.isEmpty());
296     }
297 
298     @Test
299     @SuppressWarnings("unchecked")
300     public void testIterator() {
301         setUpTest();
302         one.add((E) "1");
303         two.add((E) "2");
304         c.addComposited(one);
305         c.addComposited(two);
306         final Iterator<E> i = c.iterator();
307         E next = i.next();
308         assertTrue(c.contains(next));
309         assertTrue(one.contains(next));
310         next = i.next();
311         i.remove();
312         assertFalse(c.contains(next));
313         assertFalse(two.contains(next));
314     }
315 
316     @Test
317     @SuppressWarnings("unchecked")
318     public void testMultipleCollectionsSize() {
319         setUpTest();
320         final HashSet<E> set = new HashSet<>();
321         set.add((E) "a");
322         set.add((E) "b");
323         c.addComposited(set);
324         final HashSet<E> other = new HashSet<>();
325         other.add((E) "c");
326         c.addComposited(other);
327         assertEquals(set.size() + other.size(), c.size());
328     }
329 
330     @Test
331     @SuppressWarnings("unchecked")
332     public void testRemove() {
333         setUpMutatorTest();
334         one.add((E) "1");
335         two.add((E) "2");
336         two.add((E) "1");
337         c.addComposited(one, two);
338         c.remove("1");
339         assertFalse(c.contains("1"));
340         assertFalse(one.contains("1"));
341         assertFalse(two.contains("1"));
342     }
343 
344     @Test
345     @SuppressWarnings("unchecked")
346     public void testRemoveAll() {
347         setUpMutatorTest();
348         one.add((E) "1");
349         two.add((E) "2");
350         two.add((E) "1");
351         // need separate list to remove, as otherwise one clears itself
352         final Collection<E> removing = new ArrayList<>(one);
353         c.addComposited(one, two);
354         c.removeAll(removing);
355         assertFalse(c.contains("1"));
356         assertFalse(one.contains("1"));
357         assertFalse(two.contains("1"));
358         c.removeAll(null);
359         assertFalse(c.contains("1"));
360         assertFalse(one.contains("1"));
361         assertFalse(two.contains("1"));
362     }
363 
364     @Test
365     @SuppressWarnings("unchecked")
366     public void testRemoveComposited() {
367         setUpMutatorTest();
368         one.add((E) "1");
369         two.add((E) "2");
370         two.add((E) "1");
371         c.addComposited(one, two);
372         c.removeComposited(one);
373         assertTrue(c.contains("1"));
374         assertEquals(2, c.size());
375     }
376 
377     /**
378      */
379     @Test
380     @SuppressWarnings("unchecked")
381     public void testRemoveIf() {
382         setUpMutatorTest();
383         one.add((E) "1");
384         two.add((E) "2");
385         two.add((E) "1");
386         // need separate list to remove, as otherwise one clears itself
387         final Predicate<E> predicate = e -> e == "1";
388         c.addComposited(one, two);
389         c.removeIf(predicate);
390         assertFalse(c.contains("1"));
391         assertFalse(one.contains("1"));
392         assertFalse(two.contains("1"));
393         c.removeIf(null);
394         assertFalse(c.contains("1"));
395         assertFalse(one.contains("1"));
396         assertFalse(two.contains("1"));
397     }
398 
399     @Test
400     @SuppressWarnings("unchecked")
401     public void testRetainAll() {
402         setUpTest();
403         one.add((E) "1");
404         one.add((E) "2");
405         two.add((E) "1");
406         c.addComposited(one);
407         c.retainAll(two);
408         assertFalse(c.contains("2"));
409         assertFalse(one.contains("2"));
410         assertTrue(c.contains("1"));
411         assertTrue(one.contains("1"));
412         c.retainAll(null);
413         assertFalse(c.contains("2"));
414         assertFalse(one.contains("2"));
415         assertTrue(c.contains("1"));
416         assertTrue(one.contains("1"));
417     }
418 
419     @Test
420     @SuppressWarnings("unchecked")
421     public void testSize() {
422         setUpTest();
423         final HashSet<E> set = new HashSet<>();
424         set.add((E) "a");
425         set.add((E) "b");
426         c.addComposited(set);
427         assertEquals(set.size(), c.size());
428     }
429 
430     @Test
431     @SuppressWarnings("unchecked")
432     public void testToCollection() {
433         setUpTest();
434         one.add((E) "1");
435         two.add((E) "2");
436         c.addComposited(one, two);
437         final Collection<E> foo = c.toCollection();
438         assertTrue(foo.containsAll(c));
439         assertEquals(c.size(), foo.size());
440         one.add((E) "3");
441         assertFalse(foo.containsAll(c));
442     }
443 
444     /**
445      * Override testUnsupportedRemove, since the default impl expects removeAll,
446      * retainAll and iterator().remove to throw
447      */
448     @Test
449     @Override
450     public void testUnsupportedRemove() {
451         resetFull();
452 
453         assertThrows(UnsupportedOperationException.class, () -> getCollection().remove(null));
454 
455         verify();
456     }
457 
458 //    public void testCreate() throws Exception {
459 //        resetEmpty();
460 //        writeExternalFormToDisk((java.io.Serializable) getCollection(), "src/test/resources/data/test/CompositeCollection.emptyCollection.version4.obj");
461 //        resetFull();
462 //        writeExternalFormToDisk((java.io.Serializable) getCollection(), "src/test/resources/data/test/CompositeCollection.fullCollection.version4.obj");
463 //    }
464 
465 }