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 17 package com.google.common.collect.testing; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS; 21 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES; 22 23 import com.google.common.collect.Lists; 24 import com.google.common.collect.Maps; 25 import com.google.common.collect.testing.features.CollectionFeature; 26 import com.google.common.collect.testing.features.CollectionSize; 27 import com.google.common.collect.testing.features.Feature; 28 import com.google.common.collect.testing.features.MapFeature; 29 import java.util.AbstractMap; 30 import java.util.AbstractSet; 31 import java.util.Collection; 32 import java.util.Collections; 33 import java.util.HashMap; 34 import java.util.Iterator; 35 import java.util.List; 36 import java.util.Map; 37 import java.util.Map.Entry; 38 import java.util.Set; 39 import junit.framework.Test; 40 import junit.framework.TestCase; 41 import junit.framework.TestSuite; 42 43 /** 44 * Tests {@link MapTestSuiteBuilder} by using it against maps that have various negative behaviors. 45 * 46 * @author George van den Driessche 47 */ 48 public final class MapTestSuiteBuilderTests extends TestCase { MapTestSuiteBuilderTests()49 private MapTestSuiteBuilderTests() {} 50 suite()51 public static Test suite() { 52 TestSuite suite = new TestSuite(MapTestSuiteBuilderTests.class.getSimpleName()); 53 suite.addTest(testsForHashMapNullKeysForbidden()); 54 suite.addTest(testsForHashMapNullValuesForbidden()); 55 return suite; 56 } 57 58 private abstract static class WrappedHashMapGenerator extends TestStringMapGenerator { 59 @Override create(Entry<String, String>[] entries)60 protected final Map<String, String> create(Entry<String, String>[] entries) { 61 HashMap<String, String> map = Maps.newHashMap(); 62 for (Entry<String, String> entry : entries) { 63 map.put(entry.getKey(), entry.getValue()); 64 } 65 return wrap(map); 66 } 67 wrap(HashMap<String, String> map)68 abstract Map<String, String> wrap(HashMap<String, String> map); 69 } 70 wrappedHashMapTests( WrappedHashMapGenerator generator, String name, Feature<?>... features)71 private static TestSuite wrappedHashMapTests( 72 WrappedHashMapGenerator generator, String name, Feature<?>... features) { 73 List<Feature<?>> featuresList = Lists.newArrayList(features); 74 Collections.addAll( 75 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 testsForHashMapNullKeysForbidden()87 private static Test testsForHashMapNullKeysForbidden() { 88 return wrappedHashMapTests( 89 new WrappedHashMapGenerator() { 90 @Override 91 Map<String, String> wrap(final HashMap<String, String> map) { 92 if (map.containsKey(null)) { 93 throw new NullPointerException(); 94 } 95 return new AbstractMap<String, String>() { 96 @Override 97 public Set<Entry<String, String>> entrySet() { 98 return map.entrySet(); 99 } 100 101 @Override 102 public String put(String key, String value) { 103 checkNotNull(key); 104 return map.put(key, value); 105 } 106 }; 107 } 108 }, 109 "HashMap w/out null keys", 110 ALLOWS_NULL_VALUES); 111 } 112 113 private static Test testsForHashMapNullValuesForbidden() { 114 return wrappedHashMapTests( 115 new WrappedHashMapGenerator() { 116 @Override 117 Map<String, String> wrap(final HashMap<String, String> map) { 118 if (map.containsValue(null)) { 119 throw new NullPointerException(); 120 } 121 122 return new AbstractMap<String, String>() { 123 @Override 124 public Set<Entry<String, String>> entrySet() { 125 return new EntrySet(); 126 } 127 128 @Override 129 public int hashCode() { 130 return map.hashCode(); 131 } 132 133 @Override 134 public boolean equals(Object o) { 135 return map.equals(o); 136 } 137 138 @Override 139 public String toString() { 140 return map.toString(); 141 } 142 143 @Override 144 public String remove(Object key) { 145 return map.remove(key); 146 } 147 148 class EntrySet extends AbstractSet<Map.Entry<String, String>> { 149 @Override 150 public Iterator<Entry<String, String>> iterator() { 151 return new Iterator<Entry<String, String>>() { 152 153 final Iterator<Entry<String, String>> iterator = map.entrySet().iterator(); 154 155 @Override 156 public void remove() { 157 iterator.remove(); 158 } 159 160 @Override 161 public boolean hasNext() { 162 return iterator.hasNext(); 163 } 164 165 @Override 166 public Entry<String, String> next() { 167 return transform(iterator.next()); 168 } 169 170 private Entry<String, String> transform(final Entry<String, String> next) { 171 return new Entry<String, String>() { 172 173 @Override 174 public String setValue(String value) { 175 checkNotNull(value); 176 return next.setValue(value); 177 } 178 179 @Override 180 public String getValue() { 181 return next.getValue(); 182 } 183 184 @Override 185 public String getKey() { 186 return next.getKey(); 187 } 188 189 @Override 190 public boolean equals(Object obj) { 191 return next.equals(obj); 192 } 193 194 @Override 195 public int hashCode() { 196 return next.hashCode(); 197 } 198 }; 199 } 200 }; 201 } 202 203 @Override 204 public int size() { 205 return map.size(); 206 } 207 208 @Override 209 public boolean remove(Object o) { 210 return map.entrySet().remove(o); 211 } 212 213 @Override 214 public boolean containsAll(Collection<?> c) { 215 return map.entrySet().containsAll(c); 216 } 217 218 @Override 219 public boolean removeAll(Collection<?> c) { 220 return map.entrySet().removeAll(c); 221 } 222 223 @Override 224 public boolean retainAll(Collection<?> c) { 225 return map.entrySet().retainAll(c); 226 } 227 228 @Override 229 public int hashCode() { 230 return map.entrySet().hashCode(); 231 } 232 233 @Override 234 public boolean equals(Object o) { 235 return map.entrySet().equals(o); 236 } 237 238 @Override 239 public String toString() { 240 return map.entrySet().toString(); 241 } 242 } 243 244 @Override 245 public String put(String key, String value) { 246 checkNotNull(value); 247 return map.put(key, value); 248 } 249 }; 250 } 251 }, 252 "HashMap w/out null values", 253 ALLOWS_NULL_KEYS); 254 } 255 } 256