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 17package com.google.common.collect; 18 19import static com.google.common.collect.Lists.newArrayList; 20import static com.google.common.collect.Sets.newHashSet; 21import static com.google.common.collect.Sets.newLinkedHashSet; 22import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE; 23import static java.util.Arrays.asList; 24import static org.junit.contrib.truth.Truth.ASSERT; 25 26import com.google.common.annotations.GwtCompatible; 27import com.google.common.annotations.GwtIncompatible; 28import com.google.common.collect.testing.IteratorTester; 29import com.google.common.testing.SerializableTester; 30 31import java.util.Collection; 32import java.util.Iterator; 33import java.util.List; 34import java.util.Map; 35import java.util.Map.Entry; 36import java.util.Set; 37 38/** 39 * Unit tests for {@code LinkedHashMultimap}. 40 * 41 * @author Jared Levy 42 */ 43@GwtCompatible(emulated = true) 44public class LinkedHashMultimapTest extends AbstractSetMultimapTest { 45 46 @Override protected Multimap<String, Integer> create() { 47 return LinkedHashMultimap.create(); 48 } 49 50 private Multimap<String, Integer> initializeMultimap5() { 51 Multimap<String, Integer> multimap = getMultimap(); 52 multimap.put("foo", 5); 53 multimap.put("bar", 4); 54 multimap.put("foo", 3); 55 multimap.put("cow", 2); 56 multimap.put("bar", 1); 57 return multimap; 58 } 59 60 public void testToString() { 61 assertEquals("{foo=[3, -1, 2, 4, 1], bar=[1, 2, 3]}", 62 createSample().toString()); 63 } 64 65 public void testOrderingReadOnly() { 66 Multimap<String, Integer> multimap = initializeMultimap5(); 67 assertOrderingReadOnly(multimap); 68 } 69 70 public void testOrderingUnmodifiable() { 71 Multimap<String, Integer> multimap = initializeMultimap5(); 72 assertOrderingReadOnly(Multimaps.unmodifiableMultimap(multimap)); 73 } 74 75 public void testOrderingSynchronized() { 76 Multimap<String, Integer> multimap = initializeMultimap5(); 77 assertOrderingReadOnly(Multimaps.synchronizedMultimap(multimap)); 78 } 79 80 @GwtIncompatible("SeriazableTester") 81 public void testSerializationOrdering() { 82 Multimap<String, Integer> multimap = initializeMultimap5(); 83 Multimap<String, Integer> copy 84 = SerializableTester.reserializeAndAssert(multimap); 85 assertOrderingReadOnly(copy); 86 } 87 88 private void assertOrderingReadOnly(Multimap<String, Integer> multimap) { 89 ASSERT.that(multimap.get("foo")).hasContentsInOrder(5, 3); 90 ASSERT.that(multimap.get("bar")).hasContentsInOrder(4, 1); 91 ASSERT.that(multimap.get("cow")).hasContentsInOrder(2); 92 93 ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "bar", "cow"); 94 ASSERT.that(multimap.values()).hasContentsInOrder(5, 4, 3, 2, 1); 95 96 Iterator<Map.Entry<String, Integer>> entryIterator = 97 multimap.entries().iterator(); 98 assertEquals(Maps.immutableEntry("foo", 5), entryIterator.next()); 99 assertEquals(Maps.immutableEntry("bar", 4), entryIterator.next()); 100 assertEquals(Maps.immutableEntry("foo", 3), entryIterator.next()); 101 assertEquals(Maps.immutableEntry("cow", 2), entryIterator.next()); 102 assertEquals(Maps.immutableEntry("bar", 1), entryIterator.next()); 103 104 Iterator<Map.Entry<String, Collection<Integer>>> collectionIterator = 105 multimap.asMap().entrySet().iterator(); 106 Map.Entry<String, Collection<Integer>> entry = collectionIterator.next(); 107 assertEquals("foo", entry.getKey()); 108 ASSERT.that(entry.getValue()).hasContentsInOrder(5, 3); 109 entry = collectionIterator.next(); 110 assertEquals("bar", entry.getKey()); 111 ASSERT.that(entry.getValue()).hasContentsInOrder(4, 1); 112 entry = collectionIterator.next(); 113 assertEquals("cow", entry.getKey()); 114 ASSERT.that(entry.getValue()).hasContentsInOrder(2); 115 } 116 117 public void testOrderingUpdates() { 118 Multimap<String, Integer> multimap = initializeMultimap5(); 119 120 ASSERT.that(multimap.replaceValues("foo", asList(6, 7))).hasContentsInOrder(5, 3); 121 ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "bar", "cow"); 122 ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(6, 7); 123 ASSERT.that(multimap.keySet()).hasContentsInOrder("bar", "cow"); 124 assertTrue(multimap.remove("bar", 4)); 125 ASSERT.that(multimap.keySet()).hasContentsInOrder("bar", "cow"); 126 assertTrue(multimap.remove("bar", 1)); 127 ASSERT.that(multimap.keySet()).hasContentsInOrder("cow"); 128 multimap.put("bar", 9); 129 ASSERT.that(multimap.keySet()).hasContentsInOrder("cow", "bar"); 130 } 131 132 public void testToStringNullExact() { 133 Multimap<String, Integer> multimap = getMultimap(); 134 135 multimap.put("foo", 3); 136 multimap.put("foo", -1); 137 multimap.put(null, null); 138 multimap.put("bar", 1); 139 multimap.put("foo", 2); 140 multimap.put(null, 0); 141 multimap.put("bar", 2); 142 multimap.put("bar", null); 143 multimap.put("foo", null); 144 multimap.put("foo", 4); 145 multimap.put(null, -1); 146 multimap.put("bar", 3); 147 multimap.put("bar", 1); 148 multimap.put("foo", 1); 149 150 assertEquals( 151 "{foo=[3, -1, 2, null, 4, 1], null=[null, 0, -1], bar=[1, 2, null, 3]}", 152 multimap.toString()); 153 } 154 155 public void testPutMultimapOrdered() { 156 Multimap<String, Integer> multimap = LinkedHashMultimap.create(); 157 multimap.putAll(initializeMultimap5()); 158 assertOrderingReadOnly(multimap); 159 } 160 161 public void testKeysToString_ordering() { 162 Multimap<String, Integer> multimap = initializeMultimap5(); 163 assertEquals("[foo x 2, bar x 2, cow]", multimap.keys().toString()); 164 } 165 166 public void testCreate() { 167 LinkedHashMultimap<String, Integer> multimap = LinkedHashMultimap.create(); 168 multimap.put("foo", 1); 169 multimap.put("bar", 2); 170 multimap.put("foo", 3); 171 assertEquals(ImmutableSet.of(1, 3), multimap.get("foo")); 172 assertEquals(8, multimap.expectedValuesPerKey); 173 } 174 175 public void testCreateFromMultimap() { 176 Multimap<String, Integer> multimap = createSample(); 177 LinkedHashMultimap<String, Integer> copy = 178 LinkedHashMultimap.create(multimap); 179 assertEquals(multimap, copy); 180 assertEquals(8, copy.expectedValuesPerKey); 181 } 182 183 public void testCreateFromSizes() { 184 LinkedHashMultimap<String, Integer> multimap 185 = LinkedHashMultimap.create(20, 15); 186 multimap.put("foo", 1); 187 multimap.put("bar", 2); 188 multimap.put("foo", 3); 189 assertEquals(ImmutableSet.of(1, 3), multimap.get("foo")); 190 assertEquals(15, multimap.expectedValuesPerKey); 191 } 192 193 public void testCreateFromIllegalSizes() { 194 try { 195 LinkedHashMultimap.create(-20, 15); 196 fail(); 197 } catch (IllegalArgumentException expected) {} 198 199 try { 200 LinkedHashMultimap.create(20, -15); 201 fail(); 202 } catch (IllegalArgumentException expected) {} 203 } 204 205 @GwtIncompatible("unreasonable slow") 206 public void testGetIteration() { 207 new IteratorTester<Integer>(6, MODIFIABLE, 208 newLinkedHashSet(asList(2, 3, 4, 7, 8)), 209 IteratorTester.KnownOrder.KNOWN_ORDER) { 210 private Multimap<String, Integer> multimap; 211 212 @Override protected Iterator<Integer> newTargetIterator() { 213 multimap = create(); 214 multimap.putAll("foo", asList(2, 3, 4)); 215 multimap.putAll("bar", asList(5, 6)); 216 multimap.putAll("foo", asList(7, 8)); 217 return multimap.get("foo").iterator(); 218 } 219 220 @Override protected void verify(List<Integer> elements) { 221 assertEquals(newHashSet(elements), multimap.get("foo")); 222 } 223 }.test(); 224 } 225 226 @GwtIncompatible("unreasonable slow") 227 public void testEntriesIteration() { 228 @SuppressWarnings("unchecked") 229 Set<Entry<String, Integer>> set = Sets.newLinkedHashSet(asList( 230 Maps.immutableEntry("foo", 2), 231 Maps.immutableEntry("foo", 3), 232 Maps.immutableEntry("bar", 4), 233 Maps.immutableEntry("bar", 5), 234 Maps.immutableEntry("foo", 6))); 235 236 new IteratorTester<Entry<String, Integer>>(6, MODIFIABLE, set, 237 IteratorTester.KnownOrder.KNOWN_ORDER) { 238 private Multimap<String, Integer> multimap; 239 240 @Override protected Iterator<Entry<String, Integer>> newTargetIterator() { 241 multimap = create(); 242 multimap.putAll("foo", asList(2, 3)); 243 multimap.putAll("bar", asList(4, 5)); 244 multimap.putAll("foo", asList(6)); 245 return multimap.entries().iterator(); 246 } 247 248 @Override protected void verify(List<Entry<String, Integer>> elements) { 249 assertEquals(newHashSet(elements), multimap.entries()); 250 } 251 }.test(); 252 } 253 254 @GwtIncompatible("unreasonable slow") 255 public void testKeysIteration() { 256 new IteratorTester<String>(6, MODIFIABLE, newArrayList("foo", "foo", "bar", 257 "bar", "foo"), IteratorTester.KnownOrder.KNOWN_ORDER) { 258 private Multimap<String, Integer> multimap; 259 260 @Override protected Iterator<String> newTargetIterator() { 261 multimap = create(); 262 multimap.putAll("foo", asList(2, 3)); 263 multimap.putAll("bar", asList(4, 5)); 264 multimap.putAll("foo", asList(6)); 265 return multimap.keys().iterator(); 266 } 267 268 @Override protected void verify(List<String> elements) { 269 assertEquals(elements, Lists.newArrayList(multimap.keys())); 270 } 271 }.test(); 272 } 273 274 @GwtIncompatible("unreasonable slow") 275 public void testValuesIteration() { 276 new IteratorTester<Integer>(6, MODIFIABLE, newArrayList(2, 3, 4, 5, 6), 277 IteratorTester.KnownOrder.KNOWN_ORDER) { 278 private Multimap<String, Integer> multimap; 279 280 @Override protected Iterator<Integer> newTargetIterator() { 281 multimap = create(); 282 multimap.putAll("foo", asList(2, 3)); 283 multimap.putAll("bar", asList(4, 5)); 284 multimap.putAll("foo", asList(6)); 285 return multimap.values().iterator(); 286 } 287 288 @Override protected void verify(List<Integer> elements) { 289 assertEquals(elements, Lists.newArrayList(multimap.values())); 290 } 291 }.test(); 292 } 293 294 @GwtIncompatible("unreasonable slow") 295 public void testKeySetIteration() { 296 new IteratorTester<String>(6, MODIFIABLE, newLinkedHashSet(asList( 297 "foo", "bar", "baz", "dog", "cat")), 298 IteratorTester.KnownOrder.KNOWN_ORDER) { 299 private Multimap<String, Integer> multimap; 300 301 @Override protected Iterator<String> newTargetIterator() { 302 multimap = create(); 303 multimap.putAll("foo", asList(2, 3)); 304 multimap.putAll("bar", asList(4, 5)); 305 multimap.putAll("foo", asList(6)); 306 multimap.putAll("baz", asList(7, 8)); 307 multimap.putAll("dog", asList(9)); 308 multimap.putAll("bar", asList(10, 11)); 309 multimap.putAll("cat", asList(12, 13, 14)); 310 return multimap.keySet().iterator(); 311 } 312 313 @Override protected void verify(List<String> elements) { 314 assertEquals(newHashSet(elements), multimap.keySet()); 315 } 316 }.test(); 317 } 318 319 @GwtIncompatible("unreasonable slow") 320 public void testAsSetIteration() { 321 @SuppressWarnings("unchecked") 322 Set<Entry<String, Collection<Integer>>> set = newLinkedHashSet(asList( 323 Maps.immutableEntry("foo", 324 (Collection<Integer>) Sets.newHashSet(2, 3, 6)), 325 Maps.immutableEntry("bar", 326 (Collection<Integer>) Sets.newHashSet(4, 5, 10, 11)), 327 Maps.immutableEntry("baz", 328 (Collection<Integer>) Sets.newHashSet(7, 8)), 329 Maps.immutableEntry("dog", 330 (Collection<Integer>) Sets.newHashSet(9)), 331 Maps.immutableEntry("cat", 332 (Collection<Integer>) Sets.newHashSet(12, 13, 14)) 333 )); 334 new IteratorTester<Entry<String, Collection<Integer>>>(6, MODIFIABLE, set, 335 IteratorTester.KnownOrder.KNOWN_ORDER) { 336 private Multimap<String, Integer> multimap; 337 338 @Override protected Iterator<Entry<String, Collection<Integer>>> 339 newTargetIterator() { 340 multimap = create(); 341 multimap.putAll("foo", asList(2, 3)); 342 multimap.putAll("bar", asList(4, 5)); 343 multimap.putAll("foo", asList(6)); 344 multimap.putAll("baz", asList(7, 8)); 345 multimap.putAll("dog", asList(9)); 346 multimap.putAll("bar", asList(10, 11)); 347 multimap.putAll("cat", asList(12, 13, 14)); 348 return multimap.asMap().entrySet().iterator(); 349 } 350 351 @Override protected void verify( 352 List<Entry<String, Collection<Integer>>> elements) { 353 assertEquals(newHashSet(elements), multimap.asMap().entrySet()); 354 } 355 }.test(); 356 } 357 358} 359