Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2008 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.collect;
     18 
     19 import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods;
     20 import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods;
     21 import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods;
     22 import static java.util.Arrays.asList;
     23 
     24 import com.google.common.annotations.GwtIncompatible;
     25 import com.google.common.collect.testing.AnEnum;
     26 import com.google.common.collect.testing.features.CollectionFeature;
     27 import com.google.common.collect.testing.features.CollectionSize;
     28 import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
     29 import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
     30 import com.google.common.collect.testing.google.TestEnumMultisetGenerator;
     31 import com.google.common.collect.testing.google.TestStringMultisetGenerator;
     32 
     33 import junit.framework.Test;
     34 import junit.framework.TestCase;
     35 import junit.framework.TestSuite;
     36 
     37 import java.util.Arrays;
     38 import java.util.Collections;
     39 import java.util.List;
     40 
     41 /**
     42  * Collection tests for {@link Multiset} implementations.
     43  *
     44  * @author Jared Levy
     45  */
     46 @GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version
     47 public class MultisetCollectionTest extends TestCase {
     48 
     49   public static Test suite() {
     50     TestSuite suite = new TestSuite();
     51 
     52     suite.addTest(MultisetTestSuiteBuilder.using(hashMultisetGenerator())
     53         .withFeatures(CollectionSize.ANY,
     54             CollectionFeature.ALLOWS_NULL_VALUES,
     55             CollectionFeature.GENERAL_PURPOSE)
     56         .named("HashMultiset")
     57         .createTestSuite());
     58 
     59     suite.addTest(MultisetTestSuiteBuilder.using(
     60         unmodifiableMultisetGenerator())
     61         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
     62             CollectionFeature.ALLOWS_NULL_QUERIES)
     63         .named("UnmodifiableTreeMultiset")
     64         .createTestSuite());
     65 
     66     suite.addTest(SortedMultisetTestSuiteBuilder
     67         .using(new TestStringMultisetGenerator() {
     68           @Override
     69           protected Multiset<String> create(String[] elements) {
     70             return TreeMultiset.create(Arrays.asList(elements));
     71           }
     72 
     73           @Override
     74           public List<String> order(List<String> insertionOrder) {
     75             return Ordering.natural().sortedCopy(insertionOrder);
     76           }
     77         })
     78         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
     79             CollectionFeature.GENERAL_PURPOSE,
     80             CollectionFeature.ALLOWS_NULL_QUERIES)
     81         .named("TreeMultiset, Ordering.natural")
     82         .createTestSuite());
     83 
     84 
     85     suite.addTest(SortedMultisetTestSuiteBuilder
     86         .using(new TestStringMultisetGenerator() {
     87           @Override
     88           protected Multiset<String> create(String[] elements) {
     89             Multiset<String> result = TreeMultiset.create(Ordering.natural().nullsFirst());
     90             result.addAll(Arrays.asList(elements));
     91             return result;
     92           }
     93 
     94           @Override
     95           public List<String> order(List<String> insertionOrder) {
     96             return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
     97           }
     98         })
     99         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
    100             CollectionFeature.GENERAL_PURPOSE,
    101             CollectionFeature.ALLOWS_NULL_VALUES)
    102         .named("TreeMultiset, Ordering.natural.nullsFirst")
    103         .createTestSuite());
    104 
    105     suite.addTest(MultisetTestSuiteBuilder.using(forSetGenerator())
    106         .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
    107             CollectionFeature.REMOVE_OPERATIONS)
    108         .suppressing(getReadsDuplicateInitializingMethods())
    109         .suppressing(getSetCountDuplicateInitializingMethods())
    110         .suppressing(getIteratorDuplicateInitializingMethods())
    111         .named("ForSetMultiset")
    112         .createTestSuite());
    113 
    114     suite.addTest(MultisetTestSuiteBuilder.using(
    115         concurrentMultisetGenerator())
    116         .withFeatures(CollectionSize.ANY,
    117             CollectionFeature.GENERAL_PURPOSE,
    118             CollectionFeature.ALLOWS_NULL_QUERIES)
    119         .named("ConcurrentHashMultiset")
    120         .createTestSuite());
    121 
    122     suite.addTest(MultisetTestSuiteBuilder.using(enumMultisetGenerator())
    123         .withFeatures(CollectionSize.ANY,
    124             CollectionFeature.KNOWN_ORDER,
    125             CollectionFeature.GENERAL_PURPOSE,
    126             CollectionFeature.ALLOWS_NULL_QUERIES)
    127         .named("EnumMultiset")
    128         .createTestSuite());
    129 
    130     suite.addTest(MultisetTestSuiteBuilder.using(intersectionGenerator())
    131         .withFeatures(CollectionSize.ANY,
    132             CollectionFeature.ALLOWS_NULL_VALUES,
    133             CollectionFeature.KNOWN_ORDER)
    134         .named("IntersectionMultiset")
    135         .createTestSuite());
    136 
    137     suite.addTest(SortedMultisetTestSuiteBuilder.using(unmodifiableSortedMultisetGenerator())
    138         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
    139             CollectionFeature.ALLOWS_NULL_QUERIES)
    140         .named("UnmodifiableSortedTreeMultiset")
    141         .createTestSuite());
    142 
    143     return suite;
    144   }
    145 
    146   private static TestStringMultisetGenerator hashMultisetGenerator() {
    147     return new TestStringMultisetGenerator() {
    148       @Override protected Multiset<String> create(String[] elements) {
    149         return HashMultiset.create(asList(elements));
    150       }
    151     };
    152   }
    153 
    154   private static TestStringMultisetGenerator unmodifiableMultisetGenerator() {
    155     return new TestStringMultisetGenerator() {
    156       @Override protected Multiset<String> create(String[] elements) {
    157         return Multisets.unmodifiableMultiset(
    158             TreeMultiset.create(asList(elements)));
    159       }
    160       @Override public List<String> order(List<String> insertionOrder) {
    161         Collections.sort(insertionOrder);
    162         return insertionOrder;
    163       }
    164     };
    165   }
    166 
    167   private static TestStringMultisetGenerator unmodifiableSortedMultisetGenerator() {
    168     return new TestStringMultisetGenerator() {
    169       @Override protected Multiset<String> create(String[] elements) {
    170         return Multisets.unmodifiableSortedMultiset(
    171             TreeMultiset.create(asList(elements)));
    172       }
    173       @Override public List<String> order(List<String> insertionOrder) {
    174         Collections.sort(insertionOrder);
    175         return insertionOrder;
    176       }
    177     };
    178   }
    179 
    180   private static TestStringMultisetGenerator forSetGenerator() {
    181     return new TestStringMultisetGenerator() {
    182       @Override protected Multiset<String> create(String[] elements) {
    183         return Multisets.forSet(Sets.newHashSet(elements));
    184       }
    185     };
    186   }
    187 
    188   private static TestStringMultisetGenerator concurrentMultisetGenerator() {
    189     return new TestStringMultisetGenerator() {
    190       @Override protected Multiset<String> create(String[] elements) {
    191         return ConcurrentHashMultiset.create(asList(elements));
    192       }
    193     };
    194   }
    195 
    196   private static TestEnumMultisetGenerator enumMultisetGenerator() {
    197     return new TestEnumMultisetGenerator() {
    198       @Override protected Multiset<AnEnum> create(AnEnum[] elements) {
    199         return (elements.length == 0)
    200             ? EnumMultiset.create(AnEnum.class)
    201             : EnumMultiset.create(asList(elements));
    202       }
    203     };
    204   }
    205 
    206   private static TestStringMultisetGenerator intersectionGenerator() {
    207     return new TestStringMultisetGenerator() {
    208       @Override protected Multiset<String> create(String[] elements) {
    209         Multiset<String> multiset1 = LinkedHashMultiset.create();
    210         Multiset<String> multiset2 = LinkedHashMultiset.create();
    211         multiset1.add("only1");
    212         multiset2.add("only2");
    213         for (int i = 0; i < elements.length; i++) {
    214           multiset1.add(elements[i]);
    215           multiset2.add(elements[elements.length - 1 - i]);
    216         }
    217         if (elements.length > 0) {
    218           multiset1.add(elements[0]);
    219         }
    220         if (elements.length > 1) {
    221           /*
    222            * When a test requests a multiset with duplicates, our plan of
    223            * "add an extra item 0 to A and an extra item 1 to B" really means
    224            * "add an extra item 0 to A and B," which isn't what we want.
    225            */
    226           if (!elements[0].equals(elements[1])) {
    227             multiset2.add(elements[1], 2);
    228           }
    229         }
    230         return Multisets.intersection(multiset1, multiset2);
    231       }
    232     };
    233   }
    234 }
    235