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