• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 import static org.easymock.EasyMock.anyObject;
19 import static org.easymock.EasyMock.createMock;
20 import static org.easymock.EasyMock.expect;
21 import static org.easymock.EasyMock.expectLastCall;
22 import static org.easymock.EasyMock.replay;
23 import static org.easymock.EasyMock.verify;
24 
25 import com.google.common.collect.testing.MapTestSuiteBuilder;
26 import com.google.common.collect.testing.TestStringMapGenerator;
27 import com.google.common.collect.testing.features.CollectionSize;
28 import com.google.common.collect.testing.features.MapFeature;
29 
30 import junit.framework.Test;
31 import junit.framework.TestSuite;
32 
33 import java.lang.reflect.InvocationTargetException;
34 import java.util.Collection;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.Map;
38 import java.util.Map.Entry;
39 import java.util.Set;
40 
41 /**
42  * Unit test for {@link ForwardingMap}.
43  *
44  * @author Hayward Chan
45  * @author Louis Wasserman
46  */
47 public class ForwardingMapTest extends ForwardingTestCase {
48   static class StandardImplForwardingMap<K, V> extends ForwardingMap<K, V> {
49     private final Map<K, V> backingMap;
50 
StandardImplForwardingMap(Map<K, V> backingMap)51     StandardImplForwardingMap(Map<K, V> backingMap) {
52       this.backingMap = backingMap;
53     }
54 
delegate()55     @Override protected Map<K, V> delegate() {
56       return backingMap;
57     }
58 
containsKey(Object key)59     @Override public boolean containsKey(Object key) {
60       return standardContainsKey(key);
61     }
62 
containsValue(Object value)63     @Override public boolean containsValue(Object value) {
64       return standardContainsValue(value);
65     }
66 
putAll(Map<? extends K, ? extends V> map)67     @Override public void putAll(Map<? extends K, ? extends V> map) {
68       standardPutAll(map);
69     }
70 
remove(Object object)71     @Override public V remove(Object object) {
72       return standardRemove(object);
73     }
74 
equals(Object object)75     @Override public boolean equals(Object object) {
76       return standardEquals(object);
77     }
78 
hashCode()79     @Override public int hashCode() {
80       return standardHashCode();
81     }
82 
keySet()83     @Override public Set<K> keySet() {
84       return new StandardKeySet();
85     }
86 
values()87     @Override public Collection<V> values() {
88       return new StandardValues();
89     }
90 
toString()91     @Override public String toString() {
92       return standardToString();
93     }
94 
entrySet()95     @Override public Set<Entry<K, V>> entrySet() {
96       return new StandardEntrySet() {
97         @Override
98         public Iterator<Entry<K, V>> iterator() {
99           return delegate()
100               .entrySet()
101               .iterator();
102         }
103       };
104     }
105 
clear()106     @Override public void clear() {
107       standardClear();
108     }
109 
isEmpty()110     @Override public boolean isEmpty() {
111       return standardIsEmpty();
112     }
113   }
114 
115   Map<String, Boolean> forward;
116 
117   public static Test suite() {
118     TestSuite suite = new TestSuite();
119 
120     suite.addTestSuite(ForwardingMapTest.class);
121     suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
122 
123       @Override protected Map<String, String> create(
124           Entry<String, String>[] entries) {
125         Map<String, String> map = Maps.newLinkedHashMap();
126         for (Entry<String, String> entry : entries) {
127           map.put(entry.getKey(), entry.getValue());
128         }
129         return new StandardImplForwardingMap<String, String>(map);
130       }
131 
132     }).named("ForwardingMap[LinkedHashMap] with standard implementations")
133         .withFeatures(CollectionSize.ANY, MapFeature.ALLOWS_NULL_VALUES,
134             MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE)
135         .createTestSuite());
136     suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
137 
138       @Override protected Map<String, String> create(
139           Entry<String, String>[] entries) {
140         ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
141         for (Entry<String, String> entry : entries) {
142           builder.put(entry.getKey(), entry.getValue());
143         }
144         return new StandardImplForwardingMap<String, String>(builder.build());
145       }
146 
147     }).named("ForwardingMap[ImmutableMap] with standard implementations")
148         .withFeatures(
149             CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION,
150             MapFeature.ALLOWS_NULL_QUERIES)
151         .createTestSuite());
152 
153     return suite;
154   }
155 
156   @Override public void setUp() throws Exception {
157     super.setUp();
158     /*
159      * Class parameters must be raw, so we can't create a proxy with generic
160      * type arguments. The created proxy only records calls and returns null, so
161      * the type is irrelevant at runtime.
162      */
163     @SuppressWarnings("unchecked")
164     final Map<String, Boolean> map = createProxyInstance(Map.class);
165     forward = new ForwardingMap<String, Boolean>() {
166       @Override protected Map<String, Boolean> delegate() {
167         return map;
168       }
169     };
170   }
171 
172   public void testSize() {
173     forward().size();
174     assertEquals("[size]", getCalls());
175   }
176 
177   public void testIsEmpty() {
178     forward().isEmpty();
179     assertEquals("[isEmpty]", getCalls());
180   }
181 
182   public void testRemove() {
183     forward().remove(null);
184     assertEquals("[remove(Object)]", getCalls());
185   }
186 
187   public void testClear() {
188     forward().clear();
189     assertEquals("[clear]", getCalls());
190   }
191 
192   public void testContainsKey() {
193     forward().containsKey("asdf");
194     assertEquals("[containsKey(Object)]", getCalls());
195   }
196 
197   public void testContainsValue() {
198     forward().containsValue(false);
199     assertEquals("[containsValue(Object)]", getCalls());
200   }
201 
202   public void testGet_Object() {
203     forward().get("asdf");
204     assertEquals("[get(Object)]", getCalls());
205   }
206 
207   public void testPut_Key_Value() {
208     forward().put("key", false);
209     assertEquals("[put(Object,Object)]", getCalls());
210   }
211 
212   public void testPutAll_Map() {
213     forward().putAll(new HashMap<String, Boolean>());
214     assertEquals("[putAll(Map)]", getCalls());
215   }
216 
217   public void testKeySet() {
218     forward().keySet();
219     assertEquals("[keySet]", getCalls());
220   }
221 
222   public void testValues() {
223     forward().values();
224     assertEquals("[values]", getCalls());
225   }
226 
227   public void testEntrySet() {
228     forward().entrySet();
229     assertEquals("[entrySet]", getCalls());
230   }
231 
232   public void testToString() {
233     forward().toString();
234     assertEquals("[toString]", getCalls());
235   }
236 
237   public void testEquals_Object() {
238     forward().equals("asdf");
239     assertEquals("[equals(Object)]", getCalls());
240   }
241 
242   public void testHashCode() {
243     forward().hashCode();
244     assertEquals("[hashCode]", getCalls());
245   }
246 
247   public void testStandardEntrySet() throws InvocationTargetException {
248     @SuppressWarnings("unchecked")
249     final Map<String, Boolean> map = createMock(Map.class);
250     @SuppressWarnings("unchecked")
251     final Set<Map.Entry<String, Boolean>> entrySet = createMock(Set.class);
252     expect(map.containsKey(anyObject())).andReturn(false).anyTimes();
253     expect(map.get(anyObject())).andReturn(null).anyTimes();
254     expect(map.isEmpty()).andReturn(true).anyTimes();
255     expect(map.remove(anyObject())).andReturn(null).anyTimes();
256     expect(map.size()).andReturn(0).anyTimes();
257     expect(entrySet.iterator())
258         .andReturn(Iterators.<Entry<String, Boolean>>emptyIterator())
259         .anyTimes();
260     map.clear();
261     expectLastCall().anyTimes();
262 
263     replay(map, entrySet);
264 
265     Map<String, Boolean> forward = new ForwardingMap<String, Boolean>() {
266       @Override protected Map<String, Boolean> delegate() {
267         return map;
268       }
269 
270       @Override public Set<Entry<String, Boolean>> entrySet() {
271         return new StandardEntrySet() {
272           @Override
273           public Iterator<Entry<String, Boolean>> iterator() {
274             return entrySet.iterator();
275           }
276         };
277       }
278     };
279     callAllPublicMethods(Set.class, forward.entrySet());
280 
281     verify(map, entrySet);
282   }
283 
284   public void testStandardKeySet() throws InvocationTargetException {
285     @SuppressWarnings("unchecked")
286     Set<Entry<String, Boolean>> entrySet = createMock(Set.class);
287     expect(entrySet.iterator()).andReturn(
288         Iterators.<Entry<String, Boolean>>emptyIterator()).anyTimes();
289 
290     @SuppressWarnings("unchecked")
291     final Map<String, Boolean> map = createMock(Map.class);
292     expect(map.containsKey(anyObject())).andReturn(false).anyTimes();
293     expect(map.isEmpty()).andReturn(true).anyTimes();
294     expect(map.remove(anyObject())).andReturn(null).anyTimes();
295     expect(map.size()).andReturn(0).anyTimes();
296     expect(map.entrySet()).andReturn(entrySet).anyTimes();
297     map.clear();
298     expectLastCall().anyTimes();
299 
300     replay(entrySet, map);
301 
302     Map<String, Boolean> forward = new ForwardingMap<String, Boolean>() {
303       @Override protected Map<String, Boolean> delegate() {
304         return map;
305       }
306 
307       @Override public Set<String> keySet() {
308         return new StandardKeySet();
309       }
310     };
311     callAllPublicMethods(Set.class, forward.keySet());
312 
313     verify(entrySet, map);
314   }
315 
316   public void testStandardValues() throws InvocationTargetException {
317     @SuppressWarnings("unchecked")
318     Set<Entry<String, Boolean>> entrySet = createMock(Set.class);
319     expect(entrySet.iterator()).andReturn(
320         Iterators.<Entry<String, Boolean>>emptyIterator()).anyTimes();
321 
322     @SuppressWarnings("unchecked")
323     final Map<String, Boolean> map = createMock(Map.class);
324     expect(map.containsValue(anyObject())).andReturn(false).anyTimes();
325     expect(map.isEmpty()).andReturn(true).anyTimes();
326     expect(map.size()).andReturn(0).anyTimes();
327     expect(map.entrySet()).andReturn(entrySet).anyTimes();
328     map.clear();
329     expectLastCall().anyTimes();
330 
331     replay(entrySet, map);
332 
333     Map<String, Boolean> forward = new ForwardingMap<String, Boolean>() {
334       @Override protected Map<String, Boolean> delegate() {
335         return map;
336       }
337 
338       @Override public Collection<Boolean> values() {
339         return new StandardValues();
340       }
341     };
342     callAllPublicMethods(Collection.class, forward.values());
343 
344     verify(entrySet, map);
345   }
346 
347   Map<String, Boolean> forward() {
348     return forward;
349   }
350 }
351