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