1 /* 2 * Copyright (C) 2007 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 com.google.common.truth.Truth.assertThat; 20 21 import com.google.common.annotations.GwtCompatible; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.annotations.J2ktIncompatible; 24 import com.google.common.collect.testing.DerivedComparable; 25 import com.google.common.testing.CollectorTester; 26 import com.google.common.testing.NullPointerTester; 27 import java.util.Arrays; 28 import java.util.Collections; 29 import java.util.List; 30 import java.util.function.BiPredicate; 31 import junit.framework.TestCase; 32 33 /** 34 * Tests for {@link Multisets}. 35 * 36 * @author Mike Bostock 37 * @author Jared Levy 38 * @author Louis Wasserman 39 */ 40 @GwtCompatible(emulated = true) 41 @ElementTypesAreNonnullByDefault 42 public class MultisetsTest extends TestCase { 43 44 /* See MultisetsImmutableEntryTest for immutableEntry() tests. */ 45 testNewTreeMultisetDerived()46 public void testNewTreeMultisetDerived() { 47 TreeMultiset<DerivedComparable> set = TreeMultiset.create(); 48 assertTrue(set.isEmpty()); 49 set.add(new DerivedComparable("foo"), 2); 50 set.add(new DerivedComparable("bar"), 3); 51 assertThat(set) 52 .containsExactly( 53 new DerivedComparable("bar"), 54 new DerivedComparable("bar"), 55 new DerivedComparable("bar"), 56 new DerivedComparable("foo"), 57 new DerivedComparable("foo")) 58 .inOrder(); 59 } 60 testNewTreeMultisetNonGeneric()61 public void testNewTreeMultisetNonGeneric() { 62 TreeMultiset<LegacyComparable> set = TreeMultiset.create(); 63 assertTrue(set.isEmpty()); 64 set.add(new LegacyComparable("foo"), 2); 65 set.add(new LegacyComparable("bar"), 3); 66 assertThat(set) 67 .containsExactly( 68 new LegacyComparable("bar"), 69 new LegacyComparable("bar"), 70 new LegacyComparable("bar"), 71 new LegacyComparable("foo"), 72 new LegacyComparable("foo")) 73 .inOrder(); 74 } 75 testNewTreeMultisetComparator()76 public void testNewTreeMultisetComparator() { 77 TreeMultiset<String> multiset = TreeMultiset.create(Collections.reverseOrder()); 78 multiset.add("bar", 3); 79 multiset.add("foo", 2); 80 assertThat(multiset).containsExactly("foo", "foo", "bar", "bar", "bar").inOrder(); 81 } 82 testRetainOccurrencesEmpty()83 public void testRetainOccurrencesEmpty() { 84 Multiset<String> multiset = HashMultiset.create(); 85 Multiset<String> toRetain = HashMultiset.create(Arrays.asList("a", "b", "a")); 86 assertFalse(Multisets.retainOccurrences(multiset, toRetain)); 87 assertThat(multiset).isEmpty(); 88 } 89 testRemoveOccurrencesIterableEmpty()90 public void testRemoveOccurrencesIterableEmpty() { 91 Multiset<String> multiset = HashMultiset.create(); 92 Iterable<String> toRemove = Arrays.asList("a", "b", "a"); 93 assertFalse(Multisets.removeOccurrences(multiset, toRemove)); 94 assertTrue(multiset.isEmpty()); 95 } 96 testRemoveOccurrencesMultisetEmpty()97 public void testRemoveOccurrencesMultisetEmpty() { 98 Multiset<String> multiset = HashMultiset.create(); 99 Multiset<String> toRemove = HashMultiset.create(Arrays.asList("a", "b", "a")); 100 assertFalse(Multisets.removeOccurrences(multiset, toRemove)); 101 assertTrue(multiset.isEmpty()); 102 } 103 testUnion()104 public void testUnion() { 105 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 106 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "b", "c")); 107 assertThat(Multisets.union(ms1, ms2)).containsExactly("a", "a", "b", "b", "c"); 108 } 109 testUnionEqualMultisets()110 public void testUnionEqualMultisets() { 111 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 112 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a")); 113 assertEquals(ms1, Multisets.union(ms1, ms2)); 114 } 115 testUnionEmptyNonempty()116 public void testUnionEmptyNonempty() { 117 Multiset<String> ms1 = HashMultiset.create(); 118 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a")); 119 assertEquals(ms2, Multisets.union(ms1, ms2)); 120 } 121 testUnionNonemptyEmpty()122 public void testUnionNonemptyEmpty() { 123 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 124 Multiset<String> ms2 = HashMultiset.create(); 125 assertEquals(ms1, Multisets.union(ms1, ms2)); 126 } 127 testIntersectEmptyNonempty()128 public void testIntersectEmptyNonempty() { 129 Multiset<String> ms1 = HashMultiset.create(); 130 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a")); 131 assertThat(Multisets.intersection(ms1, ms2)).isEmpty(); 132 } 133 testIntersectNonemptyEmpty()134 public void testIntersectNonemptyEmpty() { 135 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 136 Multiset<String> ms2 = HashMultiset.create(); 137 assertThat(Multisets.intersection(ms1, ms2)).isEmpty(); 138 } 139 testSum()140 public void testSum() { 141 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 142 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b", "c")); 143 assertThat(Multisets.sum(ms1, ms2)).containsExactly("a", "a", "b", "b", "c"); 144 } 145 testSumEmptyNonempty()146 public void testSumEmptyNonempty() { 147 Multiset<String> ms1 = HashMultiset.create(); 148 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a")); 149 assertThat(Multisets.sum(ms1, ms2)).containsExactly("a", "b", "a"); 150 } 151 testSumNonemptyEmpty()152 public void testSumNonemptyEmpty() { 153 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 154 Multiset<String> ms2 = HashMultiset.create(); 155 assertThat(Multisets.sum(ms1, ms2)).containsExactly("a", "b", "a"); 156 } 157 testDifferenceWithNoRemovedElements()158 public void testDifferenceWithNoRemovedElements() { 159 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 160 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a")); 161 assertThat(Multisets.difference(ms1, ms2)).containsExactly("a", "b"); 162 } 163 testDifferenceWithRemovedElement()164 public void testDifferenceWithRemovedElement() { 165 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 166 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b")); 167 assertThat(Multisets.difference(ms1, ms2)).containsExactly("a", "a"); 168 } 169 testDifferenceWithMoreElementsInSecondMultiset()170 public void testDifferenceWithMoreElementsInSecondMultiset() { 171 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 172 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "b", "b")); 173 Multiset<String> diff = Multisets.difference(ms1, ms2); 174 assertThat(diff).contains("a"); 175 assertEquals(0, diff.count("b")); 176 assertEquals(1, diff.count("a")); 177 assertFalse(diff.contains("b")); 178 assertTrue(diff.contains("a")); 179 } 180 testDifferenceEmptyNonempty()181 public void testDifferenceEmptyNonempty() { 182 Multiset<String> ms1 = HashMultiset.create(); 183 Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a")); 184 assertEquals(ms1, Multisets.difference(ms1, ms2)); 185 } 186 testDifferenceNonemptyEmpty()187 public void testDifferenceNonemptyEmpty() { 188 Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); 189 Multiset<String> ms2 = HashMultiset.create(); 190 assertEquals(ms1, Multisets.difference(ms1, ms2)); 191 } 192 testContainsOccurrencesEmpty()193 public void testContainsOccurrencesEmpty() { 194 Multiset<String> superMultiset = HashMultiset.create(Arrays.asList("a", "b", "a")); 195 Multiset<String> subMultiset = HashMultiset.create(); 196 assertTrue(Multisets.containsOccurrences(superMultiset, subMultiset)); 197 assertFalse(Multisets.containsOccurrences(subMultiset, superMultiset)); 198 } 199 testContainsOccurrences()200 public void testContainsOccurrences() { 201 Multiset<String> superMultiset = HashMultiset.create(Arrays.asList("a", "b", "a")); 202 Multiset<String> subMultiset = HashMultiset.create(Arrays.asList("a", "b")); 203 assertTrue(Multisets.containsOccurrences(superMultiset, subMultiset)); 204 assertFalse(Multisets.containsOccurrences(subMultiset, superMultiset)); 205 Multiset<String> diffMultiset = HashMultiset.create(Arrays.asList("a", "b", "c")); 206 assertFalse(Multisets.containsOccurrences(superMultiset, diffMultiset)); 207 assertTrue(Multisets.containsOccurrences(diffMultiset, subMultiset)); 208 } 209 testRetainEmptyOccurrences()210 public void testRetainEmptyOccurrences() { 211 Multiset<String> multiset = HashMultiset.create(Arrays.asList("a", "b", "a")); 212 Multiset<String> toRetain = HashMultiset.create(); 213 assertTrue(Multisets.retainOccurrences(multiset, toRetain)); 214 assertTrue(multiset.isEmpty()); 215 } 216 testRetainOccurrences()217 public void testRetainOccurrences() { 218 Multiset<String> multiset = TreeMultiset.create(Arrays.asList("a", "b", "a", "c")); 219 Multiset<String> toRetain = HashMultiset.create(Arrays.asList("a", "b", "b")); 220 assertTrue(Multisets.retainOccurrences(multiset, toRetain)); 221 assertThat(multiset).containsExactly("a", "b").inOrder(); 222 } 223 testRemoveEmptyOccurrencesMultiset()224 public void testRemoveEmptyOccurrencesMultiset() { 225 Multiset<String> multiset = TreeMultiset.create(Arrays.asList("a", "b", "a")); 226 Multiset<String> toRemove = HashMultiset.create(); 227 assertFalse(Multisets.removeOccurrences(multiset, toRemove)); 228 assertThat(multiset).containsExactly("a", "a", "b").inOrder(); 229 } 230 testRemoveOccurrencesMultiset()231 public void testRemoveOccurrencesMultiset() { 232 Multiset<String> multiset = TreeMultiset.create(Arrays.asList("a", "b", "a", "c")); 233 Multiset<String> toRemove = HashMultiset.create(Arrays.asList("a", "b", "b")); 234 assertTrue(Multisets.removeOccurrences(multiset, toRemove)); 235 assertThat(multiset).containsExactly("a", "c").inOrder(); 236 } 237 testRemoveEmptyOccurrencesIterable()238 public void testRemoveEmptyOccurrencesIterable() { 239 Multiset<String> multiset = TreeMultiset.create(Arrays.asList("a", "b", "a")); 240 Iterable<String> toRemove = ImmutableList.of(); 241 assertFalse(Multisets.removeOccurrences(multiset, toRemove)); 242 assertThat(multiset).containsExactly("a", "a", "b").inOrder(); 243 } 244 testRemoveOccurrencesMultisetIterable()245 public void testRemoveOccurrencesMultisetIterable() { 246 Multiset<String> multiset = TreeMultiset.create(Arrays.asList("a", "b", "a", "c")); 247 List<String> toRemove = Arrays.asList("a", "b", "b"); 248 assertTrue(Multisets.removeOccurrences(multiset, toRemove)); 249 assertThat(multiset).containsExactly("a", "c").inOrder(); 250 } 251 252 @SuppressWarnings("deprecation") testUnmodifiableMultisetShortCircuit()253 public void testUnmodifiableMultisetShortCircuit() { 254 Multiset<String> mod = HashMultiset.create(); 255 Multiset<String> unmod = Multisets.unmodifiableMultiset(mod); 256 assertNotSame(mod, unmod); 257 assertSame(unmod, Multisets.unmodifiableMultiset(unmod)); 258 ImmutableMultiset<String> immutable = ImmutableMultiset.of("a", "a", "b", "a"); 259 assertSame(immutable, Multisets.unmodifiableMultiset(immutable)); 260 assertSame(immutable, Multisets.unmodifiableMultiset((Multiset<String>) immutable)); 261 } 262 testHighestCountFirst()263 public void testHighestCountFirst() { 264 Multiset<String> multiset = HashMultiset.create(Arrays.asList("a", "a", "a", "b", "c", "c")); 265 ImmutableMultiset<String> sortedMultiset = Multisets.copyHighestCountFirst(multiset); 266 267 assertThat(sortedMultiset.entrySet()) 268 .containsExactly( 269 Multisets.immutableEntry("a", 3), 270 Multisets.immutableEntry("c", 2), 271 Multisets.immutableEntry("b", 1)) 272 .inOrder(); 273 274 assertThat(sortedMultiset).containsExactly("a", "a", "a", "c", "c", "b").inOrder(); 275 276 assertThat(Multisets.copyHighestCountFirst(ImmutableMultiset.of())).isEmpty(); 277 } 278 testToMultisetCountFunction()279 public void testToMultisetCountFunction() { 280 BiPredicate<Multiset<String>, Multiset<String>> equivalence = 281 (ms1, ms2) -> 282 ms1.equals(ms2) 283 && ImmutableList.copyOf(ms1.entrySet()) 284 .equals(ImmutableList.copyOf(ms2.entrySet())); 285 CollectorTester.of( 286 Multisets.<Multiset.Entry<String>, String, Multiset<String>>toMultiset( 287 Multiset.Entry::getElement, Multiset.Entry::getCount, LinkedHashMultiset::create), 288 equivalence) 289 .expectCollects(ImmutableMultiset.<String>of()) 290 .expectCollects( 291 ImmutableMultiset.of("a", "a", "b", "c", "c", "c"), 292 Multisets.immutableEntry("a", 1), 293 Multisets.immutableEntry("b", 1), 294 Multisets.immutableEntry("a", 1), 295 Multisets.immutableEntry("c", 3)); 296 } 297 298 @J2ktIncompatible 299 @GwtIncompatible // NullPointerTester testNullPointers()300 public void testNullPointers() { 301 new NullPointerTester().testAllPublicStaticMethods(Multisets.class); 302 } 303 } 304