View Javadoc
1   /*
2    * Copyright (C) 2010 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.collect.testing.features.CollectionFeature.KNOWN_ORDER;
20  
21  import com.google.common.annotations.GwtIncompatible;
22  import com.google.common.collect.testing.DerivedCollectionGenerators.Bound;
23  import com.google.common.collect.testing.DerivedCollectionGenerators.SortedMapSubmapTestMapGenerator;
24  import com.google.common.collect.testing.features.Feature;
25  import com.google.common.collect.testing.testers.SortedMapNavigationTester;
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Map.Entry;
31  import java.util.Set;
32  import junit.framework.TestSuite;
33  
34  /**
35   * Creates, based on your criteria, a JUnit test suite that exhaustively tests
36   * a SortedMap implementation.
37   */
38  @GwtIncompatible
39  public class SortedMapTestSuiteBuilder<K, V> extends MapTestSuiteBuilder<K, V> {
40    public static <K, V> SortedMapTestSuiteBuilder<K, V> using(
41        TestSortedMapGenerator<K, V> generator) {
42      SortedMapTestSuiteBuilder<K, V> result = new SortedMapTestSuiteBuilder<>();
43      result.usingGenerator(generator);
44      return result;
45    }
46  
47    @Override
48    protected List<Class<? extends AbstractTester>> getTesters() {
49      List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
50      testers.add(SortedMapNavigationTester.class);
51      return testers;
52    }
53  
54    @Override
55    public TestSuite createTestSuite() {
56      if (!getFeatures().contains(KNOWN_ORDER)) {
57        List<Feature<?>> features = Helpers.copyToList(getFeatures());
58        features.add(KNOWN_ORDER);
59        withFeatures(features);
60      }
61      return super.createTestSuite();
62    }
63  
64    @Override
65    protected List<TestSuite> createDerivedSuites(
66        FeatureSpecificTestSuiteBuilder<
67                ?, ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>>
68            parentBuilder) {
69      List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
70  
71      if (!parentBuilder.getFeatures().contains(NoRecurse.SUBMAP)) {
72        derivedSuites.add(createSubmapSuite(parentBuilder, Bound.NO_BOUND, Bound.EXCLUSIVE));
73        derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.NO_BOUND));
74        derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.EXCLUSIVE));
75      }
76  
77      return derivedSuites;
78    }
79  
80    @Override
81    protected SetTestSuiteBuilder<K> createDerivedKeySetSuite(TestSetGenerator<K> keySetGenerator) {
82      return keySetGenerator instanceof TestSortedSetGenerator
83          ? SortedSetTestSuiteBuilder.using((TestSortedSetGenerator<K>) keySetGenerator)
84          : SetTestSuiteBuilder.using(keySetGenerator);
85    }
86  
87    /**
88     * To avoid infinite recursion, test suites with these marker features won't
89     * have derived suites created for them.
90     */
91    enum NoRecurse implements Feature<Void> {
92      SUBMAP,
93      DESCENDING;
94  
95      @Override
96      public Set<Feature<? super Void>> getImpliedFeatures() {
97        return Collections.emptySet();
98      }
99    }
100 
101   /**
102    * Creates a suite whose map has some elements filtered out of view.
103    *
104    * <p>Because the map may be ascending or descending, this test must derive
105    * the relative order of these extreme values rather than relying on their
106    * regular sort ordering.
107    */
108   final TestSuite createSubmapSuite(
109       final FeatureSpecificTestSuiteBuilder<
110               ?, ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>>
111           parentBuilder,
112       final Bound from,
113       final Bound to) {
114     final TestSortedMapGenerator<K, V> delegate =
115         (TestSortedMapGenerator<K, V>) parentBuilder.getSubjectGenerator().getInnerGenerator();
116 
117     List<Feature<?>> features = new ArrayList<>();
118     features.add(NoRecurse.SUBMAP);
119     features.addAll(parentBuilder.getFeatures());
120 
121     return newBuilderUsing(delegate, to, from)
122         .named(parentBuilder.getName() + " subMap " + from + "-" + to)
123         .withFeatures(features)
124         .suppressing(parentBuilder.getSuppressedTests())
125         .createTestSuite();
126   }
127 
128   /** Like using() but overrideable by NavigableMapTestSuiteBuilder. */
129   SortedMapTestSuiteBuilder<K, V> newBuilderUsing(
130       TestSortedMapGenerator<K, V> delegate, Bound to, Bound from) {
131     return using(new SortedMapSubmapTestMapGenerator<K, V>(delegate, to, from));
132   }
133 }