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