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
18package org.apache.harmony.tests.java.util;
19
20import org.apache.harmony.testframework.serialization.SerializationTest;
21import tests.support.Support_MapTest2;
22import java.io.Serializable;
23import java.util.AbstractMap;
24import java.util.ArrayList;
25import java.util.Arrays;
26import java.util.Collection;
27import java.util.HashMap;
28import java.util.IdentityHashMap;
29import java.util.Iterator;
30import java.util.Map;
31import java.util.Set;
32import java.util.TreeMap;
33
34public class IdentityHashMap2Test extends junit.framework.TestCase {
35    private static final String ID = "hello";
36
37    class MockMap extends AbstractMap {
38        public Set entrySet() {
39            return null;
40        }
41
42        public int size() {
43            return 0;
44        }
45    }
46    private IdentityHashMap hm;
47
48    private final static int hmSize = 20;
49
50    private Object[] objArray;
51
52    private Object[] objArray2;
53
54    /**
55     * java.util.IdentityHashMap#IdentityHashMap()
56     */
57    public void test_Constructor() {
58        // Test for method java.util.IdentityHashMap()
59        new Support_MapTest2(new IdentityHashMap()).runTest();
60
61        IdentityHashMap hm2 = new IdentityHashMap();
62        assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
63    }
64
65    /**
66     * java.util.IdentityHashMap#IdentityHashMap(int)
67     */
68    public void test_ConstructorI() {
69        // Test for method java.util.IdentityHashMap(int)
70        IdentityHashMap hm2 = new IdentityHashMap(5);
71        assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
72        try {
73            new IdentityHashMap(-1);
74        } catch (IllegalArgumentException e) {
75            return;
76        }
77        fail(
78                "Failed to throw IllegalArgumentException for initial capacity < 0");
79
80        IdentityHashMap empty = new IdentityHashMap(0);
81        assertNull("Empty IdentityHashMap access", empty.get("nothing"));
82        empty.put("something", "here");
83        assertTrue("cannot get element", empty.get("something") == "here");
84    }
85
86    /**
87     * java.util.IdentityHashMap#IdentityHashMap(java.util.Map)
88     */
89    public void test_ConstructorLjava_util_Map() {
90        // Test for method java.util.IdentityHashMap(java.util.Map)
91        Map myMap = new TreeMap();
92        for (int counter = 0; counter < hmSize; counter++)
93            myMap.put(objArray2[counter], objArray[counter]);
94        IdentityHashMap hm2 = new IdentityHashMap(myMap);
95        for (int counter = 0; counter < hmSize; counter++)
96            assertTrue("Failed to construct correct IdentityHashMap", hm
97                    .get(objArray2[counter]) == hm2.get(objArray2[counter]));
98
99        Map mockMap = new MockMap();
100        hm2 = new IdentityHashMap(mockMap);
101        assertEquals("Size should be 0", 0, hm2.size());
102    }
103
104    public void test_IdentityHashMap_Constructor_BigSize() {
105        try {
106            new IdentityHashMap(Integer.MAX_VALUE);
107            fail("should throw OutOfMemoryError");
108        } catch (OutOfMemoryError e) {
109            // Expected
110        }
111    }
112
113    /**
114     * java.util.IdentityHashMap#clear()
115     */
116    public void test_clear() {
117        // Test for method void java.util.IdentityHashMap.clear()
118        hm.clear();
119        assertEquals("Clear failed to reset size", 0, hm.size());
120        for (int i = 0; i < hmSize; i++)
121            assertNull("Failed to clear all elements",
122                    hm.get(objArray2[i]));
123
124    }
125
126    /**
127     * java.util.IdentityHashMap#clone()
128     */
129    public void test_clone() {
130        // Test for method java.lang.Object java.util.IdentityHashMap.clone()
131        IdentityHashMap hm2 = (IdentityHashMap) hm.clone();
132        assertTrue("Clone answered equivalent IdentityHashMap", hm2 != hm);
133        for (int counter = 0; counter < hmSize; counter++)
134            assertTrue("Clone answered unequal IdentityHashMap", hm
135                    .get(objArray2[counter]) == hm2.get(objArray2[counter]));
136
137        IdentityHashMap map = new IdentityHashMap();
138        map.put("key", "value");
139        // get the keySet() and values() on the original Map
140        Set keys = map.keySet();
141        Collection values = map.values();
142        assertSame("values() does not work",
143                "value", values.iterator().next());
144        assertSame("keySet() does not work",
145                "key", keys.iterator().next());
146        AbstractMap map2 = (AbstractMap) map.clone();
147        map2.put("key", "value2");
148        Collection values2 = map2.values();
149        assertTrue("values() is identical", values2 != values);
150        // values() and keySet() on the cloned() map should be different
151        assertEquals("values() was not cloned",
152                "value2", values2.iterator().next());
153        map2.clear();
154        map2.put("key2", "value3");
155        Set key2 = map2.keySet();
156        assertTrue("keySet() is identical", key2 != keys);
157        assertSame("keySet() was not cloned",
158                "key2", key2.iterator().next());
159    }
160
161    /**
162     * java.util.IdentityHashMap#containsKey(java.lang.Object)
163     */
164    public void test_containsKeyLjava_lang_Object() {
165        IdentityHashMap m = new IdentityHashMap();
166        m.put(null, "test");
167        assertTrue("Failed with null key", m.containsKey(null));
168        assertFalse("Failed with missing key matching null hash", m.containsKey(new Integer(0)));
169    }
170
171    public static class TestKey implements Cloneable {
172        private final String foo;
173
174        TestKey(String foo) {
175            this.foo = foo;
176        }
177
178        @Override
179        public boolean equals(Object o) {
180            return o instanceof TestKey && foo.equals(((TestKey) o).foo);
181        }
182
183        public Object clone() throws CloneNotSupportedException {
184            return super.clone();
185        }
186    }
187
188    public void test_containsKey_copies() throws Exception {
189        TestKey a = new TestKey("a");
190        hm.put(a, new Object());
191        assertTrue(hm.containsKey(a));
192        assertFalse(hm.containsKey(a.clone()));
193    }
194
195    /**
196     * java.util.IdentityHashMap#containsValue(java.lang.Object)
197     */
198    public void test_containsValueLjava_lang_Object() {
199        // Test for method boolean
200        // java.util.IdentityHashMap.containsValue(java.lang.Object)
201        assertTrue("Returned false for valid value", hm
202                .containsValue(objArray[19]));
203        assertTrue("Returned true for invalid valie", !hm
204                .containsValue(new Integer(-9)));
205    }
206
207    /**
208     * java.util.IdentityHashMap#entrySet()
209     */
210    public void test_entrySet() {
211        // Test for method java.util.Set java.util.IdentityHashMap.entrySet()
212        Set s = hm.entrySet();
213        Iterator i = s.iterator();
214        assertTrue("Returned set of incorrect size", hm.size() == s.size());
215        while (i.hasNext()) {
216            Map.Entry m = (Map.Entry) i.next();
217            assertTrue("Returned incorrect entry set", hm.containsKey(m
218                    .getKey())
219                    && hm.containsValue(m.getValue()));
220        }
221    }
222
223    /**
224     * java.util.IdentityHashMap#get(java.lang.Object)
225     */
226    public void test_getLjava_lang_Object() {
227        // Test for method java.lang.Object
228        // java.util.IdentityHashMap.get(java.lang.Object)
229        assertNull("Get returned non-null for non existent key",
230                hm.get("T"));
231        hm.put("T", "HELLO");
232        assertEquals("Get returned incorecct value for existing key", "HELLO", hm.get("T"));
233
234        IdentityHashMap m = new IdentityHashMap();
235        m.put(null, "test");
236        assertEquals("Failed with null key", "test", m.get(null));
237        assertNull("Failed with missing key matching null hash", m
238                .get(new Integer(0)));
239    }
240
241    /**
242     * java.util.IdentityHashMap#isEmpty()
243     */
244    public void test_isEmpty() {
245        // Test for method boolean java.util.IdentityHashMap.isEmpty()
246        assertTrue("Returned false for new map", new IdentityHashMap()
247                .isEmpty());
248        assertTrue("Returned true for non-empty", !hm.isEmpty());
249    }
250
251    /**
252     * java.util.IdentityHashMap#keySet()
253     */
254    public void test_keySet() {
255        // Test for method java.util.Set java.util.IdentityHashMap.keySet()
256        Set s = hm.keySet();
257        assertTrue("Returned set of incorrect size()", s.size() == hm.size());
258        for (int i = 0; i < objArray.length; i++) {
259            assertTrue("Returned set does not contain all keys", s
260                    .contains(objArray2[i]));
261        }
262
263        IdentityHashMap m = new IdentityHashMap();
264        m.put(null, "test");
265        assertTrue("Failed with null key", m.keySet().contains(null));
266        assertNull("Failed with null key", m.keySet().iterator().next());
267
268        Map map = new IdentityHashMap(101);
269        map.put(new Integer(1), "1");
270        map.put(new Integer(102), "102");
271        map.put(new Integer(203), "203");
272        Iterator it = map.keySet().iterator();
273        Integer remove1 = (Integer) it.next();
274        it.hasNext();
275        it.remove();
276        Integer remove2 = (Integer) it.next();
277        it.remove();
278        ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
279                new Integer(1), new Integer(102), new Integer(203) }));
280        list.remove(remove1);
281        list.remove(remove2);
282        assertTrue("Wrong result", it.next().equals(list.get(0)));
283        assertEquals("Wrong size", 1, map.size());
284        assertTrue("Wrong contents", map.keySet().iterator().next().equals(
285                list.get(0)));
286
287        Map map2 = new IdentityHashMap(101);
288        map2.put(new Integer(1), "1");
289        map2.put(new Integer(4), "4");
290        Iterator it2 = map2.keySet().iterator();
291        Integer remove3 = (Integer) it2.next();
292        Integer next;
293        if (remove3.intValue() == 1)
294            next = new Integer(4);
295        else
296            next = new Integer(1);
297        it2.hasNext();
298        it2.remove();
299        assertTrue("Wrong result 2", it2.next().equals(next));
300        assertEquals("Wrong size 2", 1, map2.size());
301        assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
302                next));
303    }
304
305    /**
306     * java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
307     */
308    public void test_putLjava_lang_ObjectLjava_lang_Object() {
309        // Test for method java.lang.Object
310        // java.util.IdentityHashMap.put(java.lang.Object, java.lang.Object)
311        hm.put("KEY", "VALUE");
312        assertEquals("Failed to install key/value pair",
313                "VALUE", hm.get("KEY"));
314
315        IdentityHashMap m = new IdentityHashMap();
316        Short s0 = new Short((short) 0);
317        m.put(s0, "short");
318        m.put(null, "test");
319        Integer i0 = new Integer(0);
320        m.put(i0, "int");
321        assertEquals("Failed adding to bucket containing null",
322                "short", m.get(s0));
323        assertEquals("Failed adding to bucket containing null2", "int", m.get(i0)
324        );
325    }
326
327    /**
328     * java.util.IdentityHashMap#putAll(java.util.Map)
329     */
330    public void test_putAllLjava_util_Map() {
331        // Test for method void java.util.IdentityHashMap.putAll(java.util.Map)
332        IdentityHashMap hm2 = new IdentityHashMap();
333        hm2.putAll(hm);
334        for (int i = 0; i < hmSize; i++) {
335            assertTrue("Failed to clear all elements", hm2.get(objArray2[i])
336                    .equals((new Integer(i))));
337        }
338
339        hm2 = new IdentityHashMap();
340        Map mockMap = new MockMap();
341        hm2.putAll(mockMap);
342        assertEquals("Size should be 0", 0, hm2.size());
343    }
344
345    /**
346     * java.util.IdentityHashMap#remove(java.lang.Object)
347     */
348    public void test_removeLjava_lang_Object() {
349        // Test for method java.lang.Object
350        // java.util.IdentityHashMap.remove(java.lang.Object)
351        int size = hm.size();
352        Integer x = ((Integer) hm.remove(objArray2[9]));
353        assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
354        assertNull("Failed to remove given key", hm.get(objArray2[9]));
355        assertTrue("Failed to decrement size", hm.size() == (size - 1));
356        assertNull("Remove of non-existent key returned non-null", hm
357                .remove("LCLCLC"));
358
359        IdentityHashMap m = new IdentityHashMap();
360        m.put(null, "test");
361        assertNull("Failed with same hash as null",
362                m.remove(objArray[0]));
363        assertEquals("Failed with null key", "test", m.remove(null));
364    }
365
366    /**
367     * java.util.IdentityHashMap#size()
368     */
369    public void test_size() {
370        // Test for method int java.util.IdentityHashMap.size()
371        assertEquals("Returned incorrect size, ", (objArray.length), hm.size());
372    }
373
374    /**
375     * java.util.IdentityHashMap#equals(java.lang.Object)
376     */
377    public void test_equalsLjava_lang_Object() {
378        IdentityHashMap mapOne = new IdentityHashMap();
379        IdentityHashMap mapTwo = new IdentityHashMap();
380        IdentityHashMap mapThree = new IdentityHashMap();
381        IdentityHashMap mapFour = new IdentityHashMap();
382
383        String one = "one";
384        String alsoOne = new String(one); // use the new operator to ensure a
385        // new reference is constructed
386        String two = "two";
387        String alsoTwo = new String(two); // use the new operator to ensure a
388        // new reference is constructed
389
390        mapOne.put(one, two);
391        mapFour.put(one, two);
392
393        // these two are not equal to the above two
394        mapTwo.put(alsoOne, two);
395        mapThree.put(one, alsoTwo);
396
397        assertEquals("failure of equality of IdentityHashMaps", mapOne, mapFour);
398        assertTrue("failure of non-equality of IdentityHashMaps one and two",
399                !mapOne.equals(mapTwo));
400        assertTrue("failure of non-equality of IdentityHashMaps one and three",
401                !mapOne.equals(mapThree));
402        assertTrue("failure of non-equality of IdentityHashMaps two and three",
403                !mapTwo.equals(mapThree));
404
405        HashMap hashMapTwo = new HashMap();
406        HashMap hashMapThree = new HashMap();
407        hashMapTwo.put(alsoOne, two);
408        hashMapThree.put(one, alsoTwo);
409
410        assertTrue(
411                "failure of non-equality of IdentityHashMaps one and Hashmap two",
412                !mapOne.equals(hashMapTwo));
413        assertTrue(
414                "failure of non-equality of IdentityHashMaps one and Hashmap three",
415                !mapOne.equals(hashMapThree));
416    }
417
418    /**
419     * java.util.IdentityHashMap#values()
420     */
421    public void test_values() {
422        // Test for method java.util.Collection
423        // java.util.IdentityHashMap.values()
424        Collection c = hm.values();
425        assertTrue("Returned collection of incorrect size()", c.size() == hm
426                .size());
427        for (int i = 0; i < objArray.length; i++)
428            assertTrue("Returned collection does not contain all keys", c
429                    .contains(objArray[i]));
430
431        IdentityHashMap myIdentityHashMap = new IdentityHashMap();
432        for (int i = 0; i < hmSize; i++)
433            myIdentityHashMap.put(objArray2[i], objArray[i]);
434        Collection values = myIdentityHashMap.values();
435        values.remove(objArray[0]);
436        assertTrue(
437                "Removing from the values collection should remove from the original map",
438                !myIdentityHashMap.containsValue(objArray2[0]));
439
440    }
441
442    protected void setUp() {
443        objArray = new Object[hmSize];
444        objArray2 = new Object[hmSize];
445        for (int i = 0; i < objArray.length; i++) {
446            objArray[i] = new Integer(i);
447            objArray2[i] = objArray[i].toString();
448        }
449
450        hm = new IdentityHashMap();
451        for (int i = 0; i < objArray.length; i++) {
452            hm.put(objArray2[i], objArray[i]);
453        }
454    }
455
456
457    private static final SerializationTest.SerializableAssert comparator = new
458            SerializationTest.SerializableAssert() {
459
460                public void assertDeserialized(Serializable initial, Serializable deserialized) {
461                    IdentityHashMap<String, String> initialMap = (IdentityHashMap<String, String>) initial;
462                    IdentityHashMap<String, String> deseriaMap = (IdentityHashMap<String, String>) deserialized;
463                    assertEquals("should be equal", initialMap.size(), deseriaMap.size());
464                }
465
466            };
467}
468