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.bag;
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.assertNotEquals;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.io.IOException;
26  import java.io.Serializable;
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.Collection;
30  import java.util.ConcurrentModificationException;
31  import java.util.HashSet;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.NoSuchElementException;
35  import java.util.Set;
36  
37  import org.apache.commons.collections4.Bag;
38  import org.apache.commons.collections4.BulkTest;
39  import org.apache.commons.collections4.collection.AbstractCollectionTest;
40  import org.apache.commons.collections4.set.AbstractSetTest;
41  import org.apache.commons.lang3.ArrayUtils;
42  import org.apache.commons.lang3.StringUtils;
43  import org.junit.jupiter.api.Test;
44  
45  /**
46   * Abstract test class for {@link org.apache.commons.collections4.Bag Bag} methods and contracts.
47   * <p>
48   * To use, simply extend this class, and implement
49   * the {@link #makeObject} method.
50   * <p>
51   * If your bag fails one of these tests by design,
52   * you may still use this base set of cases.  Simply override the
53   * test case (method) your bag fails.
54   * <p>
55   * <b>Note:</b> The Bag interface does not conform to the Collection interface
56   * so the generic collection tests from AbstractCollectionTest would normally fail.
57   * As a work-around since 4.0, a CollectionBag decorator can be used
58   * to make any Bag implementation comply to the Collection contract.
59   * <p>
60   * This abstract test class does wrap the concrete bag implementation
61   * with such a decorator, see the overridden {@link #resetEmpty()} and
62   * {@link #resetFull()} methods.
63   * <p>
64   * In addition to the generic collection tests (prefix testCollection) inherited
65   * from AbstractCollectionTest, there are test methods that test the "normal" Bag
66   * interface (prefix testBag). For Bag specific tests use the {@link #makeObject()} and
67   * {@link #makeFullCollection()} methods instead of {@link #resetEmpty()} and resetFull(),
68   * otherwise the collection will be wrapped by a {@link CollectionBag} decorator.
69   */
70  public abstract class AbstractBagTest<T> extends AbstractCollectionTest<T> {
71  
72      public class TestBagUniqueSet extends AbstractSetTest<T> {
73  
74          public TestBagUniqueSet() {
75              super(StringUtils.EMPTY);
76          }
77  
78          @Override
79          public T[] getFullElements() {
80              return AbstractBagTest.this.getFullElements();
81          }
82  
83          @Override
84          protected int getIterationBehaviour(){
85              return AbstractBagTest.this.getIterationBehaviour();
86          }
87  
88          @Override
89          public T[] getOtherElements() {
90              return AbstractBagTest.this.getOtherElements();
91          }
92  
93          @Override
94          public boolean isAddSupported() {
95              return false;
96          }
97  
98          @Override
99          public boolean isNullSupported() {
100             return AbstractBagTest.this.isNullSupported();
101         }
102 
103         @Override
104         public boolean isRemoveSupported() {
105             return false;
106         }
107 
108         @Override
109         public boolean isTestSerialization() {
110             return false;
111         }
112 
113         @Override
114         public Set<T> makeFullCollection() {
115             return AbstractBagTest.this.makeFullCollection().uniqueSet();
116         }
117 
118         @Override
119         public Set<T> makeObject() {
120             return AbstractBagTest.this.makeObject().uniqueSet();
121         }
122 
123         @Override
124         public void resetEmpty() {
125             AbstractBagTest.this.resetEmpty();
126             TestBagUniqueSet.this.setCollection(AbstractBagTest.this.getCollection().uniqueSet());
127             TestBagUniqueSet.this.setConfirmed(new HashSet<>(AbstractBagTest.this.getConfirmed()));
128         }
129 
130         @Override
131         public void resetFull() {
132             AbstractBagTest.this.resetFull();
133             TestBagUniqueSet.this.setCollection(AbstractBagTest.this.getCollection().uniqueSet());
134             TestBagUniqueSet.this.setConfirmed(new HashSet<>(AbstractBagTest.this.getConfirmed()));
135         }
136 
137         @Override
138         public void verify() {
139             super.verify();
140         }
141     }
142 
143     /**
144      * JUnit constructor.
145      *
146      * @param testName  the test class name
147      */
148     public AbstractBagTest(final String testName) {
149         super(testName);
150     }
151 
152     /**
153      * Bulk test {@link Bag#uniqueSet()}.  This method runs through all of
154      * the tests in {@link AbstractSetTest}.
155      * After modification operations, {@link #verify()} is invoked to ensure
156      * that the bag and the other collection views are still valid.
157      *
158      * @return a {@link AbstractSetTest} instance for testing the bag's unique set
159      */
160     public BulkTest bulkTestBagUniqueSet() {
161         return new TestBagUniqueSet();
162     }
163 
164     /**
165      * Returns the {@link #collection} field cast to a {@link Bag}.
166      *
167      * @return the collection field as a Bag
168      */
169     @Override
170     public Bag<T> getCollection() {
171         return (Bag<T>) super.getCollection();
172     }
173 
174     /**
175      * Returns an empty {@link ArrayList}.
176      */
177     @Override
178     public Collection<T> makeConfirmedCollection() {
179         return new ArrayList<>();
180     }
181 
182     /**
183      * Returns a full collection.
184      */
185     @Override
186     public Collection<T> makeConfirmedFullCollection() {
187         final Collection<T> coll = makeConfirmedCollection();
188         coll.addAll(Arrays.asList(getFullElements()));
189         return coll;
190     }
191 
192     /**
193      * {@inheritDoc}
194      */
195     @Override
196     public Bag<T> makeFullCollection() {
197         final Bag<T> bag = makeObject();
198         bag.addAll(Arrays.asList(getFullElements()));
199         return bag;
200     }
201 
202     /**
203      * Return a new, empty bag to used for testing.
204      *
205      * @return the bag to be tested
206      */
207     @Override
208     public abstract Bag<T> makeObject();
209 
210     @Override
211     public void resetEmpty() {
212         this.setCollection(CollectionBag.collectionBag(makeObject()));
213         this.setConfirmed(makeConfirmedCollection());
214     }
215 
216     @Override
217     public void resetFull() {
218         this.setCollection(CollectionBag.collectionBag(makeFullCollection()));
219         this.setConfirmed(makeConfirmedFullCollection());
220     }
221 
222     @Test
223     @SuppressWarnings("unchecked")
224     public void testBagAdd() {
225         if (!isAddSupported()) {
226             return;
227         }
228 
229         final Bag<T> bag = makeObject();
230         bag.add((T) "A");
231         assertTrue(bag.contains("A"), "Should contain 'A'");
232         assertEquals(1, bag.getCount("A"), "Should have count of 1");
233         bag.add((T) "A");
234         assertTrue(bag.contains("A"), "Should contain 'A'");
235         assertEquals(2, bag.getCount("A"), "Should have count of 2");
236         bag.add((T) "B");
237         assertTrue(bag.contains("A"));
238         assertTrue(bag.contains("B"));
239     }
240 
241     @Test
242     @SuppressWarnings("unchecked")
243     public void testBagContains() {
244         if (!isAddSupported()) {
245             return;
246         }
247 
248         final Bag<T> bag = makeObject();
249 
250         assertFalse(bag.contains("A"), "Bag does not have at least 1 'A'");
251         assertFalse(bag.contains("B"), "Bag does not have at least 1 'B'");
252 
253         bag.add((T) "A");  // bag 1A
254         assertTrue(bag.contains("A"), "Bag has at least 1 'A'");
255         assertFalse(bag.contains("B"), "Bag does not have at least 1 'B'");
256 
257         bag.add((T) "A");  // bag 2A
258         assertTrue(bag.contains("A"), "Bag has at least 1 'A'");
259         assertFalse(bag.contains("B"), "Bag does not have at least 1 'B'");
260 
261         bag.add((T) "B");  // bag 2A,1B
262         assertTrue(bag.contains("A"), "Bag has at least 1 'A'");
263         assertTrue(bag.contains("B"), "Bag has at least 1 'B'");
264     }
265 
266     @Test
267     @SuppressWarnings("unchecked")
268     public void testBagContainsAll() {
269         if (!isAddSupported()) {
270             return;
271         }
272 
273         final Bag<T> bag = makeObject();
274         final List<String> known = new ArrayList<>();
275         final List<String> known1A = new ArrayList<>();
276         known1A.add("A");
277         final List<String> known2A = new ArrayList<>();
278         known2A.add("A");
279         known2A.add("A");
280         final List<String> known1B = new ArrayList<>();
281         known1B.add("B");
282         final List<String> known1A1B = new ArrayList<>();
283         known1A1B.add("A");
284         known1A1B.add("B");
285 
286         assertTrue(bag.containsAll(known), "Bag containsAll of empty");
287         assertFalse(bag.containsAll(known1A), "Bag does not containsAll of 1 'A'");
288         assertFalse(bag.containsAll(known2A), "Bag does not containsAll of 2 'A'");
289         assertFalse(bag.containsAll(known1B), "Bag does not containsAll of 1 'B'");
290         assertFalse(bag.containsAll(known1A1B), "Bag does not containsAll of 1 'A' 1 'B'");
291 
292         bag.add((T) "A");  // bag 1A
293         assertTrue(bag.containsAll(known), "Bag containsAll of empty");
294         assertTrue(bag.containsAll(known1A), "Bag containsAll of 1 'A'");
295         assertFalse(bag.containsAll(known2A), "Bag does not containsAll of 2 'A'");
296         assertFalse(bag.containsAll(known1B), "Bag does not containsAll of 1 'B'");
297         assertFalse(bag.containsAll(known1A1B), "Bag does not containsAll of 1 'A' 1 'B'");
298 
299         bag.add((T) "A");  // bag 2A
300         assertTrue(bag.containsAll(known), "Bag containsAll of empty");
301         assertTrue(bag.containsAll(known1A), "Bag containsAll of 1 'A'");
302         assertTrue(bag.containsAll(known2A), "Bag containsAll of 2 'A'");
303         assertFalse(bag.containsAll(known1B), "Bag does not containsAll of 1 'B'");
304         assertFalse(bag.containsAll(known1A1B), "Bag does not containsAll of 1 'A' 1 'B'");
305 
306         bag.add((T) "A");  // bag 3A
307         assertTrue(bag.containsAll(known), "Bag containsAll of empty");
308         assertTrue(bag.containsAll(known1A), "Bag containsAll of 1 'A'");
309         assertTrue(bag.containsAll(known2A), "Bag containsAll of 2 'A'");
310         assertFalse(bag.containsAll(known1B), "Bag does not containsAll of 1 'B'");
311         assertFalse(bag.containsAll(known1A1B), "Bag does not containsAll of 1 'A' 1 'B'");
312 
313         bag.add((T) "B");  // bag 3A1B
314         assertTrue(bag.containsAll(known), "Bag containsAll of empty");
315         assertTrue(bag.containsAll(known1A), "Bag containsAll of 1 'A'");
316         assertTrue(bag.containsAll(known2A), "Bag containsAll of 2 'A'");
317         assertTrue(bag.containsAll(known1B), "Bag containsAll of 1 'B'");
318         assertTrue(bag.containsAll(known1A1B), "Bag containsAll of 1 'A' 1 'B'");
319     }
320 
321     @Test
322     @SuppressWarnings("unchecked")
323     public void testBagEquals() {
324         if (!isAddSupported()) {
325             return;
326         }
327 
328         final Bag<T> bag = makeObject();
329         final Bag<T> bag2 = makeObject();
330         assertEquals(bag, bag2);
331         bag.add((T) "A");
332         assertNotEquals(bag, bag2);
333         bag2.add((T) "A");
334         assertEquals(bag, bag2);
335         bag.add((T) "A");
336         bag.add((T) "B");
337         bag.add((T) "B");
338         bag.add((T) "C");
339         bag2.add((T) "A");
340         bag2.add((T) "B");
341         bag2.add((T) "B");
342         bag2.add((T) "C");
343         assertEquals(bag, bag2);
344     }
345 
346     @Test
347     @SuppressWarnings("unchecked")
348     public void testBagEqualsHashBag() {
349         if (!isAddSupported()) {
350             return;
351         }
352 
353         final Bag<T> bag = makeObject();
354         final Bag<T> bag2 = new HashBag<>();
355         assertEquals(bag, bag2);
356         bag.add((T) "A");
357         assertNotEquals(bag, bag2);
358         bag2.add((T) "A");
359         assertEquals(bag, bag2);
360         bag.add((T) "A");
361         bag.add((T) "B");
362         bag.add((T) "B");
363         bag.add((T) "C");
364         bag2.add((T) "A");
365         bag2.add((T) "B");
366         bag2.add((T) "B");
367         bag2.add((T) "C");
368         assertEquals(bag, bag2);
369     }
370 
371     @Test
372     @SuppressWarnings("unchecked")
373     public void testBagEqualsSelf() {
374         final Bag<T> bag = makeObject();
375         assertEquals(bag, bag);
376 
377         if (!isAddSupported()) {
378             return;
379         }
380 
381         bag.add((T) "elt");
382         assertEquals(bag, bag);
383         bag.add((T) "elt"); // again
384         assertEquals(bag, bag);
385         bag.add((T) "elt2");
386         assertEquals(bag, bag);
387     }
388 
389     @Test
390     @SuppressWarnings("unchecked")
391     public void testBagHashCode() {
392         if (!isAddSupported()) {
393             return;
394         }
395 
396         final Bag<T> bag = makeObject();
397         final Bag<T> bag2 = makeObject();
398         assertEquals(0, bag.hashCode());
399         assertEquals(0, bag2.hashCode());
400         assertEquals(bag.hashCode(), bag2.hashCode());
401         bag.add((T) "A");
402         bag.add((T) "A");
403         bag.add((T) "B");
404         bag.add((T) "B");
405         bag.add((T) "C");
406         bag2.add((T) "A");
407         bag2.add((T) "A");
408         bag2.add((T) "B");
409         bag2.add((T) "B");
410         bag2.add((T) "C");
411         assertEquals(bag.hashCode(), bag2.hashCode());
412 
413         int total = 0;
414         total += "A".hashCode() ^ 2;
415         total += "B".hashCode() ^ 2;
416         total += "C".hashCode() ^ 1;
417         assertEquals(total, bag.hashCode());
418         assertEquals(total, bag2.hashCode());
419     }
420 
421     @Test
422     @SuppressWarnings("unchecked")
423     public void testBagIterator() {
424         if (!isAddSupported()) {
425             return;
426         }
427 
428         final Bag<T> bag = makeObject();
429         bag.add((T) "A");
430         bag.add((T) "A");
431         bag.add((T) "B");
432         assertEquals(3, bag.size(), "Bag should have 3 items");
433         final Iterator<T> i = bag.iterator();
434 
435         boolean foundA = false;
436         while (i.hasNext()) {
437             final String element = (String) i.next();
438             // ignore the first A, remove the second via Iterator.remove()
439             if (element.equals("A")) {
440                 if (!foundA) {
441                     foundA = true;
442                 } else {
443                     i.remove();
444                 }
445             }
446         }
447 
448         assertTrue(bag.contains("A"), "Bag should still contain 'A'");
449         assertEquals(2, bag.size(), "Bag should have 2 items");
450         assertEquals(1, bag.getCount("A"), "Bag should have 1 'A'");
451     }
452 
453     @Test
454     @SuppressWarnings("unchecked")
455     public void testBagIteratorFail() {
456         if (!isAddSupported()) {
457             return;
458         }
459 
460         final Bag<T> bag = makeObject();
461         bag.add((T) "A");
462         bag.add((T) "A");
463         bag.add((T) "B");
464         final Iterator<T> it = bag.iterator();
465         it.next();
466         bag.remove("A");
467 
468         assertThrows(ConcurrentModificationException.class, () -> it.next());
469     }
470 
471     @Test
472     @SuppressWarnings("unchecked")
473     public void testBagIteratorFailDoubleRemove() {
474         if (!isAddSupported()) {
475             return;
476         }
477 
478         final Bag<T> bag = makeObject();
479         bag.add((T) "A");
480         bag.add((T) "A");
481         bag.add((T) "B");
482         final Iterator<T> it = bag.iterator();
483         it.next();
484         it.next();
485         assertEquals(3, bag.size());
486         it.remove();
487         assertEquals(2, bag.size());
488 
489         assertThrows(IllegalStateException.class, () -> it.remove());
490 
491         assertEquals(2, bag.size());
492         it.next();
493         it.remove();
494         assertEquals(1, bag.size());
495     }
496 
497     @Test
498     @SuppressWarnings("unchecked")
499     public void testBagIteratorFailNoMore() {
500         if (!isAddSupported()) {
501             return;
502         }
503 
504         final Bag<T> bag = makeObject();
505         bag.add((T) "A");
506         bag.add((T) "A");
507         bag.add((T) "B");
508         final Iterator<T> it = bag.iterator();
509         it.next();
510         it.next();
511         it.next();
512 
513         assertThrows(NoSuchElementException.class, () -> it.next());
514     }
515 
516     @Test
517     @SuppressWarnings("unchecked")
518     public void testBagIteratorRemoveProtectsInvariants() {
519         if (!isAddSupported()) {
520             return;
521         }
522 
523         final Bag<T> bag = makeObject();
524         bag.add((T) "A");
525         bag.add((T) "A");
526         assertEquals(2, bag.size());
527         final Iterator<T> it = bag.iterator();
528         assertEquals("A", it.next());
529         assertTrue(it.hasNext());
530         it.remove();
531         assertEquals(1, bag.size());
532         assertTrue(it.hasNext());
533         assertEquals("A", it.next());
534         assertFalse(it.hasNext());
535         it.remove();
536         assertEquals(0, bag.size());
537         assertFalse(it.hasNext());
538 
539         final Iterator<T> it2 = bag.iterator();
540         assertFalse(it2.hasNext());
541     }
542 
543     @Test
544     @SuppressWarnings("unchecked")
545     public void testBagRemove() {
546         if (!isRemoveSupported()) {
547             return;
548         }
549 
550         final Bag<T> bag = makeObject();
551         bag.add((T) "A");
552         assertEquals(1, bag.getCount("A"), "Should have count of 1");
553         bag.remove("A");
554         assertEquals(0, bag.getCount("A"), "Should have count of 0");
555         bag.add((T) "A");
556         bag.add((T) "A");
557         bag.add((T) "A");
558         bag.add((T) "A");
559         assertEquals(4, bag.getCount("A"), "Should have count of 4");
560         bag.remove("A", 0);
561         assertEquals(4, bag.getCount("A"), "Should have count of 4");
562         bag.remove("A", 2);
563         assertEquals(2, bag.getCount("A"), "Should have count of 2");
564         bag.remove("A");
565         assertEquals(0, bag.getCount("A"), "Should have count of 0");
566     }
567 
568     @Test
569     @SuppressWarnings("unchecked")
570     public void testBagRemoveAll() {
571         if (!isRemoveSupported()) {
572             return;
573         }
574 
575         final Bag<T> bag = makeObject();
576         bag.add((T) "A", 2);
577         assertEquals(2, bag.getCount("A"), "Should have count of 2");
578         bag.add((T) "B");
579         bag.add((T) "C");
580         assertEquals(4, bag.size(), "Should have count of 4");
581         final List<String> delete = new ArrayList<>();
582         delete.add("A");
583         delete.add("B");
584         bag.removeAll(delete);
585         assertEquals(1, bag.getCount("A"), "Should have count of 1");
586         assertEquals(0, bag.getCount("B"), "Should have count of 0");
587         assertEquals(1, bag.getCount("C"), "Should have count of 1");
588         assertEquals(2, bag.size(), "Should have count of 2");
589     }
590 
591     @Test
592     @SuppressWarnings("unchecked")
593     public void testBagRetainAll() {
594         if (!isAddSupported()) {
595             return;
596         }
597 
598         final Bag<T> bag = makeObject();
599         bag.add((T) "A");
600         bag.add((T) "A");
601         bag.add((T) "A");
602         bag.add((T) "B");
603         bag.add((T) "B");
604         bag.add((T) "C");
605         final List<String> retains = new ArrayList<>();
606         retains.add("B");
607         retains.add("C");
608         bag.retainAll(retains);
609         assertEquals(2, bag.size(), "Should have 2 total items");
610     }
611 
612     @Test
613     @SuppressWarnings("unchecked")
614     public void testBagSize() {
615         if (!isAddSupported()) {
616             return;
617         }
618 
619         final Bag<T> bag = makeObject();
620         assertEquals(0, bag.size(), "Should have 0 total items");
621         bag.add((T) "A");
622         assertEquals(1, bag.size(), "Should have 1 total items");
623         bag.add((T) "A");
624         assertEquals(2, bag.size(), "Should have 2 total items");
625         bag.add((T) "A");
626         assertEquals(3, bag.size(), "Should have 3 total items");
627         bag.add((T) "B");
628         assertEquals(4, bag.size(), "Should have 4 total items");
629         bag.add((T) "B");
630         assertEquals(5, bag.size(), "Should have 5 total items");
631         bag.remove("A", 2);
632         assertEquals(1, bag.getCount("A"), "Should have 1 'A'");
633         assertEquals(3, bag.size(), "Should have 3 total items");
634         bag.remove("B");
635         assertEquals(1, bag.size(), "Should have 1 total item");
636     }
637 
638     @Test
639     @SuppressWarnings("unchecked")
640     public void testBagToArray() {
641         if (!isAddSupported()) {
642             return;
643         }
644 
645         final Bag<T> bag = makeObject();
646         bag.add((T) "A");
647         bag.add((T) "A");
648         bag.add((T) "B");
649         bag.add((T) "B");
650         bag.add((T) "C");
651         final Object[] array = bag.toArray();
652         int a = 0, b = 0, c = 0;
653         for (final Object element : array) {
654             a += element.equals("A") ? 1 : 0;
655             b += element.equals("B") ? 1 : 0;
656             c += element.equals("C") ? 1 : 0;
657         }
658         assertEquals(2, a);
659         assertEquals(2, b);
660         assertEquals(1, c);
661     }
662 
663     @Test
664     @SuppressWarnings("unchecked")
665     public void testBagToArrayPopulate() {
666         if (!isAddSupported()) {
667             return;
668         }
669 
670         final Bag<T> bag = makeObject();
671         bag.add((T) "A");
672         bag.add((T) "A");
673         bag.add((T) "B");
674         bag.add((T) "B");
675         bag.add((T) "C");
676         final String[] array = bag.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
677         int a = 0, b = 0, c = 0;
678         for (final String element : array) {
679             a += element.equals("A") ? 1 : 0;
680             b += element.equals("B") ? 1 : 0;
681             c += element.equals("C") ? 1 : 0;
682         }
683         assertEquals(2, a);
684         assertEquals(2, b);
685         assertEquals(1, c);
686     }
687 
688     /**
689      * Compare the current serialized form of the Bag
690      * against the canonical version in SCM.
691      */
692     @Test
693     public void testEmptyBagCompatibility() throws IOException, ClassNotFoundException {
694         // test to make sure the canonical form has been preserved
695         final Bag<T> bag = makeObject();
696         if (bag instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
697             final Bag<?> bag2 = (Bag<?>) readExternalFormFromDisk(getCanonicalEmptyCollectionName(bag));
698             assertTrue(bag2.isEmpty(), "Bag is empty");
699             assertEquals(bag, bag2);
700         }
701     }
702 
703     /**
704      * Compare the current serialized form of the Bag
705      * against the canonical version in SCM.
706      */
707     @Test
708     public void testFullBagCompatibility() throws IOException, ClassNotFoundException {
709         // test to make sure the canonical form has been preserved
710         final Bag<T> bag = makeFullCollection();
711         if (bag instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
712             final Bag<?> bag2 = (Bag<?>) readExternalFormFromDisk(getCanonicalFullCollectionName(bag));
713             assertEquals(bag.size(), bag2.size(), "Bag is the right size");
714             assertEquals(bag, bag2);
715         }
716     }
717 
718 }