guava
599 строк · 21.6 Кб
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
17package com.google.common.collect.testing;
18
19import static java.util.Arrays.asList;
20
21import com.google.common.annotations.GwtIncompatible;
22import com.google.common.collect.testing.features.CollectionFeature;
23import com.google.common.collect.testing.features.CollectionSize;
24import com.google.common.collect.testing.features.MapFeature;
25import com.google.common.collect.testing.testers.MapEntrySetTester;
26import java.io.Serializable;
27import java.lang.reflect.Method;
28import java.util.Collection;
29import java.util.Collections;
30import java.util.Comparator;
31import java.util.EnumMap;
32import java.util.HashMap;
33import java.util.Hashtable;
34import java.util.LinkedHashMap;
35import java.util.Map;
36import java.util.Map.Entry;
37import java.util.NavigableMap;
38import java.util.SortedMap;
39import java.util.TreeMap;
40import java.util.concurrent.ConcurrentHashMap;
41import java.util.concurrent.ConcurrentSkipListMap;
42import junit.framework.Test;
43import junit.framework.TestSuite;
44
45/**
46* Generates a test suite covering the {@link Map} implementations in the {@link java.util} package.
47* Can be subclassed to specify tests that should be suppressed.
48*
49* @author Kevin Bourrillion
50*/
51@GwtIncompatible
52public class TestsForMapsInJavaUtil {
53
54public static Test suite() {
55return new TestsForMapsInJavaUtil().allTests();
56}
57
58public Test allTests() {
59TestSuite suite = new TestSuite("java.util Maps");
60suite.addTest(testsForCheckedMap());
61suite.addTest(testsForCheckedNavigableMap());
62suite.addTest(testsForCheckedSortedMap());
63suite.addTest(testsForEmptyMap());
64suite.addTest(testsForEmptyNavigableMap());
65suite.addTest(testsForEmptySortedMap());
66suite.addTest(testsForSingletonMap());
67suite.addTest(testsForHashMap());
68suite.addTest(testsForHashtable());
69suite.addTest(testsForLinkedHashMap());
70suite.addTest(testsForSynchronizedNavigableMap());
71suite.addTest(testsForTreeMapNatural());
72suite.addTest(testsForTreeMapWithComparator());
73suite.addTest(testsForUnmodifiableMap());
74suite.addTest(testsForUnmodifiableNavigableMap());
75suite.addTest(testsForUnmodifiableSortedMap());
76suite.addTest(testsForEnumMap());
77suite.addTest(testsForConcurrentHashMap());
78suite.addTest(testsForConcurrentSkipListMapNatural());
79suite.addTest(testsForConcurrentSkipListMapWithComparator());
80return suite;
81}
82
83protected Collection<Method> suppressForCheckedMap() {
84return Collections.emptySet();
85}
86
87protected Collection<Method> suppressForCheckedNavigableMap() {
88return Collections.emptySet();
89}
90
91protected Collection<Method> suppressForCheckedSortedMap() {
92return Collections.emptySet();
93}
94
95protected Collection<Method> suppressForEmptyMap() {
96return Collections.emptySet();
97}
98
99private Collection<Method> suppressForEmptyNavigableMap() {
100return Collections.emptySet();
101}
102
103private Collection<Method> suppressForEmptySortedMap() {
104return Collections.emptySet();
105}
106
107protected Collection<Method> suppressForSingletonMap() {
108return Collections.emptySet();
109}
110
111protected Collection<Method> suppressForHashMap() {
112return Collections.emptySet();
113}
114
115protected Collection<Method> suppressForHashtable() {
116return Collections.emptySet();
117}
118
119protected Collection<Method> suppressForLinkedHashMap() {
120return Collections.emptySet();
121}
122
123protected Collection<Method> suppressForSynchronizedNavigableMap() {
124return Collections.emptySet();
125}
126
127protected Collection<Method> suppressForTreeMapNatural() {
128return Collections.emptySet();
129}
130
131protected Collection<Method> suppressForTreeMapWithComparator() {
132return Collections.emptySet();
133}
134
135protected Collection<Method> suppressForUnmodifiableMap() {
136return Collections.emptySet();
137}
138
139protected Collection<Method> suppressForUnmodifiableNavigableMap() {
140return Collections.emptySet();
141}
142
143protected Collection<Method> suppressForUnmodifiableSortedMap() {
144return Collections.emptySet();
145}
146
147protected Collection<Method> suppressForEnumMap() {
148return Collections.emptySet();
149}
150
151protected Collection<Method> suppressForConcurrentHashMap() {
152return Collections.emptySet();
153}
154
155protected Collection<Method> suppressForConcurrentSkipListMap() {
156return asList(
157MapEntrySetTester.getSetValueMethod(),
158MapEntrySetTester.getSetValueWithNullValuesAbsentMethod(),
159MapEntrySetTester.getSetValueWithNullValuesPresentMethod());
160}
161
162public Test testsForCheckedMap() {
163return MapTestSuiteBuilder.using(
164new TestStringMapGenerator() {
165@Override
166protected Map<String, String> create(Entry<String, String>[] entries) {
167Map<String, String> map = populate(new HashMap<String, String>(), entries);
168return Collections.checkedMap(map, String.class, String.class);
169}
170})
171.named("checkedMap/HashMap")
172.withFeatures(
173MapFeature.GENERAL_PURPOSE,
174MapFeature.ALLOWS_NULL_KEYS,
175MapFeature.ALLOWS_NULL_VALUES,
176MapFeature.ALLOWS_ANY_NULL_QUERIES,
177MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
178MapFeature.RESTRICTS_KEYS,
179MapFeature.RESTRICTS_VALUES,
180CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
181CollectionFeature.SERIALIZABLE,
182CollectionSize.ANY)
183.suppressing(suppressForCheckedMap())
184.createTestSuite();
185}
186
187public Test testsForCheckedNavigableMap() {
188return SortedMapTestSuiteBuilder.using(
189new TestStringSortedMapGenerator() {
190@Override
191protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
192NavigableMap<String, String> map = populate(new TreeMap<String, String>(), entries);
193return Collections.checkedNavigableMap(map, String.class, String.class);
194}
195})
196.named("checkedNavigableMap/TreeMap, natural")
197.withFeatures(
198MapFeature.GENERAL_PURPOSE,
199MapFeature.ALLOWS_NULL_VALUES,
200MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
201MapFeature.RESTRICTS_KEYS,
202MapFeature.RESTRICTS_VALUES,
203CollectionFeature.KNOWN_ORDER,
204CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
205CollectionFeature.SERIALIZABLE,
206CollectionSize.ANY)
207.suppressing(suppressForCheckedNavigableMap())
208.createTestSuite();
209}
210
211public Test testsForCheckedSortedMap() {
212return SortedMapTestSuiteBuilder.using(
213new TestStringSortedMapGenerator() {
214@Override
215protected SortedMap<String, String> create(Entry<String, String>[] entries) {
216SortedMap<String, String> map = populate(new TreeMap<String, String>(), entries);
217return Collections.checkedSortedMap(map, String.class, String.class);
218}
219})
220.named("checkedSortedMap/TreeMap, natural")
221.withFeatures(
222MapFeature.GENERAL_PURPOSE,
223MapFeature.ALLOWS_NULL_VALUES,
224MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
225MapFeature.RESTRICTS_KEYS,
226MapFeature.RESTRICTS_VALUES,
227CollectionFeature.KNOWN_ORDER,
228CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
229CollectionFeature.SERIALIZABLE,
230CollectionSize.ANY)
231.suppressing(suppressForCheckedSortedMap())
232.createTestSuite();
233}
234
235public Test testsForEmptyMap() {
236return MapTestSuiteBuilder.using(
237new TestStringMapGenerator() {
238@Override
239protected Map<String, String> create(Entry<String, String>[] entries) {
240return Collections.emptyMap();
241}
242})
243.named("emptyMap")
244.withFeatures(CollectionFeature.SERIALIZABLE, CollectionSize.ZERO)
245.suppressing(suppressForEmptyMap())
246.createTestSuite();
247}
248
249public Test testsForEmptyNavigableMap() {
250return MapTestSuiteBuilder.using(
251new TestStringSortedMapGenerator() {
252@Override
253protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
254return Collections.emptyNavigableMap();
255}
256})
257.named("emptyNavigableMap")
258.withFeatures(CollectionFeature.SERIALIZABLE, CollectionSize.ZERO)
259.suppressing(suppressForEmptyNavigableMap())
260.createTestSuite();
261}
262
263public Test testsForEmptySortedMap() {
264return MapTestSuiteBuilder.using(
265new TestStringSortedMapGenerator() {
266@Override
267protected SortedMap<String, String> create(Entry<String, String>[] entries) {
268return Collections.emptySortedMap();
269}
270})
271.named("emptySortedMap")
272.withFeatures(CollectionFeature.SERIALIZABLE, CollectionSize.ZERO)
273.suppressing(suppressForEmptySortedMap())
274.createTestSuite();
275}
276
277public Test testsForSingletonMap() {
278return MapTestSuiteBuilder.using(
279new TestStringMapGenerator() {
280@Override
281protected Map<String, String> create(Entry<String, String>[] entries) {
282return Collections.singletonMap(entries[0].getKey(), entries[0].getValue());
283}
284})
285.named("singletonMap")
286.withFeatures(
287MapFeature.ALLOWS_NULL_KEYS,
288MapFeature.ALLOWS_NULL_VALUES,
289MapFeature.ALLOWS_ANY_NULL_QUERIES,
290CollectionFeature.SERIALIZABLE,
291CollectionSize.ONE)
292.suppressing(suppressForSingletonMap())
293.createTestSuite();
294}
295
296public Test testsForHashMap() {
297return MapTestSuiteBuilder.using(
298new TestStringMapGenerator() {
299@Override
300protected Map<String, String> create(Entry<String, String>[] entries) {
301return toHashMap(entries);
302}
303})
304.named("HashMap")
305.withFeatures(
306MapFeature.GENERAL_PURPOSE,
307MapFeature.ALLOWS_NULL_KEYS,
308MapFeature.ALLOWS_NULL_VALUES,
309MapFeature.ALLOWS_ANY_NULL_QUERIES,
310MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
311CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
312CollectionFeature.SERIALIZABLE,
313CollectionSize.ANY)
314.suppressing(suppressForHashMap())
315.createTestSuite();
316}
317
318public Test testsForHashtable() {
319return MapTestSuiteBuilder.using(
320new TestStringMapGenerator() {
321@Override
322protected Map<String, String> create(Entry<String, String>[] entries) {
323return populate(new Hashtable<String, String>(), entries);
324}
325})
326.withFeatures(
327MapFeature.GENERAL_PURPOSE,
328MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
329MapFeature.RESTRICTS_KEYS,
330MapFeature.SUPPORTS_REMOVE,
331CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
332CollectionFeature.SERIALIZABLE,
333CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
334CollectionFeature.SUPPORTS_REMOVE,
335CollectionSize.ANY)
336.named("Hashtable")
337.suppressing(suppressForHashtable())
338.createTestSuite();
339}
340
341public Test testsForLinkedHashMap() {
342return MapTestSuiteBuilder.using(
343new TestStringMapGenerator() {
344@Override
345protected Map<String, String> create(Entry<String, String>[] entries) {
346return populate(new LinkedHashMap<String, String>(), entries);
347}
348})
349.named("LinkedHashMap")
350.withFeatures(
351MapFeature.GENERAL_PURPOSE,
352MapFeature.ALLOWS_NULL_KEYS,
353MapFeature.ALLOWS_NULL_VALUES,
354MapFeature.ALLOWS_ANY_NULL_QUERIES,
355MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
356CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
357CollectionFeature.KNOWN_ORDER,
358CollectionFeature.SERIALIZABLE,
359CollectionSize.ANY)
360.suppressing(suppressForLinkedHashMap())
361.createTestSuite();
362}
363
364/**
365* Tests regular NavigableMap behavior of synchronizedNavigableMap(treeMap); does not test the
366* fact that it's synchronized.
367*/
368public Test testsForSynchronizedNavigableMap() {
369return NavigableMapTestSuiteBuilder.using(
370new TestStringSortedMapGenerator() {
371@Override
372protected SortedMap<String, String> create(Entry<String, String>[] entries) {
373NavigableMap<String, String> delegate = populate(new TreeMap<>(), entries);
374return Collections.synchronizedNavigableMap(delegate);
375}
376})
377.named("synchronizedNavigableMap/TreeMap, natural")
378.withFeatures(
379MapFeature.GENERAL_PURPOSE,
380MapFeature.ALLOWS_NULL_VALUES,
381MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
382CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
383CollectionFeature.KNOWN_ORDER,
384CollectionFeature.SERIALIZABLE,
385CollectionSize.ANY)
386.suppressing(suppressForSynchronizedNavigableMap())
387.createTestSuite();
388}
389
390public Test testsForTreeMapNatural() {
391return NavigableMapTestSuiteBuilder.using(
392new TestStringSortedMapGenerator() {
393@Override
394protected SortedMap<String, String> create(Entry<String, String>[] entries) {
395/*
396* TODO(cpovirk): it would be nice to create an input Map and use
397* the copy constructor here and in the other tests
398*/
399return populate(new TreeMap<String, String>(), entries);
400}
401})
402.named("TreeMap, natural")
403.withFeatures(
404MapFeature.GENERAL_PURPOSE,
405MapFeature.ALLOWS_NULL_VALUES,
406MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
407CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
408CollectionFeature.KNOWN_ORDER,
409CollectionFeature.SERIALIZABLE,
410CollectionSize.ANY)
411.suppressing(suppressForTreeMapNatural())
412.createTestSuite();
413}
414
415public Test testsForTreeMapWithComparator() {
416return NavigableMapTestSuiteBuilder.using(
417new TestStringSortedMapGenerator() {
418@Override
419protected SortedMap<String, String> create(Entry<String, String>[] entries) {
420return populate(
421new TreeMap<String, String>(arbitraryNullFriendlyComparator()), entries);
422}
423})
424.named("TreeMap, with comparator")
425.withFeatures(
426MapFeature.GENERAL_PURPOSE,
427MapFeature.ALLOWS_NULL_KEYS,
428MapFeature.ALLOWS_NULL_VALUES,
429MapFeature.ALLOWS_ANY_NULL_QUERIES,
430MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
431CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
432CollectionFeature.KNOWN_ORDER,
433CollectionFeature.SERIALIZABLE,
434CollectionSize.ANY)
435.suppressing(suppressForTreeMapWithComparator())
436.createTestSuite();
437}
438
439public Test testsForUnmodifiableMap() {
440return MapTestSuiteBuilder.using(
441new TestStringMapGenerator() {
442@Override
443protected Map<String, String> create(Entry<String, String>[] entries) {
444return Collections.unmodifiableMap(toHashMap(entries));
445}
446})
447.named("unmodifiableMap/HashMap")
448.withFeatures(
449MapFeature.ALLOWS_NULL_KEYS,
450MapFeature.ALLOWS_NULL_VALUES,
451MapFeature.ALLOWS_ANY_NULL_QUERIES,
452CollectionFeature.SERIALIZABLE,
453CollectionSize.ANY)
454.suppressing(suppressForUnmodifiableMap())
455.createTestSuite();
456}
457
458public Test testsForUnmodifiableNavigableMap() {
459return MapTestSuiteBuilder.using(
460new TestStringSortedMapGenerator() {
461@Override
462protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
463return Collections.unmodifiableNavigableMap(populate(new TreeMap<>(), entries));
464}
465})
466.named("unmodifiableNavigableMap/TreeMap, natural")
467.withFeatures(
468MapFeature.ALLOWS_NULL_VALUES,
469CollectionFeature.KNOWN_ORDER,
470CollectionFeature.SERIALIZABLE,
471CollectionSize.ANY)
472.suppressing(suppressForUnmodifiableNavigableMap())
473.createTestSuite();
474}
475
476public Test testsForUnmodifiableSortedMap() {
477return MapTestSuiteBuilder.using(
478new TestStringSortedMapGenerator() {
479@Override
480protected SortedMap<String, String> create(Entry<String, String>[] entries) {
481SortedMap<String, String> map = populate(new TreeMap<String, String>(), entries);
482return Collections.unmodifiableSortedMap(map);
483}
484})
485.named("unmodifiableSortedMap/TreeMap, natural")
486.withFeatures(
487MapFeature.ALLOWS_NULL_VALUES,
488CollectionFeature.KNOWN_ORDER,
489CollectionFeature.SERIALIZABLE,
490CollectionSize.ANY)
491.suppressing(suppressForUnmodifiableSortedMap())
492.createTestSuite();
493}
494
495public Test testsForEnumMap() {
496return MapTestSuiteBuilder.using(
497new TestEnumMapGenerator() {
498@Override
499protected Map<AnEnum, String> create(Entry<AnEnum, String>[] entries) {
500return populate(new EnumMap<AnEnum, String>(AnEnum.class), entries);
501}
502})
503.named("EnumMap")
504.withFeatures(
505MapFeature.GENERAL_PURPOSE,
506MapFeature.ALLOWS_NULL_VALUES,
507MapFeature.RESTRICTS_KEYS,
508CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
509CollectionFeature.KNOWN_ORDER,
510CollectionFeature.SERIALIZABLE,
511CollectionSize.ANY)
512.suppressing(suppressForEnumMap())
513.createTestSuite();
514}
515
516public Test testsForConcurrentHashMap() {
517return MapTestSuiteBuilder.using(
518new TestStringMapGenerator() {
519@Override
520protected Map<String, String> create(Entry<String, String>[] entries) {
521return populate(new ConcurrentHashMap<String, String>(), entries);
522}
523})
524.named("ConcurrentHashMap")
525.withFeatures(
526MapFeature.GENERAL_PURPOSE,
527CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
528CollectionFeature.SERIALIZABLE,
529CollectionSize.ANY)
530.suppressing(suppressForConcurrentHashMap())
531.createTestSuite();
532}
533
534public Test testsForConcurrentSkipListMapNatural() {
535return NavigableMapTestSuiteBuilder.using(
536new TestStringSortedMapGenerator() {
537@Override
538protected SortedMap<String, String> create(Entry<String, String>[] entries) {
539return populate(new ConcurrentSkipListMap<String, String>(), entries);
540}
541})
542.named("ConcurrentSkipListMap, natural")
543.withFeatures(
544MapFeature.GENERAL_PURPOSE,
545CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
546CollectionFeature.KNOWN_ORDER,
547CollectionFeature.SERIALIZABLE,
548CollectionSize.ANY)
549.suppressing(suppressForConcurrentSkipListMap())
550.createTestSuite();
551}
552
553public Test testsForConcurrentSkipListMapWithComparator() {
554return NavigableMapTestSuiteBuilder.using(
555new TestStringSortedMapGenerator() {
556@Override
557protected SortedMap<String, String> create(Entry<String, String>[] entries) {
558return populate(
559new ConcurrentSkipListMap<String, String>(arbitraryNullFriendlyComparator()),
560entries);
561}
562})
563.named("ConcurrentSkipListMap, with comparator")
564.withFeatures(
565MapFeature.GENERAL_PURPOSE,
566CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
567CollectionFeature.KNOWN_ORDER,
568CollectionFeature.SERIALIZABLE,
569CollectionSize.ANY)
570.suppressing(suppressForConcurrentSkipListMap())
571.createTestSuite();
572}
573
574// TODO: IdentityHashMap, AbstractMap
575
576private static Map<String, String> toHashMap(Entry<String, String>[] entries) {
577return populate(new HashMap<String, String>(), entries);
578}
579
580// TODO: call conversion constructors or factory methods instead of using
581// populate() on an empty map
582private static <T, M extends Map<T, String>> M populate(M map, Entry<T, String>[] entries) {
583for (Entry<T, String> entry : entries) {
584map.put(entry.getKey(), entry.getValue());
585}
586return map;
587}
588
589static <T> Comparator<T> arbitraryNullFriendlyComparator() {
590return new NullFriendlyComparator<>();
591}
592
593private static final class NullFriendlyComparator<T> implements Comparator<T>, Serializable {
594@Override
595public int compare(T left, T right) {
596return String.valueOf(left).compareTo(String.valueOf(right));
597}
598}
599}
600