Home | History | Annotate | Download | only in collect
      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 
     51     StandardImplForwardingMap(Map<K, V> backingMap) {
     52       this.backingMap = backingMap;
     53     }
     54 
     55     @Override protected Map<K, V> delegate() {
     56       return backingMap;
     57     }
     58 
     59     @Override public boolean containsKey(Object key) {
     60       return standardContainsKey(key);
     61     }
     62 
     63     @Override public boolean containsValue(Object value) {
     64       return standardContainsValue(value);
     65     }
     66 
     67     @Override public void putAll(Map<? extends K, ? extends V> map) {
     68       standardPutAll(map);
     69     }
     70 
     71     @Override public V remove(Object object) {
     72       return standardRemove(object);
     73     }
     74 
     75     @Override public boolean equals(Object object) {
     76       return standardEquals(object);
     77     }
     78 
     79     @Override public int hashCode() {
     80       return standardHashCode();
     81     }
     82 
     83     @Override public Set<K> keySet() {
     84       return new StandardKeySet();
     85     }
     86 
     87     @Override public Collection<V> values() {
     88       return new StandardValues();
     89     }
     90 
     91     @Override public String toString() {
     92       return standardToString();
     93     }
     94 
     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 
    106     @Override public void clear() {
    107       standardClear();
    108     }
    109 
    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