HashMapTest.java revision 6d5c5d6c3e64b37d67af1d516b70a3fee38b2796
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 tests.api.java.util;
19
20import dalvik.annotation.TestTargetNew;
21import dalvik.annotation.TestTargets;
22import dalvik.annotation.TestLevel;
23import dalvik.annotation.TestTargetClass;
24
25import java.util.AbstractMap;
26import java.util.ArrayList;
27import java.util.Arrays;
28import java.util.Collection;
29import java.util.HashMap;
30import java.util.Iterator;
31import java.util.Map;
32import java.util.Set;
33import java.util.TreeMap;
34
35import tests.support.Support_MapTest2;
36import tests.support.Support_UnmodifiableCollectionTest;
37
38@TestTargetClass(HashMap.class)
39public class HashMapTest extends junit.framework.TestCase {
40    class MockMap extends AbstractMap {
41        public Set entrySet() {
42            return null;
43        }
44        public int size(){
45            return 0;
46        }
47    }
48
49    private static class MockMapNull extends AbstractMap {
50        public Set entrySet() {
51            return null;
52        }
53
54        public int size() {
55            return 10;
56        }
57    }
58
59    HashMap hm;
60
61    final static int hmSize = 1000;
62
63    Object[] objArray;
64
65    Object[] objArray2;
66
67    /**
68     * @tests java.util.HashMap#HashMap()
69     */
70    @TestTargetNew(
71        level = TestLevel.COMPLETE,
72        notes = "",
73        method = "HashMap",
74        args = {}
75    )
76    public void test_Constructor() {
77        // Test for method java.util.HashMap()
78        new Support_MapTest2(new HashMap()).runTest();
79
80        HashMap hm2 = new HashMap();
81        assertEquals("Created incorrect HashMap", 0, hm2.size());
82    }
83
84    /**
85     * @tests java.util.HashMap#HashMap(int)
86     */
87    @TestTargetNew(
88        level = TestLevel.COMPLETE,
89        notes = "",
90        method = "HashMap",
91        args = {int.class}
92    )
93    public void test_ConstructorI() {
94        // Test for method java.util.HashMap(int)
95        HashMap hm2 = new HashMap(5);
96        assertEquals("Created incorrect HashMap", 0, hm2.size());
97        try {
98            new HashMap(-1);
99            fail("IllegalArgumentException expected");
100        } catch (IllegalArgumentException e) {
101            //expected
102        }
103
104        HashMap empty = new HashMap(0);
105        assertNull("Empty hashmap access", empty.get("nothing"));
106        empty.put("something", "here");
107        assertTrue("cannot get element", empty.get("something") == "here");
108    }
109
110    /**
111     * @tests java.util.HashMap#HashMap(int, float)
112     */
113    @TestTargetNew(
114        level = TestLevel.COMPLETE,
115        notes = "",
116        method = "HashMap",
117        args = {int.class, float.class}
118    )
119    public void test_ConstructorIF() {
120        // Test for method java.util.HashMap(int, float)
121        HashMap hm2 = new HashMap(5, (float) 0.5);
122        assertEquals("Created incorrect HashMap", 0, hm2.size());
123        try {
124            new HashMap(0, 0);
125            fail("IllegalArgumentException expected");
126        } catch (IllegalArgumentException e) {
127            //expected
128        }
129
130        HashMap empty = new HashMap(0, 0.75f);
131        assertNull("Empty hashtable access", empty.get("nothing"));
132        empty.put("something", "here");
133        assertTrue("cannot get element", empty.get("something") == "here");
134    }
135
136    /**
137     * @tests java.util.HashMap#HashMap(java.util.Map)
138     */
139    @TestTargetNew(
140        level = TestLevel.COMPLETE,
141        notes = "",
142        method = "HashMap",
143        args = {java.util.Map.class}
144    )
145    public void test_ConstructorLjava_util_Map() {
146        // Test for method java.util.HashMap(java.util.Map)
147        Map myMap = new TreeMap();
148        for (int counter = 0; counter < hmSize; counter++)
149            myMap.put(objArray2[counter], objArray[counter]);
150        HashMap hm2 = new HashMap(myMap);
151        for (int counter = 0; counter < hmSize; counter++)
152            assertTrue("Failed to construct correct HashMap", hm
153                    .get(objArray2[counter]) == hm2.get(objArray2[counter]));
154
155        try {
156            Map mockMap = new MockMap();
157            hm = new HashMap(mockMap);
158            fail("Should throw NullPointerException");
159        } catch (NullPointerException e) {
160            //empty
161        }
162    }
163
164    /**
165     * @tests java.util.HashMap#clear()
166     */
167    @TestTargetNew(
168        level = TestLevel.COMPLETE,
169        notes = "",
170        method = "clear",
171        args = {}
172    )
173    public void test_clear() {
174        // Test for method void java.util.HashMap.clear()
175        hm.clear();
176        assertEquals("Clear failed to reset size", 0, hm.size());
177        for (int i = 0; i < hmSize; i++)
178            assertNull("Failed to clear all elements",
179                    hm.get(objArray2[i]));
180
181    }
182
183    /**
184     * @tests java.util.HashMap#clone()
185     */
186    @TestTargetNew(
187        level = TestLevel.COMPLETE,
188        notes = "",
189        method = "clone",
190        args = {}
191    )
192    public void test_clone() {
193        // Test for method java.lang.Object java.util.HashMap.clone()
194        HashMap hm2 = (HashMap) hm.clone();
195        assertTrue("Clone answered equivalent HashMap", hm2 != hm);
196        for (int counter = 0; counter < hmSize; counter++)
197            assertTrue("Clone answered unequal HashMap", hm
198                    .get(objArray2[counter]) == hm2.get(objArray2[counter]));
199
200        HashMap map = new HashMap();
201        map.put("key", "value");
202        // get the keySet() and values() on the original Map
203        Set keys = map.keySet();
204        Collection values = map.values();
205        assertEquals("values() does not work",
206                "value", values.iterator().next());
207        assertEquals("keySet() does not work",
208                "key", keys.iterator().next());
209        AbstractMap map2 = (AbstractMap) map.clone();
210        map2.put("key", "value2");
211        Collection values2 = map2.values();
212        assertTrue("values() is identical", values2 != values);
213        // values() and keySet() on the cloned() map should be different
214        assertEquals("values() was not cloned",
215                "value2", values2.iterator().next());
216        map2.clear();
217        map2.put("key2", "value3");
218        Set key2 = map2.keySet();
219        assertTrue("keySet() is identical", key2 != keys);
220        assertEquals("keySet() was not cloned",
221                "key2", key2.iterator().next());
222
223        // regresion test for HARMONY-4603
224        HashMap hashmap = new HashMap();
225        MockClonable mock = new MockClonable(1);
226        hashmap.put(1, mock);
227        assertEquals(1, ((MockClonable) hashmap.get(1)).i);
228        HashMap hm3 = (HashMap)hashmap.clone();
229        assertEquals(1, ((MockClonable) hm3.get(1)).i);
230        mock.i = 0;
231        assertEquals(0, ((MockClonable) hashmap.get(1)).i);
232        assertEquals(0, ((MockClonable) hm3.get(1)).i);
233    }
234
235    /**
236     * @tests java.util.HashMap#containsKey(java.lang.Object)
237     */
238    @TestTargetNew(
239        level = TestLevel.COMPLETE,
240        notes = "",
241        method = "containsKey",
242        args = {java.lang.Object.class}
243    )
244    public void test_containsKeyLjava_lang_Object() {
245        // Test for method boolean
246        // java.util.HashMap.containsKey(java.lang.Object)
247        assertTrue("Returned false for valid key", hm.containsKey(new Integer(
248                876).toString()));
249        assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
250
251        HashMap m = new HashMap();
252        m.put(null, "test");
253        assertTrue("Failed with null key", m.containsKey(null));
254        assertTrue("Failed with missing key matching null hash", !m
255                .containsKey(new Integer(0)));
256    }
257
258    /**
259     * @tests java.util.HashMap#containsValue(java.lang.Object)
260     */
261    @TestTargetNew(
262        level = TestLevel.COMPLETE,
263        notes = "",
264        method = "containsValue",
265        args = {java.lang.Object.class}
266    )
267    public void test_containsValueLjava_lang_Object() {
268        // Test for method boolean
269        // java.util.HashMap.containsValue(java.lang.Object)
270        assertTrue("Returned false for valid value", hm
271                .containsValue(new Integer(875)));
272        assertTrue("Returned true for invalid valie", !hm
273                .containsValue(new Integer(-9)));
274    }
275
276    /**
277     * @tests java.util.HashMap#entrySet()
278     */
279    @TestTargetNew(
280        level = TestLevel.COMPLETE,
281        notes = "",
282        method = "entrySet",
283        args = {}
284    )
285    public void test_entrySet() {
286        // Test for method java.util.Set java.util.HashMap.entrySet()
287        Set s = hm.entrySet();
288        Iterator i = s.iterator();
289        assertTrue("Returned set of incorrect size", hm.size() == s.size());
290        while (i.hasNext()) {
291            Map.Entry m = (Map.Entry) i.next();
292            assertTrue("Returned incorrect entry set", hm.containsKey(m
293                    .getKey())
294                    && hm.containsValue(m.getValue()));
295        }
296    }
297
298    /**
299     * @tests java.util.HashMap#get(java.lang.Object)
300     */
301    @TestTargetNew(
302        level = TestLevel.COMPLETE,
303        notes = "",
304        method = "get",
305        args = {java.lang.Object.class}
306    )
307    public void test_getLjava_lang_Object() {
308        // Test for method java.lang.Object
309        // java.util.HashMap.get(java.lang.Object)
310        assertNull("Get returned non-null for non existent key",
311                hm.get("T"));
312        hm.put("T", "HELLO");
313        assertEquals("Get returned incorrect value for existing key", "HELLO", hm.get("T")
314                );
315
316        HashMap m = new HashMap();
317        m.put(null, "test");
318        assertEquals("Failed with null key", "test", m.get(null));
319        assertNull("Failed with missing key matching null hash", m
320                .get(new Integer(0)));
321
322        // Regression for HARMONY-206
323        ReusableKey k = new ReusableKey();
324        HashMap map = new HashMap();
325        k.setKey(1);
326        map.put(k, "value1");
327
328        k.setKey(18);
329        assertNull(map.get(k));
330
331        k.setKey(17);
332        assertNull(map.get(k));
333    }
334
335    /**
336     * @tests java.util.HashMap#isEmpty()
337     */
338    @TestTargetNew(
339        level = TestLevel.COMPLETE,
340        notes = "",
341        method = "isEmpty",
342        args = {}
343    )
344    public void test_isEmpty() {
345        // Test for method boolean java.util.HashMap.isEmpty()
346        assertTrue("Returned false for new map", new HashMap().isEmpty());
347        assertTrue("Returned true for non-empty", !hm.isEmpty());
348    }
349
350    /**
351     * @tests java.util.HashMap#keySet()
352     */
353    @TestTargetNew(
354        level = TestLevel.COMPLETE,
355        notes = "",
356        method = "keySet",
357        args = {}
358    )
359    public void test_keySet() {
360        // Test for method java.util.Set java.util.HashMap.keySet()
361        Set s = hm.keySet();
362        assertTrue("Returned set of incorrect size()", s.size() == hm.size());
363        for (int i = 0; i < objArray.length; i++)
364            assertTrue("Returned set does not contain all keys", s
365                    .contains(objArray[i].toString()));
366
367        HashMap m = new HashMap();
368        m.put(null, "test");
369        assertTrue("Failed with null key", m.keySet().contains(null));
370        assertNull("Failed with null key", m.keySet().iterator().next());
371
372        Map map = new HashMap(101);
373        map.put(new Integer(1), "1");
374        map.put(new Integer(102), "102");
375        map.put(new Integer(203), "203");
376        Iterator it = map.keySet().iterator();
377        Integer remove1 = (Integer) it.next();
378        it.hasNext();
379        it.remove();
380        Integer remove2 = (Integer) it.next();
381        it.remove();
382        ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
383                new Integer(1), new Integer(102), new Integer(203) }));
384        list.remove(remove1);
385        list.remove(remove2);
386        assertTrue("Wrong result", it.next().equals(list.get(0)));
387        assertEquals("Wrong size", 1, map.size());
388        assertTrue("Wrong contents", map.keySet().iterator().next().equals(
389                list.get(0)));
390
391        Map map2 = new HashMap(101);
392        map2.put(new Integer(1), "1");
393        map2.put(new Integer(4), "4");
394        Iterator it2 = map2.keySet().iterator();
395        Integer remove3 = (Integer) it2.next();
396        Integer next;
397        if (remove3.intValue() == 1)
398            next = new Integer(4);
399        else
400            next = new Integer(1);
401        it2.hasNext();
402        it2.remove();
403        assertTrue("Wrong result 2", it2.next().equals(next));
404        assertEquals("Wrong size 2", 1, map2.size());
405        assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
406                next));
407    }
408
409    /**
410     * @tests java.util.HashMap#put(java.lang.Object, java.lang.Object)
411     */
412    @TestTargetNew(
413        level = TestLevel.COMPLETE,
414        notes = "",
415        method = "put",
416        args = {java.lang.Object.class, java.lang.Object.class}
417    )
418    public void test_putLjava_lang_ObjectLjava_lang_Object() {
419        // Test for method java.lang.Object
420        // java.util.HashMap.put(java.lang.Object, java.lang.Object)
421        hm.put("KEY", "VALUE");
422        assertEquals("Failed to install key/value pair",
423                "VALUE", hm.get("KEY"));
424
425        HashMap m = new HashMap();
426        m.put(new Short((short) 0), "short");
427        m.put(null, "test");
428        m.put(new Integer(0), "int");
429        assertEquals("Failed adding to bucket containing null", "short", m.get(
430                new Short((short) 0)));
431        assertEquals("Failed adding to bucket containing null2", "int", m.get(
432                new Integer(0)));
433    }
434
435    /**
436     * @tests java.util.HashMap#putAll(java.util.Map)
437     */
438    @TestTargetNew(
439        level = TestLevel.PARTIAL_COMPLETE,
440        notes = "Doesn't verify NullPointerException.",
441        method = "putAll",
442        args = {java.util.Map.class}
443    )
444    public void test_putAllLjava_util_Map() {
445        // Test for method void java.util.HashMap.putAll(java.util.Map)
446        HashMap hm2 = new HashMap();
447        hm2.putAll(hm);
448        for (int i = 0; i < 1000; i++)
449            assertTrue("Failed to clear all elements", hm2.get(
450                    new Integer(i).toString()).equals((new Integer(i))));
451
452        Map mockMap = new MockMap();
453        hm2 = new HashMap();
454        hm2.putAll(mockMap);
455        assertEquals("Size should be 0", 0, hm2.size());
456    }
457
458    /**
459     * @tests java.util.HashMap#putAll(java.util.Map)
460     */
461    @TestTargetNew(
462        level = TestLevel.PARTIAL_COMPLETE,
463        notes = "Verifies NullPointerException.",
464        method = "putAll",
465        args = {java.util.Map.class}
466    )
467    public void test_putAllLjava_util_Map_Null() {
468        HashMap hashMap = new HashMap();
469        try {
470            hashMap.putAll(new MockMapNull());
471            fail("Should throw NullPointerException");
472        } catch (NullPointerException e) {
473            // expected.
474        }
475
476        try {
477            hashMap = new HashMap(new MockMapNull());
478            fail("Should throw NullPointerException");
479        } catch (NullPointerException e) {
480            // expected.
481        }
482    }
483
484    /**
485     * @tests java.util.HashMap#remove(java.lang.Object)
486     */
487    @TestTargetNew(
488        level = TestLevel.COMPLETE,
489        notes = "",
490        method = "remove",
491        args = {java.lang.Object.class}
492    )
493    public void test_removeLjava_lang_Object() {
494        // Test for method java.lang.Object
495        // java.util.HashMap.remove(java.lang.Object)
496        int size = hm.size();
497        Integer y = new Integer(9);
498        Integer x = ((Integer) hm.remove(y.toString()));
499        assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
500        assertNull("Failed to remove given key", hm.get(new Integer(9)));
501        assertTrue("Failed to decrement size", hm.size() == (size - 1));
502        assertNull("Remove of non-existent key returned non-null", hm
503                .remove("LCLCLC"));
504
505        HashMap m = new HashMap();
506        m.put(null, "test");
507        assertNull("Failed with same hash as null",
508                m.remove(new Integer(0)));
509        assertEquals("Failed with null key", "test", m.remove(null));
510    }
511
512    /**
513     * @tests java.util.HashMap#size()
514     */
515    @TestTargetNew(
516        level = TestLevel.COMPLETE,
517        notes = "",
518        method = "size",
519        args = {}
520    )
521    public void test_size() {
522        // Test for method int java.util.HashMap.size()
523        assertTrue("Returned incorrect size",
524                hm.size() == (objArray.length + 2));
525    }
526
527    /**
528     * @tests java.util.HashMap#values()
529     */
530    @TestTargetNew(
531        level = TestLevel.COMPLETE,
532        notes = "",
533        method = "values",
534        args = {}
535    )
536    public void test_values() {
537        // Test for method java.util.Collection java.util.HashMap.values()
538        Collection c = hm.values();
539        assertTrue("Returned collection of incorrect size()", c.size() == hm
540                .size());
541        for (int i = 0; i < objArray.length; i++)
542            assertTrue("Returned collection does not contain all keys", c
543                    .contains(objArray[i]));
544
545        HashMap myHashMap = new HashMap();
546        for (int i = 0; i < 100; i++)
547            myHashMap.put(objArray2[i], objArray[i]);
548        Collection values = myHashMap.values();
549        new Support_UnmodifiableCollectionTest(
550                "Test Returned Collection From HashMap.values()", values)
551                .runTest();
552        values.remove(new Integer(0));
553        assertTrue(
554                "Removing from the values collection should remove from the original map",
555                !myHashMap.containsValue(new Integer(0)));
556
557    }
558
559    static class ReusableKey {
560        private int key = 0;
561
562        public void setKey(int key) {
563            this.key = key;
564        }
565
566        public int hashCode() {
567            return key;
568        }
569
570        public boolean equals(Object o) {
571            if (o == this) {
572                return true;
573            }
574            if (!(o instanceof ReusableKey)) {
575                return false;
576            }
577            return key == ((ReusableKey) o).key;
578        }
579    }
580    @TestTargetNew(
581        level = TestLevel.COMPLETE,
582        notes = "",
583        method = "hashCode",
584        args = {}
585    )
586    public void test_Map_Entry_hashCode() {
587        //Related to HARMONY-403
588        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(10);
589        Integer key = new Integer(1);
590        Integer val = new Integer(2);
591        map.put(key, val);
592        int expected = key.hashCode() ^ val.hashCode();
593        assertEquals(expected, map.hashCode());
594        key = new Integer(4);
595        val = new Integer(8);
596        map.put(key, val);
597        expected += key.hashCode() ^ val.hashCode();
598        assertEquals(expected, map.hashCode());
599    }
600
601    class MockClonable implements Cloneable{
602        public int i;
603
604        public MockClonable(int i) {
605            this.i = i;
606        }
607
608        @Override
609        protected Object clone() throws CloneNotSupportedException {
610            return new MockClonable(i);
611        }
612    }
613
614    /**
615     * Sets up the fixture, for example, open a network connection. This method
616     * is called before a test is executed.
617     */
618    protected void setUp() {
619        objArray = new Object[hmSize];
620        objArray2 = new Object[hmSize];
621        for (int i = 0; i < objArray.length; i++) {
622            objArray[i] = new Integer(i);
623            objArray2[i] = objArray[i].toString();
624        }
625
626        hm = new HashMap();
627        for (int i = 0; i < objArray.length; i++)
628            hm.put(objArray2[i], objArray[i]);
629        hm.put("test", null);
630        hm.put(null, "test");
631    }
632
633    /**
634     * Tears down the fixture, for example, close a network connection. This
635     * method is called after a test is executed.
636     */
637    protected void tearDown() {
638        hm = null;
639        objArray = null;
640        objArray2 = null;
641    }
642}
643