Home | History | Annotate | Download | only in testing
      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.testing;
     18 
     19 import com.google.common.collect.testing.features.CollectionFeature;
     20 import com.google.common.collect.testing.features.CollectionSize;
     21 import com.google.common.collect.testing.features.MapFeature;
     22 
     23 import junit.framework.Test;
     24 import junit.framework.TestSuite;
     25 
     26 import java.lang.reflect.Method;
     27 import java.util.Collection;
     28 import java.util.Collections;
     29 import java.util.Comparator;
     30 import java.util.EnumMap;
     31 import java.util.HashMap;
     32 import java.util.LinkedHashMap;
     33 import java.util.List;
     34 import java.util.Map;
     35 import java.util.Map.Entry;
     36 import java.util.TreeMap;
     37 import java.util.concurrent.ConcurrentHashMap;
     38 
     39 /**
     40  * Generates a test suite covering the {@link Map} implementations in the
     41  * {@link java.util} package. Can be subclassed to specify tests that should
     42  * be suppressed.
     43  *
     44  * @author Kevin Bourrillion
     45  */
     46 public class TestsForMapsInJavaUtil {
     47   public static Test suite() {
     48     return new TestsForMapsInJavaUtil().allTests();
     49   }
     50 
     51   public Test allTests() {
     52     TestSuite suite = new TestSuite("java.util Maps");
     53     suite.addTest(testsForEmptyMap());
     54     suite.addTest(testsForSingletonMap());
     55     suite.addTest(testsForHashMap());
     56     suite.addTest(testsForLinkedHashMap());
     57     suite.addTest(testsForTreeMap());
     58     suite.addTest(testsForEnumMap());
     59     suite.addTest(testsForConcurrentHashMap());
     60     return suite;
     61   }
     62 
     63   protected Collection<Method> suppressForEmptyMap() {
     64     return Collections.emptySet();
     65   }
     66   protected Collection<Method> suppressForSingletonMap() {
     67     return Collections.emptySet();
     68   }
     69   protected Collection<Method> suppressForHashMap() {
     70     return Collections.emptySet();
     71   }
     72   protected Collection<Method> suppressForLinkedHashMap() {
     73     return Collections.emptySet();
     74   }
     75   protected Collection<Method> suppressForTreeMap() {
     76     return Collections.emptySet();
     77   }
     78   protected Collection<Method> suppressForEnumMap() {
     79     return Collections.emptySet();
     80   }
     81   protected Collection<Method> suppressForConcurrentHashMap() {
     82     return Collections.emptySet();
     83   }
     84 
     85   public Test testsForEmptyMap() {
     86     return MapTestSuiteBuilder
     87         .using(new TestStringMapGenerator() {
     88             @Override protected Map<String, String> create(
     89                 Entry<String, String>[] entries) {
     90               return Collections.emptyMap();
     91             }
     92           })
     93         .named("emptyMap")
     94         .withFeatures(
     95             CollectionFeature.NONE,
     96             CollectionSize.ZERO)
     97         .suppressing(suppressForEmptyMap())
     98         .createTestSuite();
     99   }
    100 
    101   public Test testsForSingletonMap() {
    102     return MapTestSuiteBuilder
    103         .using(new TestStringMapGenerator() {
    104             @Override protected Map<String, String> create(
    105                 Entry<String, String>[] entries) {
    106               return Collections.singletonMap(
    107                   entries[0].getKey(), entries[0].getValue());
    108             }
    109           })
    110         .named("singletonMap")
    111         .withFeatures(
    112             MapFeature.ALLOWS_NULL_KEYS,
    113             MapFeature.ALLOWS_NULL_VALUES,
    114             CollectionSize.ONE)
    115         .suppressing(suppressForSingletonMap())
    116         .createTestSuite();
    117   }
    118 
    119   public Test testsForHashMap() {
    120     return MapTestSuiteBuilder
    121         .using(new TestStringMapGenerator() {
    122             @Override protected Map<String, String> create(
    123                 Entry<String, String>[] entries) {
    124               return toHashMap(entries);
    125             }
    126             @Override public Iterable<Entry<String, String>> order(
    127                 List<Entry<String, String>> insertionOrder) {
    128               /*
    129                * For convenience, make this test double as a test that no tester
    130                * calls order() on a container without the KNOWN_ORDER feature.
    131                */
    132               throw new UnsupportedOperationException();
    133             }
    134           })
    135         .named("HashMap")
    136         .withFeatures(
    137             MapFeature.GENERAL_PURPOSE,
    138             MapFeature.ALLOWS_NULL_KEYS,
    139             MapFeature.ALLOWS_NULL_VALUES,
    140             CollectionSize.ANY)
    141         .suppressing(suppressForHashMap())
    142         .createTestSuite();
    143   }
    144 
    145   public Test testsForLinkedHashMap() {
    146     return MapTestSuiteBuilder
    147         .using(new TestStringMapGenerator() {
    148             @Override protected Map<String, String> create(
    149                 Entry<String, String>[] entries) {
    150               return populate(new LinkedHashMap<String, String>(), entries);
    151             }
    152           })
    153         .named("LinkedHashMap")
    154         .withFeatures(
    155             MapFeature.GENERAL_PURPOSE,
    156             MapFeature.ALLOWS_NULL_KEYS,
    157             MapFeature.ALLOWS_NULL_VALUES,
    158             CollectionFeature.KNOWN_ORDER,
    159             CollectionSize.ANY)
    160         .suppressing(suppressForLinkedHashMap())
    161         .createTestSuite();
    162   }
    163 
    164   public Test testsForTreeMap() {
    165     return NavigableMapTestSuiteBuilder
    166         .using(new TestStringMapGenerator() {
    167             @Override protected Map<String, String> create(
    168                 Entry<String, String>[] entries) {
    169               return populate(new TreeMap<String, String>(
    170                   arbitraryNullFriendlyComparator()), entries);
    171             }
    172           })
    173         .named("TreeMap")
    174         .withFeatures(
    175             MapFeature.GENERAL_PURPOSE,
    176             MapFeature.ALLOWS_NULL_KEYS,
    177             MapFeature.ALLOWS_NULL_VALUES,
    178             CollectionFeature.KNOWN_ORDER,
    179             CollectionSize.ANY)
    180         .suppressing(suppressForTreeMap())
    181         .createTestSuite();
    182   }
    183 
    184   public Test testsForEnumMap() {
    185     return MapTestSuiteBuilder
    186         .using(new TestEnumMapGenerator() {
    187             @Override protected Map<AnEnum, String> create(
    188                 Entry<AnEnum, String>[] entries) {
    189               return populate(
    190                   new EnumMap<AnEnum, String>(AnEnum.class), entries);
    191             }
    192           })
    193         .named("EnumMap")
    194         .withFeatures(
    195             MapFeature.GENERAL_PURPOSE,
    196             MapFeature.ALLOWS_NULL_VALUES,
    197             MapFeature.RESTRICTS_KEYS,
    198             CollectionFeature.KNOWN_ORDER,
    199             CollectionSize.ANY)
    200         .suppressing(suppressForEnumMap())
    201         .createTestSuite();
    202   }
    203 
    204   public Test testsForConcurrentHashMap() {
    205     return MapTestSuiteBuilder
    206         .using(new TestStringMapGenerator() {
    207           @Override protected Map<String, String> create(
    208               Entry<String, String>[] entries) {
    209             return populate(new ConcurrentHashMap<String, String>(), entries);
    210           }
    211         })
    212         .named("ConcurrentHashMap")
    213         .withFeatures(
    214             MapFeature.GENERAL_PURPOSE,
    215             CollectionSize.ANY)
    216         .suppressing(suppressForConcurrentHashMap())
    217         .createTestSuite();
    218   }
    219 
    220   // TODO: IdentityHashMap, AbstractMap
    221 
    222   private static Map<String, String> toHashMap(
    223       Entry<String, String>[] entries) {
    224     return populate(new HashMap<String, String>(), entries);
    225   }
    226 
    227   // TODO: call conversion constructors or factory methods instead of using
    228   // populate() on an empty map
    229   private static <T> Map<T, String> populate(
    230       Map<T, String> map, Entry<T, String>[] entries) {
    231     for (Entry<T, String> entry : entries) {
    232       map.put(entry.getKey(), entry.getValue());
    233     }
    234     return map;
    235   }
    236 
    237   static <T> Comparator<T> arbitraryNullFriendlyComparator() {
    238     return new Comparator<T>() {
    239       @Override
    240       public int compare(T left, T right) {
    241         return String.valueOf(left).compareTo(String.valueOf(right));
    242       }
    243     };
    244   }
    245 }
    246