View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.trinidadbuild.test;
20  
21  import java.util.Collection;
22  import java.util.HashMap;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import junit.framework.TestCase;
29  
30  /**
31   * Base class for Map test cases.
32   */
33  abstract public class MapTestCase extends TestCase
34  {
35    public MapTestCase(String testName)
36    {
37      super(testName);
38    }
39  
40    public void testInitialState()
41    {
42      Map<String, Object> map = createMap();
43      assertEquals(0, map.size());
44      assertTrue(map.isEmpty());
45      assertTrue(map.entrySet().isEmpty());
46      assertTrue(map.keySet().isEmpty());
47      assertTrue(map.values().isEmpty());
48      assertTrue(!map.entrySet().iterator().hasNext());
49    }
50  
51    public void testPut()
52    {
53      Map<String, Object> map = createMap();
54      assertNull(map.put("foo", "bar"));
55      assertEquals(1, map.size());
56      assertEquals("bar", map.get("foo"));
57      assertTrue(map.containsKey("foo"));
58      assertTrue(map.containsValue("bar"));
59  
60      assertTrue(map.keySet().contains("foo"));
61      assertTrue(map.values().contains("bar"));
62  
63      assertEquals("bar", map.put("foo", "baz"));
64      assertEquals(1, map.size());
65      assertEquals("baz", map.get("foo"));
66  
67      assertTrue(map.containsKey("foo"));
68      assertTrue(map.containsValue("baz"));
69      assertTrue(!map.containsValue("bar"));
70    }
71  
72    public void testPutAll()
73    {
74      Map<String, Object> map = createMap();
75      HashMap<String, Object> hashMap = new HashMap<String, Object>();
76      _putTwo(hashMap);
77      
78      map.putAll(hashMap);
79      assertEquals(2, map.size());
80      assertTrue(map.containsKey("first"));
81      assertEquals(ONE, map.get("first"));
82      assertTrue(map.containsKey("second"));
83      assertEquals(TWO, map.get("second"));
84    }
85  
86  
87    public void testPutNull()
88    {
89  
90      Map<String, Object> map = createMap();
91  
92      // Test putting a null value
93      try
94      {
95        map.put("foo", null);
96      }
97      catch (NullPointerException e)
98      {
99        if (supportsNullValues())
100         fail();
101     }
102 
103     if (supportsNullValues())
104     {
105       if (isNullRemove())
106       {
107         assertEquals(0, map.size());
108         assertTrue(!map.containsKey("foo"));
109         assertTrue(!map.containsValue(null));
110       }
111       else
112       {
113         assertEquals(1, map.size());
114         assertTrue(map.containsKey("foo"));
115         assertTrue(map.containsValue(null));
116       }
117     }
118 
119     // Test putting a null key
120     map = createMap();
121     try
122     {
123       map.put(null, "foo");
124     }
125     catch (NullPointerException e)
126     {
127       if (supportsNullKeys())
128         fail();
129     }
130     
131     if (supportsNullKeys())
132     {
133       assertEquals(1, map.size());
134       assertTrue(map.containsKey(null));
135       assertTrue(map.containsValue("foo"));
136     }
137   }
138 
139   public void testEntrySet()
140   {
141     Map<String, Object> map = createMap();
142     _putTwo(map);
143 
144     Set<Map.Entry<String, Object>> entries = map.entrySet();
145     assertEquals(2, entries.size());
146     _assertIteratorSize(entries.iterator(), 2);
147 
148     Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
149     while (iterator.hasNext())
150     {
151       Map.Entry<String, Object> entry = iterator.next();
152       if (entry.getKey().equals("second"))
153       {
154         entry.setValue(THREE);
155       }
156       else if (entry.getKey().equals("first"))
157       {
158         try
159         {
160           iterator.remove();
161         }
162         catch (UnsupportedOperationException e)
163         {
164           if (supportsIteratorRemove())
165             fail();
166         }
167       }
168       else
169       {
170         fail();
171       }
172     }
173 
174     if (supportsIteratorRemove())
175     {
176       assertTrue(!map.containsKey("first"));
177     }
178 
179     assertEquals(THREE, map.get("second"));
180 
181     map.clear();
182     assertTrue(map.isEmpty());
183     assertTrue(entries.isEmpty());
184 
185     _putTwo(map);
186 
187     _assertIteratorSize(entries.iterator(), 2);
188     
189     assertTrue(!entries.isEmpty());
190     entries.clear();
191 
192     _assertIteratorSize(entries.iterator(), 0);
193     assertTrue(map.isEmpty());
194     assertTrue(entries.isEmpty());
195   }
196 
197   public void testEquals()
198   {
199     Map<String, Object> map = createMap();
200     _putTwo(map);
201     assertEquals(map, map);
202 
203     Map<String, Object> secondMap = createMap();
204     assertTrue(!secondMap.equals(map));
205     assertTrue(!map.equals(secondMap));
206     assertTrue(!map.equals(null));
207     
208     _putTwo(secondMap);
209     assertEquals(map, secondMap);
210     
211     HashMap<String, Object> hashMap = new HashMap<String, Object>();
212     _putTwo(hashMap);
213     assertEquals(hashMap, map);
214     assertEquals(map, hashMap);
215   }
216 
217   public void testRemove()
218   {
219     Map<String, Object> map = createMap();
220     _putTwo(map);
221     assertNull(map.remove("NOTTHERE"));
222     assertEquals(TWO, map.remove("second"));
223     assertEquals(1, map.size());
224 
225     assertTrue(!map.containsKey("second"));
226     assertNull(map.remove("second"));
227     assertEquals(1, map.size());
228 
229     assertEquals(ONE, map.remove("first"));
230     assertTrue(map.isEmpty());
231     assertNull(map.remove("first"));
232   }
233 
234   public void testKeySet()
235   {
236     Map<String, Object> map = createMap();
237     _putTwo(map);
238     Set<String> keys = map.keySet();
239     assertEquals(2, keys.size());
240     assertTrue(keys.contains("first"));
241     assertTrue(keys.contains("second"));
242     
243     HashSet<String> hashSet = new HashSet<String>();
244     hashSet.add("first");
245     hashSet.add("second");
246     
247     assertEquals(keys, hashSet);
248     assertEquals(hashSet, keys);
249 
250     hashSet.add("third");
251     assertTrue(!keys.equals(hashSet));
252     assertTrue(!hashSet.equals(keys));
253 
254     
255     keys.clear();
256     assertTrue(keys.isEmpty());
257     assertTrue(map.isEmpty());
258   }
259   
260   public void testValues()
261   {
262     Map<String, Object> map = createMap();
263     _putTwo(map);
264     Collection<Object> values = map.values();
265     assertEquals(2, values.size());
266     assertTrue(values.contains(ONE));
267     assertTrue(values.contains(TWO));
268 
269     // Can't really assert that this values collection is equal to 
270     // any other, because we can't rely on the order of the collection
271     
272     values.clear();
273     assertTrue(values.isEmpty());
274     assertTrue(map.isEmpty());
275   }
276 
277 
278   public void testPutAndGetWithClashingHashCode()
279   {
280     Map<LameKey, Object> cache = createMapWithLameKey();
281 
282     if (cache == null)
283       return;
284 
285     cache.put(AAA, ONE);
286     cache.put(ABB, TWO);
287     cache.put(ACC, THREE);
288     assertEquals(ONE, cache.get(AAA));
289     assertEquals(TWO, cache.get(ABB));
290     assertEquals(THREE, cache.get(ACC));
291 
292     cache = createMapWithLameKey();
293     cache.put(AAA, ONE);
294     cache.put(BAA, TWO);
295     cache.put(BBB, THREE);
296     assertEquals(ONE, cache.get(AAA));
297     assertEquals(TWO, cache.get(BAA));
298     assertEquals(THREE, cache.get(BBB));
299 
300     cache = createMapWithLameKey();
301     cache.put(BAA, ONE);
302     cache.put(AAA, TWO);
303     cache.put(BBB, THREE);
304     assertEquals(ONE, cache.get(BAA));
305     assertEquals(TWO, cache.get(AAA));
306     assertEquals(THREE, cache.get(BBB));
307   }
308 
309   public void testRemoveWithClashingHashCode()
310   {
311     Map<LameKey, Object> cache = createMapWithLameKey();
312 
313     if (cache == null)
314       return;
315 
316     cache.put(AAA, ONE);
317     cache.put(ABB, TWO);
318     cache.put(ACC, THREE);
319     cache.remove(AAA);
320     assertEquals(2, cache.size());
321     assertContains(cache, ABB, ACC);
322 
323     cache = createMapWithLameKey();
324 
325     cache.put(AAA, ONE);
326     cache.put(BAA, TWO);
327     cache.put(BBB, THREE);
328     cache.remove(BAA);
329     assertEquals(2, cache.size());
330     assertContains(cache, AAA, BBB);
331 
332     cache.put(BAA, ONE);
333     cache.put(AAA, TWO);
334     cache.put(BBB, THREE);
335     cache.remove(BBB);
336     assertEquals(2, cache.size());
337     assertContains(cache, AAA, BAA);
338   }
339 
340   protected void assertContains(Map<String, Object> cache, String... keys)
341   {
342     for (String key : keys)
343       assertTrue("Object with key '" + key + "' expected to be available in the cache.",
344                  cache.containsKey(key));
345   }
346 
347   protected void assertContains(Map<LameKey, Object> cache, LameKey... keys)
348   {
349     for (LameKey key : keys)
350       assertTrue("Object with key '" + key + "' expected to be available in the cache.",
351                  cache.containsKey(key));
352   }
353 
354   protected boolean isNullRemove()
355   {
356     return false;
357   }
358 
359   protected boolean supportsNullValues()
360   {
361     return true;
362   }
363 
364   protected boolean supportsNullKeys()
365   {
366     return true;
367   }
368 
369   protected boolean supportsIteratorRemove()
370   {
371     return true;
372   }
373 
374   /**
375    * Key with lame, but stable hashing.  The key uses the first code point of the String
376    * as its hashCode
377    */
378   protected static class LameKey
379   {
380     public LameKey(String key)
381     {
382       _key = key;
383       _hashCode = key.codePointAt(0);
384     }
385 
386     @Override
387     public int hashCode()
388     {
389       return _hashCode;
390     }
391 
392     @Override
393     public boolean equals(Object o)
394     {
395       if (!(o instanceof LameKey))
396         return false;
397 
398       return _key.equals(((LameKey)o)._key);
399     }
400 
401     @Override
402     public String toString()
403     {
404       StringBuilder sb = new StringBuilder();
405 
406       sb.append('(');
407       sb.append(_key.charAt(0));
408       sb.append(')');
409       sb.append(_key.substring(1));
410 
411       return sb.toString();
412     }
413 
414     private final String _key;
415     private final int _hashCode;
416   }
417 
418   private void _assertIteratorSize(Iterator<?> iterator, int count)
419   {
420     for (int i = 0; i < count; i++)
421     {
422       assertTrue(iterator.hasNext());
423       iterator.next();
424     }
425 
426     assertTrue(!iterator.hasNext());
427   }
428 
429   private void _putTwo(Map<String, Object> map)
430   {
431     map.put("first", ONE);
432     map.put("second", TWO);
433   }
434 
435   /**
436    * @return map with minimum size 3
437    */
438   abstract protected Map<String, Object> createMap();
439 
440   /**
441    * @return map with minimum size 3, or
442    *         null when not applicable
443    */
444   abstract protected Map<LameKey, Object> createMapWithLameKey();
445 
446   protected static final Object ONE   = new Integer(1);
447   protected static final Object TWO   = new Integer(2);
448   protected static final Object THREE = new Integer(3);
449   protected static final Object FOUR  = new Integer(4);
450 
451   protected static final LameKey AAA = new LameKey("aaa");
452   protected static final LameKey ABB = new LameKey("abb");
453   protected static final LameKey ACC = new LameKey("acc");
454   protected static final LameKey ADD = new LameKey("add");
455   protected static final LameKey BAA = new LameKey("baa");
456   protected static final LameKey BBB = new LameKey("bbb");
457   protected static final LameKey BCC = new LameKey("bcc");
458   protected static final LameKey BDD = new LameKey("bdd");
459   protected static final LameKey CAA = new LameKey("caa");
460   protected static final LameKey CBB = new LameKey("cbb");
461   protected static final LameKey CCC = new LameKey("ccc");
462   protected static final LameKey CDD = new LameKey("cdd");
463   protected static final LameKey DAA = new LameKey("daa");
464   protected static final LameKey DBB = new LameKey("dbb");
465   protected static final LameKey DCC = new LameKey("dcc");
466   protected static final LameKey DDD = new LameKey("ddd");
467 }