• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
suite()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 
unmodifiableMultisetGenerator()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