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 java.util.Arrays.asList;
     20 
     21 import com.google.common.annotations.GwtIncompatible;
     22 import com.google.common.base.Objects;
     23 import com.google.common.base.Predicate;
     24 import com.google.common.base.Predicates;
     25 import com.google.common.collect.testing.features.CollectionFeature;
     26 import com.google.common.collect.testing.features.CollectionSize;
     27 import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
     28 import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
     29 import com.google.common.collect.testing.google.TestStringMultisetGenerator;
     30 
     31 import junit.framework.Test;
     32 import junit.framework.TestCase;
     33 import junit.framework.TestSuite;
     34 
     35 import java.util.ArrayList;
     36 import java.util.Collections;
     37 import java.util.List;
     38 
     39 /**
     40  * Collection tests on wrappers from {@link Multisets}.
     41  *
     42  * @author Jared Levy
     43  */
     44 @GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version
     45 public class MultisetsCollectionTest extends TestCase {
     46   public static Test suite() {
     47     TestSuite suite = new TestSuite();
     48 
     49     suite.addTest(MultisetTestSuiteBuilder.using(
     50         unmodifiableMultisetGenerator())
     51         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
     52             CollectionFeature.SERIALIZABLE,
     53             CollectionFeature.ALLOWS_NULL_QUERIES)
     54         .named("Multisets.unmodifiableMultiset[LinkedHashMultiset]")
     55         .createTestSuite());
     56 
     57     suite.addTest(SortedMultisetTestSuiteBuilder.using(unmodifiableSortedMultisetGenerator())
     58         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
     59             CollectionFeature.ALLOWS_NULL_QUERIES)
     60         .named("Multisets.unmodifiableMultiset[TreeMultiset]")
     61         .createTestSuite());
     62 
     63     suite.addTest(MultisetTestSuiteBuilder.using(unionGenerator())
     64         .withFeatures(CollectionSize.ANY,
     65             CollectionFeature.ALLOWS_NULL_VALUES)
     66         .named("Multisets.union")
     67         .createTestSuite());
     68 
     69     suite.addTest(MultisetTestSuiteBuilder.using(intersectionGenerator())
     70         .withFeatures(CollectionSize.ANY,
     71             CollectionFeature.ALLOWS_NULL_VALUES,
     72             CollectionFeature.KNOWN_ORDER)
     73         .named("Multisets.intersection")
     74         .createTestSuite());
     75 
     76     suite.addTest(MultisetTestSuiteBuilder.using(sumGenerator())
     77         .withFeatures(CollectionSize.ANY,
     78             CollectionFeature.ALLOWS_NULL_VALUES)
     79         .named("Multisets.sum")
     80         .createTestSuite());
     81 
     82     suite.addTest(MultisetTestSuiteBuilder.using(differenceGenerator())
     83         .withFeatures(CollectionSize.ANY,
     84             CollectionFeature.ALLOWS_NULL_VALUES,
     85             CollectionFeature.KNOWN_ORDER)
     86         .named("Multisets.difference")
     87         .createTestSuite());
     88 
     89     suite.addTest(MultisetTestSuiteBuilder.using(filteredGenerator())
     90         .withFeatures(CollectionSize.ANY,
     91             CollectionFeature.ALLOWS_NULL_VALUES,
     92             CollectionFeature.KNOWN_ORDER,
     93             CollectionFeature.SUPPORTS_ADD,
     94             CollectionFeature.SUPPORTS_REMOVE)
     95         .named("Multiset.filter[Multiset, Predicate]")
     96         .createTestSuite());
     97 
     98     return suite;
     99   }
    100 
    101   private static TestStringMultisetGenerator unmodifiableMultisetGenerator() {
    102     return new TestStringMultisetGenerator() {
    103       @Override protected Multiset<String> create(String[] elements) {
    104         return Multisets.unmodifiableMultiset(
    105             LinkedHashMultiset.create(asList(elements)));
    106       }
    107       @Override public List<String> order(List<String> insertionOrder) {
    108         List<String> order = new ArrayList<String>();
    109         for (String s : insertionOrder) {
    110           int index = order.indexOf(s);
    111           if (index == -1) {
    112             order.add(s);
    113           } else {
    114             order.add(index, s);
    115           }
    116         }
    117         return order;
    118       }
    119     };
    120   }
    121 
    122   private static TestStringMultisetGenerator unmodifiableSortedMultisetGenerator() {
    123     return new TestStringMultisetGenerator() {
    124       @Override protected Multiset<String> create(String[] elements) {
    125         return Multisets.unmodifiableSortedMultiset(
    126             TreeMultiset.create(asList(elements)));
    127       }
    128       @Override public List<String> order(List<String> insertionOrder) {
    129         Collections.sort(insertionOrder);
    130         return insertionOrder;
    131       }
    132     };
    133   }
    134 
    135   private static TestStringMultisetGenerator unionGenerator() {
    136     return new TestStringMultisetGenerator() {
    137       @Override
    138       protected Multiset<String> create(String[] elements) {
    139         Multiset<String> multiset1 = LinkedHashMultiset.create();
    140         Multiset<String> multiset2 = LinkedHashMultiset.create();
    141         for (int i = 0; i < elements.length; i++) {
    142           String element = elements[i];
    143           if (multiset1.contains(element) ||
    144               multiset2.contains(element)) {
    145             // add to both; the one already containing it will have more
    146             multiset1.add(element);
    147             multiset2.add(element);
    148           } else if (i % 2 == 0) {
    149             multiset1.add(elements[i]);
    150           } else {
    151             multiset2.add(elements[i]);
    152           }
    153         }
    154         return Multisets.union(multiset1, multiset2);
    155       }
    156     };
    157   }
    158 
    159   private static TestStringMultisetGenerator intersectionGenerator() {
    160     return new TestStringMultisetGenerator() {
    161       @Override protected Multiset<String> create(String[] elements) {
    162         Multiset<String> multiset1 = LinkedHashMultiset.create();
    163         Multiset<String> multiset2 = LinkedHashMultiset.create();
    164         multiset1.add("only1");
    165         multiset2.add("only2");
    166         for (int i = 0; i < elements.length; i++) {
    167           multiset1.add(elements[i]);
    168           multiset2.add(elements[elements.length - 1 - i]);
    169         }
    170         if (elements.length > 0) {
    171           multiset1.add(elements[0]);
    172         }
    173         if (elements.length > 1) {
    174           /*
    175            * When a test requests a multiset with duplicates, our plan of
    176            * "add an extra item 0 to A and an extra item 1 to B" really means
    177            * "add an extra item 0 to A and B," which isn't what we want.
    178            */
    179           if (!Objects.equal(elements[0], elements[1])) {
    180             multiset2.add(elements[1], 2);
    181           }
    182         }
    183         return Multisets.intersection(multiset1, multiset2);
    184       }
    185     };
    186   }
    187 
    188   private static TestStringMultisetGenerator sumGenerator() {
    189     return new TestStringMultisetGenerator() {
    190       @Override protected Multiset<String> create(String[] elements) {
    191         Multiset<String> multiset1 = LinkedHashMultiset.create();
    192         Multiset<String> multiset2 = LinkedHashMultiset.create();
    193         for (int i = 0; i < elements.length; i++) {
    194           // add to either; sum should contain all
    195           if (i % 2 == 0) {
    196             multiset1.add(elements[i]);
    197           } else {
    198             multiset2.add(elements[i]);
    199           }
    200         }
    201         return Multisets.sum(multiset1, multiset2);
    202       }
    203     };
    204   }
    205 
    206   private static TestStringMultisetGenerator differenceGenerator() {
    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("equalIn1");
    212         multiset1.add("fewerIn1");
    213         multiset2.add("equalIn1");
    214         multiset2.add("fewerIn1", 3);
    215         multiset2.add("onlyIn2", 2);
    216         for (int i = 0; i < elements.length; i++) {
    217           // add 1 more copy of each element to multiset1 than multiset2
    218           multiset1.add(elements[i], i + 2);
    219           multiset2.add(elements[i], i + 1);
    220         }
    221         return Multisets.difference(multiset1, multiset2);
    222       }
    223     };
    224   }
    225 
    226   private static final Multiset<String> ELEMENTS_TO_FILTER_OUT = ImmutableMultiset.of(
    227       "foobar", "bazfoo", "foobar", "foobar");
    228 
    229   private static final Predicate<String> PREDICATE =
    230       Predicates.not(Predicates.in(ELEMENTS_TO_FILTER_OUT));
    231 
    232   private static TestStringMultisetGenerator filteredGenerator() {
    233     return new TestStringMultisetGenerator() {
    234       @Override
    235       protected Multiset<String> create(String[] elements) {
    236         Multiset<String> multiset = LinkedHashMultiset.create();
    237         Collections.addAll(multiset, elements);
    238         multiset.addAll(ELEMENTS_TO_FILTER_OUT);
    239         return Multisets.filter(multiset, PREDICATE);
    240       }
    241 
    242       @Override
    243       public List<String> order(List<String> insertionOrder) {
    244         return Lists.newArrayList(LinkedHashMultiset.create(insertionOrder));
    245       }
    246     };
    247   }
    248 }
    249