1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 package org.apache.commons.collections;
18 
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collection;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.Map;
25 
26 import junit.framework.Test;
27 import junit.framework.TestSuite;
28 
29 import org.apache.commons.collections.map.AbstractTestMap;
30 
31 /**
32  * Unit Tests for <code>MultiHashMap</code>.
33  *
34  * @version $Revision: 646780 $ $Date: 2008-04-10 14:48:07 +0200 (Thu, 10 Apr 2008) $
35  *
36  * @author Unknown
37  */
38 public class TestMultiHashMap extends AbstractTestMap {
39 
TestMultiHashMap(String testName)40     public TestMultiHashMap(String testName) {
41         super(testName);
42     }
43 
suite()44     public static Test suite() {
45         return new TestSuite(TestMultiHashMap.class);
46     }
47 
main(String args[])48     public static void main(String args[]) {
49         String[] testCaseName = { TestMultiHashMap.class.getName()};
50         junit.textui.TestRunner.main(testCaseName);
51     }
52 
53     // MutltiHashMap was introduced in Collections 2.x
getCompatibilityVersion()54     public String getCompatibilityVersion() {
55         return "2";
56     }
57 
makeEmptyMap()58     public Map makeEmptyMap() {
59         return new MultiHashMap();
60     }
61 
62     //----------------------------
63     //          Tests
64     //----------------------------
testPutNGet()65     public void testPutNGet() {
66         MultiHashMap map = new MultiHashMap();
67         loadMap(map);
68         checkMap(map);
69 
70         assertTrue(map.get(new Integer(99)) == null);
71 
72         map.clear();
73         assertTrue(map.size() == 0);
74     }
75 
testContainsValue()76     public void testContainsValue() {
77         MultiHashMap map = new MultiHashMap();
78         loadMap(map);
79 
80         assertTrue(map.containsValue("uno"));
81         assertTrue(map.containsValue("quatro"));
82         assertTrue(map.containsValue("two"));
83 
84         assertTrue(!map.containsValue("uggaBugga"));
85 
86         map.clear();
87     }
88 
testValues()89     public void testValues() {
90         MultiHashMap map = new MultiHashMap();
91         loadMap(map);
92 
93         Collection vals = map.values();
94         assertTrue(vals.size() == getFullSize());
95 
96         map.clear();
97     }
98 
99     static private class MapPair {
MapPair(int key, String val)100         MapPair(int key, String val) {
101             mKey = new Integer(key);
102             mValue = val;
103         }
104 
105         Integer mKey = null;
106         String mValue = null;
107     }
108 
109     static private MapPair[][] sMapPairs =
110     {
111         {new MapPair(0,"zero")},
112         {new MapPair(1,"one"), new MapPair(1,"ONE"), new MapPair(1,"uno")},
113         {new MapPair(2,"two"), new MapPair(2,"two") },
114         {new MapPair(3,"three"), new MapPair(3,"THREE"), new MapPair(3,"tres")},
115         {new MapPair(4,"four"), new MapPair(4,"quatro")}
116     };
117 
loadMap(MultiHashMap map)118     private void loadMap(MultiHashMap map) {
119         // Set up so that we load the keys "randomly"
120         // (i.e. we don't want to load int row-order, so that all like keys
121         // load together. We want to mix it up...)
122 
123         int numRows = sMapPairs.length;
124         int maxCols = 0;
125         for (int ii = 0; ii < sMapPairs.length; ii++) {
126             if (sMapPairs[ii].length > maxCols) {
127                 maxCols = sMapPairs[ii].length;
128             }
129         }
130         for (int ii = 0; ii < maxCols; ii++) {
131             for (int jj = 0; jj < numRows; jj++) {
132                 if (ii < sMapPairs[jj].length) {
133                     map.put(sMapPairs[jj][ii].mKey, sMapPairs[jj][ii].mValue);
134                     //---------------------------------------------------------
135                 }
136             }
137         }
138         assertTrue(map.size() == sMapPairs.length);
139     }
140 
checkMap(MultiHashMap map)141     private void checkMap(MultiHashMap map) {
142         for (int ii = 0; ii < sMapPairs.length; ii++) {
143             checkKeyList(map, ii);
144         }
145     }
146 
checkKeyList(MultiHashMap map, int index)147     private void checkKeyList(MultiHashMap map, int index) {
148         assertTrue(index < sMapPairs.length);
149         Integer key = sMapPairs[index][0].mKey;
150 
151         Object obj = map.get(key);
152         //--------------------------
153 
154         assertTrue(obj != null);
155         assertTrue(obj instanceof Collection);
156         Collection keyList = (Collection) obj;
157 
158         assertTrue(keyList.size() == sMapPairs[index].length);
159         Iterator iter = keyList.iterator();
160         while (iter.hasNext()) {
161             Object oval = iter.next();
162             assertTrue(oval != null);
163             assertTrue(oval instanceof String);
164             String val = (String) oval;
165             boolean foundIt = false;
166             for (int ii = 0; ii < sMapPairs[index].length; ii++) {
167                 if (val.equals(sMapPairs[index][ii].mValue)) {
168                     foundIt = true;
169                 }
170             }
171             assertTrue(foundIt);
172         }
173     }
174 
175     public int getFullSize() {
176         int len = 0;
177         for (int ii = 0; ii < sMapPairs.length; ii++) {
178             len += sMapPairs[ii].length;
179         }
180         return len;
181     }
182 
183 
184     public void testEntrySetIterator() {
185     }
186     public void testEntrySetContainsProperMappings() {
187     }
188     public void testEntrySetIteratorHasProperMappings() {
189         // override and ignore test -- it will fail when verifying the iterator for
190         // the set contains the right value -- we're not returning the value, we're
191         // returning a collection.
192         // TODO: re-implement this test to ensure the values of the iterator match
193         // the proper collection rather than the value the superclass is checking
194         // for.
195         return;
196     }
197 
198     // Next methods are overriden because MultiHashMap values are always a
199     // collection, and deviate from the Map contract because of this.
200 
201     // TODO: implement the tests to ensure that Map.get(Object) returns the
202     // appropriate collection of values
203 
204     public void testMapGet() {
205     }
206 
207     public void testMapPut() {
208     }
209 
210     public void testMapPutAll() {
211     }
212 
213     public void testMapRemove() {
214     }
215 
216     public void testMapEquals() {
217         MultiHashMap one = new MultiHashMap();
218         Integer value = new Integer(1);
219         one.put("One", value);
220         one.remove("One", value);
221 
222         MultiHashMap two = new MultiHashMap();
223         assertEquals(two, one);
224     }
225 
226     public void testMapHashCode() {
227     }
228 
229     // The verification for the map and its entry set must also be overridden
230     // because the values are not going to be the same as the values in the
231     // confirmed map (they're going to be collections of values instead).
232     public void verifyMap() {
233         // TODO: implement test to ensure that map is the same as confirmed if
234         // its values were converted into collections.
235     }
236 
237     public void verifyEntrySet() {
238         // TODO: implement test to ensure that each entry is the same as one in
239         // the confirmed map, but with the value wrapped in a collection.
240     }
241 
242     // The verification method must be overridden because MultiHashMap's
243     // values() is not properly backed by the map (Bug 9573).
244 
245     public void verifyValues() {
246         // update the values view to the latest version, then proceed to verify
247         // as usual.
248         values = map.values();
249         super.verifyValues();
250     }
251 
252     //-----------------------------------------------------------------------
253     public void testGetCollection() {
254         MultiHashMap map = new MultiHashMap();
255         map.put("A", "AA");
256         assertSame(map.get("A"), map.getCollection("A"));
257     }
258 
259     public void testTotalSize() {
260         MultiHashMap map = new MultiHashMap();
261         assertEquals(0, map.totalSize());
262         map.put("A", "AA");
263         assertEquals(1, map.totalSize());
264         map.put("B", "BA");
265         assertEquals(2, map.totalSize());
266         map.put("B", "BB");
267         assertEquals(3, map.totalSize());
268         map.put("B", "BC");
269         assertEquals(4, map.totalSize());
270         map.remove("A");
271         assertEquals(3, map.totalSize());
272         map.remove("B", "BC");
273         assertEquals(2, map.totalSize());
274     }
275 
276     public void testSize_Key() {
277         MultiHashMap map = new MultiHashMap();
278         assertEquals(0, map.size("A"));
279         assertEquals(0, map.size("B"));
280         map.put("A", "AA");
281         assertEquals(1, map.size("A"));
282         assertEquals(0, map.size("B"));
283         map.put("B", "BA");
284         assertEquals(1, map.size("A"));
285         assertEquals(1, map.size("B"));
286         map.put("B", "BB");
287         assertEquals(1, map.size("A"));
288         assertEquals(2, map.size("B"));
289         map.put("B", "BC");
290         assertEquals(1, map.size("A"));
291         assertEquals(3, map.size("B"));
292         map.remove("A");
293         assertEquals(0, map.size("A"));
294         assertEquals(3, map.size("B"));
295         map.remove("B", "BC");
296         assertEquals(0, map.size("A"));
297         assertEquals(2, map.size("B"));
298     }
299 
300     public void testIterator_Key() {
301         MultiHashMap map = new MultiHashMap();
302         assertEquals(false, map.iterator("A").hasNext());
303         map.put("A", "AA");
304         Iterator it = map.iterator("A");
305         assertEquals(true, it.hasNext());
306         it.next();
307         assertEquals(false, it.hasNext());
308     }
309 
310     public void testContainsValue_Key() {
311         MultiHashMap map = new MultiHashMap();
312         assertEquals(false, map.containsValue("A", "AA"));
313         assertEquals(false, map.containsValue("B", "BB"));
314         map.put("A", "AA");
315         assertEquals(true, map.containsValue("A", "AA"));
316         assertEquals(false, map.containsValue("A", "AB"));
317     }
318 
319     public void testPutAll_Map1() {
320         MultiMap original = new MultiHashMap();
321         original.put("key", "object1");
322         original.put("key", "object2");
323 
324         MultiHashMap test = new MultiHashMap();
325         test.put("keyA", "objectA");
326         test.put("key", "object0");
327         test.putAll(original);
328 
329         assertEquals(2, test.size());
330         assertEquals(4, test.totalSize());
331         assertEquals(1, test.getCollection("keyA").size());
332         assertEquals(3, test.getCollection("key").size());
333         assertEquals(true, test.containsValue("objectA"));
334         assertEquals(true, test.containsValue("object0"));
335         assertEquals(true, test.containsValue("object1"));
336         assertEquals(true, test.containsValue("object2"));
337     }
338 
339     public void testPutAll_Map2() {
340         Map original = new HashMap();
341         original.put("keyX", "object1");
342         original.put("keyY", "object2");
343 
344         MultiHashMap test = new MultiHashMap();
345         test.put("keyA", "objectA");
346         test.put("keyX", "object0");
347         test.putAll(original);
348 
349         assertEquals(3, test.size());
350         assertEquals(4, test.totalSize());
351         assertEquals(1, test.getCollection("keyA").size());
352         assertEquals(2, test.getCollection("keyX").size());
353         assertEquals(1, test.getCollection("keyY").size());
354         assertEquals(true, test.containsValue("objectA"));
355         assertEquals(true, test.containsValue("object0"));
356         assertEquals(true, test.containsValue("object1"));
357         assertEquals(true, test.containsValue("object2"));
358     }
359 
360     public void testPutAll_KeyCollection() {
361         MultiHashMap map = new MultiHashMap();
362         Collection coll = Arrays.asList(new Object[] {"X", "Y", "Z"});
363 
364         assertEquals(true, map.putAll("A", coll));
365         assertEquals(3, map.size("A"));
366         assertEquals(true, map.containsValue("A", "X"));
367         assertEquals(true, map.containsValue("A", "Y"));
368         assertEquals(true, map.containsValue("A", "Z"));
369 
370         assertEquals(false, map.putAll("A", null));
371         assertEquals(3, map.size("A"));
372         assertEquals(true, map.containsValue("A", "X"));
373         assertEquals(true, map.containsValue("A", "Y"));
374         assertEquals(true, map.containsValue("A", "Z"));
375 
376         assertEquals(false, map.putAll("A", new ArrayList()));
377         assertEquals(3, map.size("A"));
378         assertEquals(true, map.containsValue("A", "X"));
379         assertEquals(true, map.containsValue("A", "Y"));
380         assertEquals(true, map.containsValue("A", "Z"));
381 
382         coll = Arrays.asList(new Object[] {"M"});
383         assertEquals(true, map.putAll("A", coll));
384         assertEquals(4, map.size("A"));
385         assertEquals(true, map.containsValue("A", "X"));
386         assertEquals(true, map.containsValue("A", "Y"));
387         assertEquals(true, map.containsValue("A", "Z"));
388         assertEquals(true, map.containsValue("A", "M"));
389     }
390 
391     public void testClone() {
392         MultiHashMap map = new MultiHashMap();
393         map.put("A", "1");
394         map.put("A", "2");
395         Collection coll = (Collection) map.get("A");
396         assertEquals(1, map.size());
397         assertEquals(2, coll.size());
398 
399         MultiHashMap cloned = (MultiHashMap) map.clone();
400         Collection clonedColl = (Collection) cloned.get("A");
401         assertNotSame(map, cloned);
402         assertNotSame(coll, clonedColl);
403         assertEquals(1, map.size());
404         assertEquals(2, coll.size());
405         assertEquals(1, cloned.size());
406         assertEquals(2, clonedColl.size());
407         map.put("A", "3");
408         assertEquals(1, map.size());
409         assertEquals(3, coll.size());
410         assertEquals(1, cloned.size());
411         assertEquals(2, clonedColl.size());
412     }
413 
414     public void testConstructorCopy1() {
415         MultiHashMap map = new MultiHashMap();
416         map.put("A", "1");
417         map.put("A", "2");
418         Collection coll = (Collection) map.get("A");
419         assertEquals(1, map.size());
420         assertEquals(2, coll.size());
421 
422         MultiHashMap newMap = new MultiHashMap(map);
423         Collection newColl = (Collection) newMap.get("A");
424         assertNotSame(map, newMap);
425         assertNotSame(coll, newColl);
426         assertEquals(1, map.size());
427         assertEquals(2, coll.size());
428         assertEquals(1, newMap.size());
429         assertEquals(2, newColl.size());
430 
431         map.put("A", "3");
432         assertEquals(1, map.size());
433         assertEquals(3, coll.size());
434         assertEquals(1, newMap.size());
435         assertEquals(2, newColl.size());
436     }
437 
438     public void testConstructorCopy2() {
439         Map map = new HashMap();
440         map.put("A", "1");
441         map.put("B", "2");
442         assertEquals(2, map.size());
443 
444         MultiHashMap newMap = new MultiHashMap(map);
445         Collection newColl = (Collection) newMap.get("A");
446         assertNotSame(map, newMap);
447         assertEquals(2, map.size());
448         assertEquals(2, newMap.size());
449         assertEquals(1, newColl.size());
450 
451         map.put("A", "3");
452         assertEquals(2, map.size());
453         assertEquals(2, newMap.size());
454         assertEquals(1, newColl.size());
455 
456         map.put("C", "4");
457         assertEquals(3, map.size());
458         assertEquals(2, newMap.size());
459         assertEquals(1, newColl.size());
460     }
461 
462     public void testRemove_KeyItem() {
463         MultiHashMap map = new MultiHashMap();
464         map.put("A", "AA");
465         map.put("A", "AB");
466         map.put("A", "AC");
467         assertEquals(false, map.remove("C", "CA"));
468         assertEquals(false, map.remove("A", "AD"));
469         assertEquals(true, map.remove("A", "AC"));
470         assertEquals(true, map.remove("A", "AB"));
471         assertEquals(true, map.remove("A", "AA"));
472         assertEquals(new MultiHashMap(), map);
473     }
474 
475 }
476