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