1/*
2 * Copyright (C) 2008 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
17package com.google.common.collect.testing;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
21import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
22
23import com.google.common.collect.Lists;
24import com.google.common.collect.Maps;
25import com.google.common.collect.testing.features.CollectionFeature;
26import com.google.common.collect.testing.features.CollectionSize;
27import com.google.common.collect.testing.features.Feature;
28import com.google.common.collect.testing.features.MapFeature;
29
30import junit.framework.Test;
31import junit.framework.TestCase;
32import junit.framework.TestSuite;
33
34import java.util.AbstractMap;
35import java.util.Collections;
36import java.util.HashMap;
37import java.util.List;
38import java.util.Map;
39import java.util.Set;
40
41/**
42 * Tests {@link MapTestSuiteBuilder} by using it against maps that have various
43 * negative behaviors.
44 *
45 * @author George van den Driessche
46 */
47public final class MapTestSuiteBuilderTests extends TestCase {
48  private MapTestSuiteBuilderTests() {}
49
50  public static Test suite() {
51    TestSuite suite = new TestSuite(
52        MapTestSuiteBuilderTests.class.getSimpleName());
53    suite.addTest(testsForHashMapNullKeysForbidden());
54    suite.addTest(testsForHashMapNullValuesForbidden());
55    return suite;
56  }
57
58  private abstract static class WrappedHashMapGenerator
59      extends TestStringMapGenerator {
60    @Override protected final Map<String, String> create(
61        Map.Entry<String, String>[] entries) {
62      HashMap<String, String> map = Maps.newHashMap();
63      for (Map.Entry<String, String> entry : entries) {
64        map.put(entry.getKey(), entry.getValue());
65      }
66      return wrap(map);
67    }
68
69    abstract Map<String, String> wrap(HashMap<String, String> map);
70  }
71
72  private static TestSuite wrappedHashMapTests(
73      WrappedHashMapGenerator generator, String name, Feature<?>... features) {
74    List<Feature<?>> featuresList = Lists.newArrayList(features);
75    Collections.addAll(featuresList,
76        MapFeature.GENERAL_PURPOSE,
77        CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
78        CollectionSize.ANY);
79    return MapTestSuiteBuilder.using(generator)
80        .named(name)
81        .withFeatures(featuresList)
82        .createTestSuite();
83  }
84
85  // TODO: consider being null-hostile in these tests
86
87  private static Test testsForHashMapNullKeysForbidden() {
88    return wrappedHashMapTests(new WrappedHashMapGenerator() {
89      @Override Map<String, String> wrap(final HashMap<String, String> map) {
90        if (map.containsKey(null)) {
91          throw new NullPointerException();
92        }
93        return new AbstractMap<String, String>() {
94          @Override public Set<Map.Entry<String, String>> entrySet() {
95            return map.entrySet();
96          }
97          @Override public String put(String key, String value) {
98            checkNotNull(key);
99            return map.put(key, value);
100          }
101        };
102      }
103    }, "HashMap w/out null keys", ALLOWS_NULL_VALUES);
104  }
105
106  private static Test testsForHashMapNullValuesForbidden() {
107    return wrappedHashMapTests(new WrappedHashMapGenerator() {
108      @Override Map<String, String> wrap(final HashMap<String, String> map) {
109        if (map.containsValue(null)) {
110          throw new NullPointerException();
111        }
112        return new AbstractMap<String, String>() {
113          @Override public Set<Map.Entry<String, String>> entrySet() {
114            return map.entrySet();
115          }
116          @Override public String put(String key, String value) {
117            checkNotNull(value);
118            return map.put(key, value);
119          }
120        };
121      }
122    }, "HashMap w/out null values", ALLOWS_NULL_KEYS);
123  }
124}
125