001/* 002 * Copyright (C) 2010 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.collect.testing; 018 019import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER; 020 021import com.google.common.annotations.GwtIncompatible; 022import com.google.common.collect.testing.DerivedCollectionGenerators.Bound; 023import com.google.common.collect.testing.DerivedCollectionGenerators.SortedMapSubmapTestMapGenerator; 024import com.google.common.collect.testing.features.Feature; 025import com.google.common.collect.testing.testers.SortedMapNavigationTester; 026import java.util.ArrayList; 027import java.util.Collections; 028import java.util.List; 029import java.util.Map; 030import java.util.Map.Entry; 031import java.util.Set; 032import junit.framework.TestSuite; 033 034/** 035 * Creates, based on your criteria, a JUnit test suite that exhaustively tests a SortedMap 036 * implementation. 037 */ 038@GwtIncompatible 039public class SortedMapTestSuiteBuilder<K, V> extends MapTestSuiteBuilder<K, V> { 040 public static <K, V> SortedMapTestSuiteBuilder<K, V> using( 041 TestSortedMapGenerator<K, V> generator) { 042 SortedMapTestSuiteBuilder<K, V> result = new SortedMapTestSuiteBuilder<>(); 043 result.usingGenerator(generator); 044 return result; 045 } 046 047 @Override 048 protected List<Class<? extends AbstractTester>> getTesters() { 049 List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters()); 050 testers.add(SortedMapNavigationTester.class); 051 return testers; 052 } 053 054 @Override 055 public TestSuite createTestSuite() { 056 if (!getFeatures().contains(KNOWN_ORDER)) { 057 List<Feature<?>> features = Helpers.copyToList(getFeatures()); 058 features.add(KNOWN_ORDER); 059 withFeatures(features); 060 } 061 return super.createTestSuite(); 062 } 063 064 @Override 065 protected List<TestSuite> createDerivedSuites( 066 FeatureSpecificTestSuiteBuilder< 067 ?, ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>> 068 parentBuilder) { 069 List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder); 070 071 if (!parentBuilder.getFeatures().contains(NoRecurse.SUBMAP)) { 072 derivedSuites.add(createSubmapSuite(parentBuilder, Bound.NO_BOUND, Bound.EXCLUSIVE)); 073 derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.NO_BOUND)); 074 derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.EXCLUSIVE)); 075 } 076 077 return derivedSuites; 078 } 079 080 @Override 081 protected SetTestSuiteBuilder<K> createDerivedKeySetSuite(TestSetGenerator<K> keySetGenerator) { 082 return keySetGenerator instanceof TestSortedSetGenerator 083 ? SortedSetTestSuiteBuilder.using((TestSortedSetGenerator<K>) keySetGenerator) 084 : SetTestSuiteBuilder.using(keySetGenerator); 085 } 086 087 /** 088 * To avoid infinite recursion, test suites with these marker features won't have derived suites 089 * created for them. 090 */ 091 enum NoRecurse implements Feature<Void> { 092 SUBMAP, 093 DESCENDING; 094 095 @Override 096 public Set<Feature<? super Void>> getImpliedFeatures() { 097 return Collections.emptySet(); 098 } 099 } 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 the relative order of 105 * these extreme values rather than relying on their regular sort ordering. 106 */ 107 final TestSuite createSubmapSuite( 108 final FeatureSpecificTestSuiteBuilder< 109 ?, ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>> 110 parentBuilder, 111 final Bound from, 112 final Bound to) { 113 final TestSortedMapGenerator<K, V> delegate = 114 (TestSortedMapGenerator<K, V>) parentBuilder.getSubjectGenerator().getInnerGenerator(); 115 116 List<Feature<?>> features = new ArrayList<>(); 117 features.add(NoRecurse.SUBMAP); 118 features.addAll(parentBuilder.getFeatures()); 119 120 return newBuilderUsing(delegate, to, from) 121 .named(parentBuilder.getName() + " subMap " + from + "-" + to) 122 .withFeatures(features) 123 .suppressing(parentBuilder.getSuppressedTests()) 124 .withSetUp(parentBuilder.getSetUp()) 125 .withTearDown(parentBuilder.getTearDown()) 126 .createTestSuite(); 127 } 128 129 /** Like using() but overrideable by NavigableMapTestSuiteBuilder. */ 130 SortedMapTestSuiteBuilder<K, V> newBuilderUsing( 131 TestSortedMapGenerator<K, V> delegate, Bound to, Bound from) { 132 return using(new SortedMapSubmapTestMapGenerator<K, V>(delegate, to, from)); 133 } 134}