Home | History | Annotate | Download | only in util
      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 
     18 package org.apache.harmony.tests.java.util;
     19 
     20 import java.util.AbstractMap;
     21 import java.util.AbstractSet;
     22 import java.util.Collection;
     23 import java.util.Collections;
     24 import java.util.Comparator;
     25 import java.util.HashMap;
     26 import java.util.HashSet;
     27 import java.util.Hashtable;
     28 import java.util.IdentityHashMap;
     29 import java.util.Iterator;
     30 import java.util.LinkedHashMap;
     31 import java.util.Map;
     32 import java.util.Set;
     33 import java.util.TreeMap;
     34 import java.util.Vector;
     35 import java.util.WeakHashMap;
     36 
     37 public class AbstractMapTest extends junit.framework.TestCase {
     38 
     39     static final String specialKey = "specialKey".intern();
     40 
     41     static final String specialValue = "specialValue".intern();
     42 
     43     // The impl of MyMap is not realistic, but serves to create a type
     44     // that uses the default remove behavior.
     45     class MyMap extends AbstractMap {
     46         final Set mySet = new HashSet(1);
     47 
     48         MyMap() {
     49             mySet.add(new Map.Entry() {
     50                 public Object getKey() {
     51                     return specialKey;
     52                 }
     53 
     54                 public Object getValue() {
     55                     return specialValue;
     56                 }
     57 
     58                 public Object setValue(Object object) {
     59                     return null;
     60                 }
     61             });
     62         }
     63 
     64         public Object put(Object key, Object value) {
     65             return null;
     66         }
     67 
     68         public Set entrySet() {
     69             return mySet;
     70         }
     71     }
     72 
     73     /**
     74      * java.util.AbstractMap#keySet()
     75      */
     76     public void test_keySet() {
     77         AbstractMap map1 = new HashMap(0);
     78         assertSame("HashMap(0)", map1.keySet(), map1.keySet());
     79 
     80         AbstractMap map2 = new HashMap(10);
     81         assertSame("HashMap(10)", map2.keySet(), map2.keySet());
     82 
     83         Map map3 = Collections.EMPTY_MAP;
     84         assertSame("EMPTY_MAP", map3.keySet(), map3.keySet());
     85 
     86         AbstractMap map4 = new IdentityHashMap(1);
     87         assertSame("IdentityHashMap", map4.keySet(), map4.keySet());
     88 
     89         AbstractMap map5 = new LinkedHashMap(122);
     90         assertSame("LinkedHashMap", map5.keySet(), map5.keySet());
     91 
     92         AbstractMap map6 = new TreeMap();
     93         assertSame("TreeMap", map6.keySet(), map6.keySet());
     94 
     95         AbstractMap map7 = new WeakHashMap();
     96         assertSame("WeakHashMap", map7.keySet(), map7.keySet());
     97     }
     98 
     99     /**
    100      * java.util.AbstractMap#remove(java.lang.Object)
    101      */
    102     public void test_removeLjava_lang_Object() {
    103         Object key = new Object();
    104         Object value = new Object();
    105 
    106         AbstractMap map1 = new HashMap(0);
    107         map1.put("key", value);
    108         assertSame("HashMap(0)", map1.remove("key"), value);
    109 
    110         AbstractMap map4 = new IdentityHashMap(1);
    111         map4.put(key, value);
    112         assertSame("IdentityHashMap", map4.remove(key), value);
    113 
    114         AbstractMap map5 = new LinkedHashMap(122);
    115         map5.put(key, value);
    116         assertSame("LinkedHashMap", map5.remove(key), value);
    117 
    118         AbstractMap map6 = new TreeMap(new Comparator() {
    119             // Bogus comparator
    120             public int compare(Object object1, Object object2) {
    121                 return 0;
    122             }
    123         });
    124         map6.put(key, value);
    125         assertSame("TreeMap", map6.remove(key), value);
    126 
    127         AbstractMap map7 = new WeakHashMap();
    128         map7.put(key, value);
    129         assertSame("WeakHashMap", map7.remove(key), value);
    130 
    131         AbstractMap aSpecialMap = new MyMap();
    132         aSpecialMap.put(specialKey, specialValue);
    133         Object valueOut = aSpecialMap.remove(specialKey);
    134         assertSame("MyMap", valueOut, specialValue);
    135     }
    136 
    137     /**
    138      * java.util.AbstractMap#clear()
    139      */
    140     public void test_clear() {
    141         // normal clear()
    142         AbstractMap map = new HashMap();
    143         map.put(1, 1);
    144         map.clear();
    145         assertTrue(map.isEmpty());
    146 
    147         // Special entrySet return a Set with no clear method.
    148         AbstractMap myMap = new MocAbstractMap();
    149         try {
    150             myMap.clear();
    151             fail("Should throw UnsupportedOprationException");
    152         } catch (UnsupportedOperationException e) {
    153             // expected
    154         }
    155     }
    156 
    157     class MocAbstractMap<K, V> extends AbstractMap {
    158 
    159         public Set entrySet() {
    160             Set set = new MySet();
    161             return set;
    162         }
    163 
    164         class MySet extends HashSet {
    165             public void clear() {
    166                 throw new UnsupportedOperationException();
    167             }
    168         }
    169     }
    170 
    171     /**
    172      * java.util.AbstractMap#containsKey(Object)
    173      */
    174     public void test_containsKey() {
    175         AbstractMap map = new AMT();
    176 
    177         assertFalse(map.containsKey("k"));
    178         assertFalse(map.containsKey(null));
    179 
    180         map.put("k", "v");
    181         map.put("key", null);
    182         map.put(null, "value");
    183         map.put(null, null);
    184 
    185         assertTrue(map.containsKey("k"));
    186         assertTrue(map.containsKey("key"));
    187         assertTrue(map.containsKey(null));
    188     }
    189 
    190     /**
    191      * java.util.AbstractMap#containsValue(Object)
    192      */
    193     public void test_containValue() {
    194         AbstractMap map = new AMT();
    195 
    196         assertFalse(map.containsValue("v"));
    197         assertFalse(map.containsValue(null));
    198 
    199         map.put("k", "v");
    200         map.put("key", null);
    201         map.put(null, "value");
    202 
    203         assertTrue(map.containsValue("v"));
    204         assertTrue(map.containsValue("value"));
    205         assertTrue(map.containsValue(null));
    206     }
    207 
    208     /**
    209      * java.util.AbstractMap#get(Object)
    210      */
    211     public void test_get() {
    212         AbstractMap map = new AMT();
    213         assertNull(map.get("key"));
    214         assertNull(map.get(null));
    215 
    216         map.put("k", "v");
    217         map.put("key", null);
    218         map.put(null, "value");
    219 
    220         assertEquals("v", map.get("k"));
    221         assertNull(map.get("key"));
    222         assertEquals("value", map.get(null));
    223     }
    224 
    225     /**
    226      * java.util.AbstractMap#values()
    227      */
    228     public void test_values() {
    229         AbstractMap map1 = new HashMap(0);
    230         assertSame("HashMap(0)", map1.values(), map1.values());
    231 
    232         AbstractMap map2 = new HashMap(10);
    233         assertSame("HashMap(10)", map2.values(), map2.values());
    234 
    235         Map map3 = Collections.EMPTY_MAP;
    236         assertSame("EMPTY_MAP", map3.values(), map3.values());
    237 
    238         AbstractMap map4 = new IdentityHashMap(1);
    239         assertSame("IdentityHashMap", map4.values(), map4.values());
    240 
    241         AbstractMap map5 = new LinkedHashMap(122);
    242         assertSame("IdentityHashMap", map5.values(), map5.values());
    243 
    244         AbstractMap map6 = new TreeMap();
    245         assertSame("TreeMap", map6.values(), map6.values());
    246 
    247         AbstractMap map7 = new WeakHashMap();
    248         assertSame("WeakHashMap", map7.values(), map7.values());
    249     }
    250 
    251     /**
    252      * java.util.AbstractMap#clone()
    253      */
    254     public void test_clone() {
    255         class MyMap extends AbstractMap implements Cloneable {
    256             private Map map = new HashMap();
    257 
    258             public Set entrySet() {
    259                 return map.entrySet();
    260             }
    261 
    262             public Object put(Object key, Object value) {
    263                 return map.put(key, value);
    264             }
    265 
    266             public Map getMap() {
    267                 return map;
    268             }
    269 
    270             public Object clone() {
    271                 try {
    272                     return super.clone();
    273                 } catch (CloneNotSupportedException e) {
    274                     fail("Clone must be supported");
    275                     return null;
    276                 }
    277             }
    278         }
    279         MyMap map = new MyMap();
    280         map.put("one", "1");
    281         Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
    282         assertTrue("entry not added", entry.getKey() == "one"
    283                 && entry.getValue() == "1");
    284         MyMap mapClone = (MyMap) map.clone();
    285         assertTrue("clone not shallow", map.getMap() == mapClone.getMap());
    286     }
    287 
    288     public class AMT extends AbstractMap {
    289 
    290         // Very crude AbstractMap implementation
    291         Vector values = new Vector();
    292         Vector keys = new Vector();
    293 
    294         public Set entrySet() {
    295             return new AbstractSet() {
    296                 public Iterator iterator() {
    297                     return new Iterator() {
    298                         int index = 0;
    299 
    300                         public boolean hasNext() {
    301                             return index < values.size();
    302                         }
    303 
    304                         public Object next() {
    305                             if (index < values.size()) {
    306                                 Map.Entry me = new Map.Entry() {
    307                                     Object v = values.elementAt(index);
    308 
    309                                     Object k = keys.elementAt(index);
    310 
    311                                     public Object getKey() {
    312                                         return k;
    313                                     }
    314 
    315                                     public Object getValue() {
    316                                         return v;
    317                                     }
    318 
    319                                     public Object setValue(Object value) {
    320                                         return null;
    321                                     }
    322                                 };
    323                                 index++;
    324                                 return me;
    325                             }
    326                             return null;
    327                         }
    328 
    329                         public void remove() {
    330                         }
    331                     };
    332                 }
    333 
    334                 public int size() {
    335                     return values.size();
    336                 }
    337             };
    338         }
    339 
    340         public Object put(Object k, Object v) {
    341             keys.add(k);
    342             values.add(v);
    343             return v;
    344         }
    345     }
    346 
    347     /**
    348      * {@link java.util.AbstractMap#putAll(Map)}
    349      */
    350     public void test_putAllLMap() {
    351         Hashtable ht = new Hashtable();
    352         AMT amt = new AMT();
    353         ht.put("this", "that");
    354         amt.putAll(ht);
    355 
    356         assertEquals("Should be equal", amt, ht);
    357     }
    358 
    359     public void testEqualsWithNullValues() {
    360         Map<String, String> a = new HashMap<String, String>();
    361         a.put("a", null);
    362         a.put("b", null);
    363 
    364         Map<String, String> b = new HashMap<String, String>();
    365         a.put("c", "cat");
    366         a.put("d", "dog");
    367 
    368         assertFalse(a.equals(b));
    369         assertFalse(b.equals(a));
    370     }
    371 
    372     public void testNullsOnViews() {
    373         Map<String, String> nullHostile = new Hashtable<String, String>();
    374 
    375         nullHostile.put("a", "apple");
    376         testNullsOnView(nullHostile.entrySet());
    377 
    378         nullHostile.put("a", "apple");
    379         testNullsOnView(nullHostile.keySet());
    380 
    381         nullHostile.put("a", "apple");
    382         testNullsOnView(nullHostile.values());
    383     }
    384 
    385     private void testNullsOnView(Collection<?> view) {
    386         try {
    387             assertFalse(view.contains(null));
    388         } catch (NullPointerException optional) {
    389         }
    390 
    391         try {
    392             assertFalse(view.remove(null));
    393         } catch (NullPointerException optional) {
    394         }
    395 
    396         Set<Object> setOfNull = Collections.singleton(null);
    397         assertFalse(view.equals(setOfNull));
    398 
    399         try {
    400             assertFalse(view.removeAll(setOfNull));
    401         } catch (NullPointerException optional) {
    402         }
    403 
    404         try {
    405             assertTrue(view.retainAll(setOfNull)); // destructive
    406         } catch (NullPointerException optional) {
    407         }
    408     }
    409 
    410     protected void setUp() {
    411     }
    412 
    413     protected void tearDown() {
    414     }
    415 }
    416