11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2010 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect.testing; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.testing.features.Feature; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.testing.testers.MapNavigationTester; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestSuite; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ArrayList; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.NavigableMap; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates, based on your criteria, a JUnit test suite that exhaustively tests 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a NavigableMap implementation. 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class NavigableMapTestSuiteBuilder<K, V> extends MapTestSuiteBuilder<K, V> { 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> NavigableMapTestSuiteBuilder<K, V> using( 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TestMapGenerator<K, V> generator) { 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NavigableMapTestSuiteBuilder<K, V> result = new NavigableMapTestSuiteBuilder<K, V>(); 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.usingGenerator(generator); 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected List<Class<? extends AbstractTester>> getTesters() { 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters()); 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert testers.add(MapNavigationTester.class); 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return testers; 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?, 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>> parentBuilder) { 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder); 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!parentBuilder.getFeatures().contains(NoRecurse.DESCENDING)) { 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createDescendingSuite(parentBuilder)); 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!parentBuilder.getFeatures().contains(NoRecurse.SUBMAP)) { 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createSubmapSuite(parentBuilder, Bound.NO_BOUND, Bound.EXCLUSIVE)); 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createSubmapSuite(parentBuilder, Bound.NO_BOUND, Bound.INCLUSIVE)); 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createSubmapSuite(parentBuilder, Bound.EXCLUSIVE, Bound.NO_BOUND)); 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createSubmapSuite(parentBuilder, Bound.EXCLUSIVE, Bound.EXCLUSIVE)); 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createSubmapSuite(parentBuilder, Bound.EXCLUSIVE, Bound.INCLUSIVE)); 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.NO_BOUND)); 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.EXCLUSIVE)); 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.INCLUSIVE)); 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return derivedSuites; 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected SetTestSuiteBuilder<K> createDerivedKeySetSuite( 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TestSetGenerator<K> keySetGenerator) { 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return NavigableSetTestSuiteBuilder.using(keySetGenerator); 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * To avoid infinite recursion, test suites with these marker features won't 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * have derived suites created for them. 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert enum NoRecurse implements Feature<Void> { 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SUBMAP, 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DESCENDING; 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<Feature<? super Void>> getImpliedFeatures() { 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.emptySet(); 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Two bounds (from and to) define how to build a subMap. 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert enum Bound { 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert INCLUSIVE, 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EXCLUSIVE, 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NO_BOUND; 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a suite whose map has some elements filtered out of view. 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Because the map may be ascending or descending, this test must derive 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the relative order of these extreme values rather than relying on their 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * regular sort ordering. 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private TestSuite createSubmapSuite(final FeatureSpecificTestSuiteBuilder<?, 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>> 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert parentBuilder, final Bound from, final Bound to) { 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final TestMapGenerator<K, V> delegate 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = (TestMapGenerator<K, V>) parentBuilder.getSubjectGenerator().getInnerGenerator(); 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Feature<?>> features = new ArrayList<Feature<?>>(); 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert features.add(NoRecurse.SUBMAP); 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert features.addAll(parentBuilder.getFeatures()); 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NavigableMap<K, V> emptyMap = (NavigableMap<K, V>) delegate.create(); 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Comparator<Entry<K, V>> entryComparator = Helpers.entryComparator(emptyMap.comparator()); 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // derive values for inclusive filtering from the input samples 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SampleElements<Entry<K, V>> samples = delegate.samples(); 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // no elements are inserted into the array 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Entry<K, V>> samplesList = Arrays.asList( 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert samples.e0, samples.e1, samples.e2, samples.e3, samples.e4); 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.sort(samplesList, entryComparator); 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final K firstInclusive = samplesList.get(0).getKey(); 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final K lastInclusive = samplesList.get(samplesList.size() - 1).getKey(); 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return NavigableMapTestSuiteBuilder 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .using(new ForwardingTestMapGenerator<K, V>(delegate) { 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<K, V> create(Object... entries) { 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // we dangerously assume K and V are both strings 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Entry<K, V>> extremeValues = (List) getExtremeValues(); 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // map generators must past entry objects 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Entry<K, V>> normalValues = (List) Arrays.asList(entries); 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // prepare extreme values to be filtered out of view 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.sort(extremeValues, entryComparator); 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K firstExclusive = extremeValues.get(1).getKey(); 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K lastExclusive = extremeValues.get(2).getKey(); 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (from == Bound.NO_BOUND) { 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extremeValues.remove(0); 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extremeValues.remove(0); 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (to == Bound.NO_BOUND) { 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extremeValues.remove(extremeValues.size() - 1); 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extremeValues.remove(extremeValues.size() - 1); 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // the regular values should be visible after filtering 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Entry<K, V>> allEntries = new ArrayList<Entry<K, V>>(); 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert allEntries.addAll(extremeValues); 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert allEntries.addAll(normalValues); 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NavigableMap<K, V> map = (NavigableMap<K, V>) 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate.create((Object[]) 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert allEntries.toArray(new Entry[allEntries.size()])); 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // call the smallest subMap overload that filters out the extreme values 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (from == Bound.NO_BOUND && to == Bound.EXCLUSIVE) { 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.headMap(lastExclusive); 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (from == Bound.NO_BOUND && to == Bound.INCLUSIVE) { 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.headMap(lastInclusive, true); 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (from == Bound.EXCLUSIVE && to == Bound.NO_BOUND) { 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.tailMap(firstExclusive, false); 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (from == Bound.EXCLUSIVE && to == Bound.EXCLUSIVE) { 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.subMap(firstExclusive, false, lastExclusive, false); 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (from == Bound.EXCLUSIVE && to == Bound.INCLUSIVE) { 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.subMap(firstExclusive, false, lastInclusive, true); 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (from == Bound.INCLUSIVE && to == Bound.NO_BOUND) { 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.tailMap(firstInclusive); 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (from == Bound.INCLUSIVE && to == Bound.EXCLUSIVE) { 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.subMap(firstInclusive, lastExclusive); 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (from == Bound.INCLUSIVE && to == Bound.INCLUSIVE) { 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.subMap(firstInclusive, true, lastInclusive, true); 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new IllegalArgumentException(); 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }) 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .named(parentBuilder.getName() + " subMap " + from + "-" + to) 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .withFeatures(features) 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .suppressing(parentBuilder.getSuppressedTests()) 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .createTestSuite(); 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an array of four bogus elements that will always be too high or 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * too low for the display. This includes two values for each extreme. 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This method (dangerously) assume that the strings {@code "!! a"} and 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code "~~ z"} will work for this purpose, which may cause problems for 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * navigable maps with non-string or unicode generators. 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private List<Entry<String, String>> getExtremeValues() { 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Entry<String, String>> result = new ArrayList<Entry<String, String>>(); 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(Helpers.mapEntry("!! a", "below view")); 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(Helpers.mapEntry("!! b", "below view")); 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(Helpers.mapEntry("~~ y", "above view")); 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(Helpers.mapEntry("~~ z", "above view")); 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Create a suite whose maps are descending views of other maps. 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private TestSuite createDescendingSuite(final FeatureSpecificTestSuiteBuilder<?, 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>> parentBuilder) { 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final TestMapGenerator<K, V> delegate 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = (TestMapGenerator<K, V>) parentBuilder.getSubjectGenerator().getInnerGenerator(); 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Feature<?>> features = new ArrayList<Feature<?>>(); 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert features.add(NoRecurse.DESCENDING); 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert features.addAll(parentBuilder.getFeatures()); 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return NavigableMapTestSuiteBuilder 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .using(new ForwardingTestMapGenerator<K, V>(delegate) { 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<K, V> create(Object... entries) { 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NavigableMap<K, V> map = (NavigableMap<K, V>) delegate.create(entries); 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.descendingMap(); 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }) 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .named(parentBuilder.getName() + " descending") 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .withFeatures(features) 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .suppressing(parentBuilder.getSuppressedTests()) 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .createTestSuite(); 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class ForwardingTestMapGenerator<K, V> implements TestMapGenerator<K, V> { 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private TestMapGenerator<K, V> delegate; 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ForwardingTestMapGenerator(TestMapGenerator<K, V> delegate) { 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = delegate; 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) { 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.order(insertionOrder); 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public K[] createKeyArray(int length) { 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.createKeyArray(length); 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V[] createValueArray(int length) { 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.createValueArray(length); 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public SampleElements<Entry<K, V>> samples() { 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.samples(); 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, V> create(Object... elements) { 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.create(elements); 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Entry<K, V>[] createArray(int length) { 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.createArray(length); 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 268