1/* 2 * Copyright (C) 2009 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 org.truth0.Truth.ASSERT; 20 21import com.google.common.annotations.GwtCompatible; 22import com.google.common.collect.ImmutableSetMultimap.Builder; 23import com.google.common.collect.testing.google.UnmodifiableCollectionTests; 24import com.google.common.testing.EqualsTester; 25 26import junit.framework.TestCase; 27 28import java.util.Arrays; 29import java.util.Collections; 30import java.util.Map.Entry; 31 32/** 33 * Tests for {@link ImmutableSetMultimap}. 34 * 35 * @author Mike Ward 36 */ 37@GwtCompatible(emulated = true) 38public class ImmutableSetMultimapTest extends TestCase { 39 40 public void testBuilder_withImmutableEntry() { 41 ImmutableSetMultimap<String, Integer> multimap = new Builder<String, Integer>() 42 .put(Maps.immutableEntry("one", 1)) 43 .build(); 44 assertEquals(ImmutableSet.of(1), multimap.get("one")); 45 } 46 47 public void testBuilder_withImmutableEntryAndNullContents() { 48 Builder<String, Integer> builder = new Builder<String, Integer>(); 49 try { 50 builder.put(Maps.immutableEntry("one", (Integer) null)); 51 fail(); 52 } catch (NullPointerException expected) { 53 } 54 try { 55 builder.put(Maps.immutableEntry((String) null, 1)); 56 fail(); 57 } catch (NullPointerException expected) { 58 } 59 } 60 61 private static class StringHolder { 62 String string; 63 } 64 65 public void testBuilder_withMutableEntry() { 66 ImmutableSetMultimap.Builder<String, Integer> builder = 67 new Builder<String, Integer>(); 68 final StringHolder holder = new StringHolder(); 69 holder.string = "one"; 70 Entry<String, Integer> entry = new AbstractMapEntry<String, Integer>() { 71 @Override public String getKey() { 72 return holder.string; 73 } 74 @Override public Integer getValue() { 75 return 1; 76 } 77 }; 78 79 builder.put(entry); 80 holder.string = "two"; 81 assertEquals(ImmutableSet.of(1), builder.build().get("one")); 82 } 83 84 public void testBuilderPutAllIterable() { 85 ImmutableSetMultimap.Builder<String, Integer> builder 86 = ImmutableSetMultimap.builder(); 87 builder.putAll("foo", Arrays.asList(1, 2, 3)); 88 builder.putAll("bar", Arrays.asList(4, 5)); 89 builder.putAll("foo", Arrays.asList(6, 7)); 90 Multimap<String, Integer> multimap = builder.build(); 91 assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo")); 92 assertEquals(ImmutableSet.of(4, 5), multimap.get("bar")); 93 assertEquals(7, multimap.size()); 94 } 95 96 public void testBuilderPutAllVarargs() { 97 ImmutableSetMultimap.Builder<String, Integer> builder 98 = ImmutableSetMultimap.builder(); 99 builder.putAll("foo", 1, 2, 3); 100 builder.putAll("bar", 4, 5); 101 builder.putAll("foo", 6, 7); 102 Multimap<String, Integer> multimap = builder.build(); 103 assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo")); 104 assertEquals(ImmutableSet.of(4, 5), multimap.get("bar")); 105 assertEquals(7, multimap.size()); 106 } 107 108 public void testBuilderPutAllMultimap() { 109 Multimap<String, Integer> toPut = LinkedListMultimap.create(); 110 toPut.put("foo", 1); 111 toPut.put("bar", 4); 112 toPut.put("foo", 2); 113 toPut.put("foo", 3); 114 Multimap<String, Integer> moreToPut = LinkedListMultimap.create(); 115 moreToPut.put("foo", 6); 116 moreToPut.put("bar", 5); 117 moreToPut.put("foo", 7); 118 ImmutableSetMultimap.Builder<String, Integer> builder 119 = ImmutableSetMultimap.builder(); 120 builder.putAll(toPut); 121 builder.putAll(moreToPut); 122 Multimap<String, Integer> multimap = builder.build(); 123 assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo")); 124 assertEquals(ImmutableSet.of(4, 5), multimap.get("bar")); 125 assertEquals(7, multimap.size()); 126 } 127 128 public void testBuilderPutAllWithDuplicates() { 129 ImmutableSetMultimap.Builder<String, Integer> builder 130 = ImmutableSetMultimap.builder(); 131 builder.putAll("foo", 1, 2, 3); 132 builder.putAll("bar", 4, 5); 133 builder.putAll("foo", 1, 6, 7); 134 ImmutableSetMultimap<String, Integer> multimap = builder.build(); 135 assertEquals(7, multimap.size()); 136 } 137 138 public void testBuilderPutWithDuplicates() { 139 ImmutableSetMultimap.Builder<String, Integer> builder 140 = ImmutableSetMultimap.builder(); 141 builder.putAll("foo", 1, 2, 3); 142 builder.putAll("bar", 4, 5); 143 builder.put("foo", 1); 144 ImmutableSetMultimap<String, Integer> multimap = builder.build(); 145 assertEquals(5, multimap.size()); 146 } 147 148 public void testBuilderPutAllMultimapWithDuplicates() { 149 Multimap<String, Integer> toPut = LinkedListMultimap.create(); 150 toPut.put("foo", 1); 151 toPut.put("bar", 4); 152 toPut.put("foo", 2); 153 toPut.put("foo", 1); 154 toPut.put("bar", 5); 155 ImmutableSetMultimap.Builder<String, Integer> builder 156 = ImmutableSetMultimap.builder(); 157 builder.putAll(toPut); 158 ImmutableSetMultimap<String, Integer> multimap = builder.build(); 159 assertEquals(4, multimap.size()); 160 } 161 162 public void testBuilderPutNullKey() { 163 Multimap<String, Integer> toPut = LinkedListMultimap.create(); 164 toPut.put("foo", null); 165 ImmutableSetMultimap.Builder<String, Integer> builder 166 = ImmutableSetMultimap.builder(); 167 try { 168 builder.put(null, 1); 169 fail(); 170 } catch (NullPointerException expected) {} 171 try { 172 builder.putAll(null, Arrays.asList(1, 2, 3)); 173 fail(); 174 } catch (NullPointerException expected) {} 175 try { 176 builder.putAll(null, 1, 2, 3); 177 fail(); 178 } catch (NullPointerException expected) {} 179 try { 180 builder.putAll(toPut); 181 fail(); 182 } catch (NullPointerException expected) {} 183 } 184 185 public void testBuilderPutNullValue() { 186 Multimap<String, Integer> toPut = LinkedListMultimap.create(); 187 toPut.put(null, 1); 188 ImmutableSetMultimap.Builder<String, Integer> builder 189 = ImmutableSetMultimap.builder(); 190 try { 191 builder.put("foo", null); 192 fail(); 193 } catch (NullPointerException expected) {} 194 try { 195 builder.putAll("foo", Arrays.asList(1, null, 3)); 196 fail(); 197 } catch (NullPointerException expected) {} 198 try { 199 builder.putAll("foo", 4, null, 6); 200 fail(); 201 } catch (NullPointerException expected) {} 202 try { 203 builder.putAll(toPut); 204 fail(); 205 } catch (NullPointerException expected) {} 206 } 207 208 public void testBuilderOrderKeysBy() { 209 ImmutableSetMultimap.Builder<String, Integer> builder 210 = ImmutableSetMultimap.builder(); 211 builder.put("b", 3); 212 builder.put("d", 2); 213 builder.put("a", 5); 214 builder.orderKeysBy(Collections.reverseOrder()); 215 builder.put("c", 4); 216 builder.put("a", 2); 217 builder.put("b", 6); 218 ImmutableSetMultimap<String, Integer> multimap = builder.build(); 219 ASSERT.that(multimap.keySet()).has().exactly("d", "c", "b", "a").inOrder(); 220 ASSERT.that(multimap.values()).has().exactly(2, 4, 3, 6, 5, 2).inOrder(); 221 ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); 222 ASSERT.that(multimap.get("b")).has().exactly(3, 6).inOrder(); 223 assertFalse(multimap.get("a") instanceof ImmutableSortedSet); 224 assertFalse(multimap.get("x") instanceof ImmutableSortedSet); 225 assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet); 226 } 227 228 public void testBuilderOrderKeysByDuplicates() { 229 ImmutableSetMultimap.Builder<String, Integer> builder 230 = ImmutableSetMultimap.builder(); 231 builder.put("bb", 3); 232 builder.put("d", 2); 233 builder.put("a", 5); 234 builder.orderKeysBy(new Ordering<String>() { 235 @Override 236 public int compare(String left, String right) { 237 return left.length() - right.length(); 238 } 239 }); 240 builder.put("cc", 4); 241 builder.put("a", 2); 242 builder.put("bb", 6); 243 ImmutableSetMultimap<String, Integer> multimap = builder.build(); 244 ASSERT.that(multimap.keySet()).has().exactly("d", "a", "bb", "cc").inOrder(); 245 ASSERT.that(multimap.values()).has().exactly(2, 5, 2, 3, 6, 4).inOrder(); 246 ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); 247 ASSERT.that(multimap.get("bb")).has().exactly(3, 6).inOrder(); 248 assertFalse(multimap.get("a") instanceof ImmutableSortedSet); 249 assertFalse(multimap.get("x") instanceof ImmutableSortedSet); 250 assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet); 251 } 252 253 public void testBuilderOrderValuesBy() { 254 ImmutableSetMultimap.Builder<String, Integer> builder 255 = ImmutableSetMultimap.builder(); 256 builder.put("b", 3); 257 builder.put("d", 2); 258 builder.put("a", 5); 259 builder.orderValuesBy(Collections.reverseOrder()); 260 builder.put("c", 4); 261 builder.put("a", 2); 262 builder.put("b", 6); 263 ImmutableSetMultimap<String, Integer> multimap = builder.build(); 264 ASSERT.that(multimap.keySet()).has().exactly("b", "d", "a", "c").inOrder(); 265 ASSERT.that(multimap.values()).has().exactly(6, 3, 2, 5, 2, 4).inOrder(); 266 ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); 267 ASSERT.that(multimap.get("b")).has().exactly(6, 3).inOrder(); 268 assertTrue(multimap.get("a") instanceof ImmutableSortedSet); 269 assertEquals(Collections.reverseOrder(), 270 ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator()); 271 assertTrue(multimap.get("x") instanceof ImmutableSortedSet); 272 assertEquals(Collections.reverseOrder(), 273 ((ImmutableSortedSet<Integer>) multimap.get("x")).comparator()); 274 assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet); 275 assertEquals(Collections.reverseOrder(), 276 ((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator()); 277 } 278 279 public void testBuilderOrderKeysAndValuesBy() { 280 ImmutableSetMultimap.Builder<String, Integer> builder 281 = ImmutableSetMultimap.builder(); 282 builder.put("b", 3); 283 builder.put("d", 2); 284 builder.put("a", 5); 285 builder.orderKeysBy(Collections.reverseOrder()); 286 builder.orderValuesBy(Collections.reverseOrder()); 287 builder.put("c", 4); 288 builder.put("a", 2); 289 builder.put("b", 6); 290 ImmutableSetMultimap<String, Integer> multimap = builder.build(); 291 ASSERT.that(multimap.keySet()).has().exactly("d", "c", "b", "a").inOrder(); 292 ASSERT.that(multimap.values()).has().exactly(2, 4, 6, 3, 5, 2).inOrder(); 293 ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); 294 ASSERT.that(multimap.get("b")).has().exactly(6, 3).inOrder(); 295 assertTrue(multimap.get("a") instanceof ImmutableSortedSet); 296 assertEquals(Collections.reverseOrder(), 297 ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator()); 298 assertTrue(multimap.get("x") instanceof ImmutableSortedSet); 299 assertEquals(Collections.reverseOrder(), 300 ((ImmutableSortedSet<Integer>) multimap.get("x")).comparator()); 301 assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet); 302 assertEquals(Collections.reverseOrder(), 303 ((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator()); 304 } 305 306 public void testCopyOf() { 307 HashMultimap<String, Integer> input = HashMultimap.create(); 308 input.put("foo", 1); 309 input.put("bar", 2); 310 input.put("foo", 3); 311 Multimap<String, Integer> multimap = ImmutableSetMultimap.copyOf(input); 312 assertEquals(multimap, input); 313 assertEquals(input, multimap); 314 } 315 316 public void testCopyOfWithDuplicates() { 317 ArrayListMultimap<Object, Object> input = ArrayListMultimap.create(); 318 input.put("foo", 1); 319 input.put("bar", 2); 320 input.put("foo", 3); 321 input.put("foo", 1); 322 ImmutableSetMultimap<Object, Object> copy 323 = ImmutableSetMultimap.copyOf(input); 324 assertEquals(3, copy.size()); 325 } 326 327 public void testCopyOfEmpty() { 328 HashMultimap<String, Integer> input = HashMultimap.create(); 329 Multimap<String, Integer> multimap = ImmutableSetMultimap.copyOf(input); 330 assertEquals(multimap, input); 331 assertEquals(input, multimap); 332 } 333 334 public void testCopyOfImmutableSetMultimap() { 335 Multimap<String, Integer> multimap = createMultimap(); 336 assertSame(multimap, ImmutableSetMultimap.copyOf(multimap)); 337 } 338 339 public void testCopyOfNullKey() { 340 HashMultimap<String, Integer> input = HashMultimap.create(); 341 input.put(null, 1); 342 try { 343 ImmutableSetMultimap.copyOf(input); 344 fail(); 345 } catch (NullPointerException expected) {} 346 } 347 348 public void testCopyOfNullValue() { 349 HashMultimap<String, Integer> input = HashMultimap.create(); 350 input.putAll("foo", Arrays.asList(1, null, 3)); 351 try { 352 ImmutableSetMultimap.copyOf(input); 353 fail(); 354 } catch (NullPointerException expected) {} 355 } 356 357 public void testEmptyMultimapReads() { 358 Multimap<String, Integer> multimap = ImmutableSetMultimap.of(); 359 assertFalse(multimap.containsKey("foo")); 360 assertFalse(multimap.containsValue(1)); 361 assertFalse(multimap.containsEntry("foo", 1)); 362 assertTrue(multimap.entries().isEmpty()); 363 assertTrue(multimap.equals(HashMultimap.create())); 364 assertEquals(Collections.emptySet(), multimap.get("foo")); 365 assertEquals(0, multimap.hashCode()); 366 assertTrue(multimap.isEmpty()); 367 assertEquals(HashMultiset.create(), multimap.keys()); 368 assertEquals(Collections.emptySet(), multimap.keySet()); 369 assertEquals(0, multimap.size()); 370 assertTrue(multimap.values().isEmpty()); 371 assertEquals("{}", multimap.toString()); 372 } 373 374 public void testEmptyMultimapWrites() { 375 Multimap<String, Integer> multimap = ImmutableSetMultimap.of(); 376 UnmodifiableCollectionTests.assertMultimapIsUnmodifiable( 377 multimap, "foo", 1); 378 } 379 380 public void testMultimapReads() { 381 Multimap<String, Integer> multimap = createMultimap(); 382 assertTrue(multimap.containsKey("foo")); 383 assertFalse(multimap.containsKey("cat")); 384 assertTrue(multimap.containsValue(1)); 385 assertFalse(multimap.containsValue(5)); 386 assertTrue(multimap.containsEntry("foo", 1)); 387 assertFalse(multimap.containsEntry("cat", 1)); 388 assertFalse(multimap.containsEntry("foo", 5)); 389 assertFalse(multimap.entries().isEmpty()); 390 assertEquals(3, multimap.size()); 391 assertFalse(multimap.isEmpty()); 392 assertEquals("{foo=[1, 3], bar=[2]}", multimap.toString()); 393 } 394 395 public void testMultimapWrites() { 396 Multimap<String, Integer> multimap = createMultimap(); 397 UnmodifiableCollectionTests.assertMultimapIsUnmodifiable( 398 multimap, "bar", 2); 399 } 400 401 public void testMultimapEquals() { 402 Multimap<String, Integer> multimap = createMultimap(); 403 Multimap<String, Integer> hashMultimap = HashMultimap.create(); 404 hashMultimap.putAll("foo", Arrays.asList(1, 3)); 405 hashMultimap.put("bar", 2); 406 407 new EqualsTester() 408 .addEqualityGroup( 409 multimap, 410 createMultimap(), 411 hashMultimap, 412 ImmutableSetMultimap.<String, Integer>builder() 413 .put("bar", 2).put("foo", 1).put("foo", 3).build(), 414 ImmutableSetMultimap.<String, Integer>builder() 415 .put("bar", 2).put("foo", 3).put("foo", 1).build()) 416 .addEqualityGroup(ImmutableSetMultimap.<String, Integer>builder() 417 .put("foo", 2).put("foo", 3).put("foo", 1).build()) 418 .addEqualityGroup(ImmutableSetMultimap.<String, Integer>builder() 419 .put("bar", 2).put("foo", 3).build()) 420 .testEquals(); 421 } 422 423 public void testOf() { 424 assertMultimapEquals( 425 ImmutableSetMultimap.of("one", 1), 426 "one", 1); 427 assertMultimapEquals( 428 ImmutableSetMultimap.of("one", 1, "two", 2), 429 "one", 1, "two", 2); 430 assertMultimapEquals( 431 ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3), 432 "one", 1, "two", 2, "three", 3); 433 assertMultimapEquals( 434 ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3, "four", 4), 435 "one", 1, "two", 2, "three", 3, "four", 4); 436 assertMultimapEquals( 437 ImmutableSetMultimap.of( 438 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5), 439 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); 440 } 441 442 public void testInverse() { 443 assertEquals( 444 ImmutableSetMultimap.<Integer, String>of(), 445 ImmutableSetMultimap.<String, Integer>of().inverse()); 446 assertEquals( 447 ImmutableSetMultimap.of(1, "one"), 448 ImmutableSetMultimap.of("one", 1).inverse()); 449 assertEquals( 450 ImmutableSetMultimap.of(1, "one", 2, "two"), 451 ImmutableSetMultimap.of("one", 1, "two", 2).inverse()); 452 assertEquals( 453 ImmutableSetMultimap.of('o', "of", 'f', "of", 't', "to", 'o', "to"), 454 ImmutableSetMultimap.of("of", 'o', "of", 'f', "to", 't', "to", 'o').inverse()); 455 } 456 457 public void testInverseMinimizesWork() { 458 ImmutableSetMultimap<String, Character> multimap = 459 ImmutableSetMultimap.of("of", 'o', "of", 'f', "to", 't', "to", 'o'); 460 assertSame(multimap.inverse(), multimap.inverse()); 461 assertSame(multimap, multimap.inverse().inverse()); 462 } 463 464 private static <K, V> void assertMultimapEquals(Multimap<K, V> multimap, 465 Object... alternatingKeysAndValues) { 466 assertEquals(multimap.size(), alternatingKeysAndValues.length / 2); 467 int i = 0; 468 for (Entry<K, V> entry : multimap.entries()) { 469 assertEquals(alternatingKeysAndValues[i++], entry.getKey()); 470 assertEquals(alternatingKeysAndValues[i++], entry.getValue()); 471 } 472 } 473 474 private ImmutableSetMultimap<String, Integer> createMultimap() { 475 return ImmutableSetMultimap.<String, Integer>builder() 476 .put("foo", 1).put("bar", 2).put("foo", 3).build(); 477 } 478} 479 480