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