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 java.util.Arrays.asList; 20import static org.truth0.Truth.ASSERT; 21 22import com.google.common.annotations.GwtCompatible; 23import com.google.common.testing.EqualsTester; 24 25import junit.framework.TestCase; 26 27import java.util.Arrays; 28import java.util.Collection; 29import java.util.Iterator; 30import java.util.Map; 31 32/** 33 * Unit tests for {@code LinkedHashMultimap}. 34 * 35 * @author Jared Levy 36 */ 37@GwtCompatible(emulated = true) 38public class LinkedHashMultimapTest extends TestCase { 39 40 public void testValueSetHashTableExpansion() { 41 LinkedHashMultimap<String, Integer> multimap = LinkedHashMultimap.create(); 42 for (int z = 1; z <= 100; z++) { 43 multimap.put("a", z); 44 // The Eclipse compiler (and hence GWT) rejects a parameterized cast. 45 @SuppressWarnings("unchecked") 46 LinkedHashMultimap<String, Integer>.ValueSet valueSet = 47 (LinkedHashMultimap.ValueSet) multimap.backingMap().get("a"); 48 assertEquals(z, valueSet.size()); 49 assertFalse(Hashing.needsResizing(valueSet.size(), valueSet.hashTable.length, 50 LinkedHashMultimap.VALUE_SET_LOAD_FACTOR)); 51 } 52 } 53 54 private Multimap<String, Integer> initializeMultimap5() { 55 Multimap<String, Integer> multimap = LinkedHashMultimap.create(); 56 multimap.put("foo", 5); 57 multimap.put("bar", 4); 58 multimap.put("foo", 3); 59 multimap.put("cow", 2); 60 multimap.put("bar", 1); 61 return multimap; 62 } 63 64 public void testToString() { 65 Multimap<String, Integer> multimap = LinkedHashMultimap.create(); 66 multimap.put("foo", 3); 67 multimap.put("bar", 1); 68 multimap.putAll("foo", Arrays.asList(-1, 2, 4)); 69 multimap.putAll("bar", Arrays.asList(2, 3)); 70 multimap.put("foo", 1); 71 assertEquals("{foo=[3, -1, 2, 4, 1], bar=[1, 2, 3]}", 72 multimap.toString()); 73 } 74 75 public void testOrderingReadOnly() { 76 Multimap<String, Integer> multimap = initializeMultimap5(); 77 assertOrderingReadOnly(multimap); 78 } 79 80 public void testOrderingUnmodifiable() { 81 Multimap<String, Integer> multimap = initializeMultimap5(); 82 assertOrderingReadOnly(Multimaps.unmodifiableMultimap(multimap)); 83 } 84 85 public void testOrderingSynchronized() { 86 Multimap<String, Integer> multimap = initializeMultimap5(); 87 assertOrderingReadOnly(Multimaps.synchronizedMultimap(multimap)); 88 } 89 90 private void assertOrderingReadOnly(Multimap<String, Integer> multimap) { 91 ASSERT.that(multimap.get("foo")).has().exactly(5, 3).inOrder(); 92 ASSERT.that(multimap.get("bar")).has().exactly(4, 1).inOrder(); 93 ASSERT.that(multimap.get("cow")).has().item(2); 94 95 ASSERT.that(multimap.keySet()).has().exactly("foo", "bar", "cow").inOrder(); 96 ASSERT.that(multimap.values()).has().exactly(5, 4, 3, 2, 1).inOrder(); 97 98 Iterator<Map.Entry<String, Integer>> entryIterator = 99 multimap.entries().iterator(); 100 assertEquals(Maps.immutableEntry("foo", 5), entryIterator.next()); 101 assertEquals(Maps.immutableEntry("bar", 4), entryIterator.next()); 102 assertEquals(Maps.immutableEntry("foo", 3), entryIterator.next()); 103 assertEquals(Maps.immutableEntry("cow", 2), entryIterator.next()); 104 assertEquals(Maps.immutableEntry("bar", 1), entryIterator.next()); 105 106 Iterator<Map.Entry<String, Collection<Integer>>> collectionIterator = 107 multimap.asMap().entrySet().iterator(); 108 Map.Entry<String, Collection<Integer>> entry = collectionIterator.next(); 109 assertEquals("foo", entry.getKey()); 110 ASSERT.that(entry.getValue()).has().exactly(5, 3).inOrder(); 111 entry = collectionIterator.next(); 112 assertEquals("bar", entry.getKey()); 113 ASSERT.that(entry.getValue()).has().exactly(4, 1).inOrder(); 114 entry = collectionIterator.next(); 115 assertEquals("cow", entry.getKey()); 116 ASSERT.that(entry.getValue()).has().item(2); 117 } 118 119 public void testOrderingUpdates() { 120 Multimap<String, Integer> multimap = initializeMultimap5(); 121 122 ASSERT.that(multimap.replaceValues("foo", asList(6, 7))).has().exactly(5, 3).inOrder(); 123 ASSERT.that(multimap.keySet()).has().exactly("foo", "bar", "cow").inOrder(); 124 ASSERT.that(multimap.removeAll("foo")).has().exactly(6, 7).inOrder(); 125 ASSERT.that(multimap.keySet()).has().exactly("bar", "cow").inOrder(); 126 assertTrue(multimap.remove("bar", 4)); 127 ASSERT.that(multimap.keySet()).has().exactly("bar", "cow").inOrder(); 128 assertTrue(multimap.remove("bar", 1)); 129 ASSERT.that(multimap.keySet()).has().item("cow"); 130 multimap.put("bar", 9); 131 ASSERT.that(multimap.keySet()).has().exactly("cow", "bar").inOrder(); 132 } 133 134 public void testToStringNullExact() { 135 Multimap<String, Integer> multimap = LinkedHashMultimap.create(); 136 137 multimap.put("foo", 3); 138 multimap.put("foo", -1); 139 multimap.put(null, null); 140 multimap.put("bar", 1); 141 multimap.put("foo", 2); 142 multimap.put(null, 0); 143 multimap.put("bar", 2); 144 multimap.put("bar", null); 145 multimap.put("foo", null); 146 multimap.put("foo", 4); 147 multimap.put(null, -1); 148 multimap.put("bar", 3); 149 multimap.put("bar", 1); 150 multimap.put("foo", 1); 151 152 assertEquals( 153 "{foo=[3, -1, 2, null, 4, 1], null=[null, 0, -1], bar=[1, 2, null, 3]}", 154 multimap.toString()); 155 } 156 157 public void testPutMultimapOrdered() { 158 Multimap<String, Integer> multimap = LinkedHashMultimap.create(); 159 multimap.putAll(initializeMultimap5()); 160 assertOrderingReadOnly(multimap); 161 } 162 163 public void testKeysToString_ordering() { 164 Multimap<String, Integer> multimap = initializeMultimap5(); 165 assertEquals("[foo x 2, bar x 2, cow]", multimap.keys().toString()); 166 } 167 168 public void testCreate() { 169 LinkedHashMultimap<String, Integer> multimap = LinkedHashMultimap.create(); 170 multimap.put("foo", 1); 171 multimap.put("bar", 2); 172 multimap.put("foo", 3); 173 assertEquals(ImmutableSet.of(1, 3), multimap.get("foo")); 174 } 175 176 public void testCreateFromMultimap() { 177 Multimap<String, Integer> multimap = LinkedHashMultimap.create(); 178 multimap.put("a", 1); 179 multimap.put("b", 2); 180 multimap.put("a", 3); 181 multimap.put("c", 4); 182 LinkedHashMultimap<String, Integer> copy = 183 LinkedHashMultimap.create(multimap); 184 new EqualsTester() 185 .addEqualityGroup(multimap, copy) 186 .testEquals(); 187 } 188 189 public void testCreateFromSizes() { 190 LinkedHashMultimap<String, Integer> multimap 191 = LinkedHashMultimap.create(20, 15); 192 multimap.put("foo", 1); 193 multimap.put("bar", 2); 194 multimap.put("foo", 3); 195 assertEquals(ImmutableSet.of(1, 3), multimap.get("foo")); 196 } 197 198 public void testCreateFromIllegalSizes() { 199 try { 200 LinkedHashMultimap.create(-20, 15); 201 fail(); 202 } catch (IllegalArgumentException expected) {} 203 204 try { 205 LinkedHashMultimap.create(20, -15); 206 fail(); 207 } catch (IllegalArgumentException expected) {} 208 } 209} 210 211