Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.google.common.collect.testing.DerivedCollectionGenerators Maven / Gradle / Ivy
Go to download
Guava testlib is a set of java classes used for more convenient
unit testing - particularly to assist the tests for Guava itself.
/*
* Copyright (C) 2008 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.common.collect.testing;
import static com.google.common.collect.testing.Helpers.castOrCopyToList;
import static com.google.common.collect.testing.Helpers.equal;
import static com.google.common.collect.testing.Helpers.mapEntry;
import static java.util.Collections.sort;
import com.google.common.annotations.GwtCompatible;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Derived suite generators, split out of the suite builders so that they are available to GWT.
*
* @author George van den Driessche
*/
@GwtCompatible
@ElementTypesAreNonnullByDefault
public final class DerivedCollectionGenerators {
public static class MapEntrySetGenerator
implements TestSetGenerator>, DerivedGenerator {
private final OneSizeTestContainerGenerator, Entry> mapGenerator;
public MapEntrySetGenerator(
OneSizeTestContainerGenerator, Entry> mapGenerator) {
this.mapGenerator = mapGenerator;
}
@Override
public SampleElements> samples() {
return mapGenerator.samples();
}
@Override
public Set> create(Object... elements) {
return mapGenerator.create(elements).entrySet();
}
@Override
public Entry[] createArray(int length) {
return mapGenerator.createArray(length);
}
@Override
public Iterable> order(List> insertionOrder) {
return mapGenerator.order(insertionOrder);
}
@Override
public OneSizeTestContainerGenerator, Entry> getInnerGenerator() {
return mapGenerator;
}
}
// TODO: investigate some API changes to SampleElements that would tidy up
// parts of the following classes.
static
TestSetGenerator keySetGenerator(
OneSizeTestContainerGenerator, Entry> mapGenerator) {
TestContainerGenerator, Entry> generator = mapGenerator.getInnerGenerator();
if (generator instanceof TestSortedMapGenerator
&& ((TestSortedMapGenerator) generator).create().keySet() instanceof SortedSet) {
return new MapSortedKeySetGenerator<>(mapGenerator);
} else {
return new MapKeySetGenerator<>(mapGenerator);
}
}
public static class MapKeySetGenerator
implements TestSetGenerator, DerivedGenerator {
private final OneSizeTestContainerGenerator, Entry> mapGenerator;
private final SampleElements samples;
public MapKeySetGenerator(OneSizeTestContainerGenerator, Entry> mapGenerator) {
this.mapGenerator = mapGenerator;
SampleElements> mapSamples = this.mapGenerator.samples();
this.samples =
new SampleElements<>(
mapSamples.e0().getKey(),
mapSamples.e1().getKey(),
mapSamples.e2().getKey(),
mapSamples.e3().getKey(),
mapSamples.e4().getKey());
}
@Override
public SampleElements samples() {
return samples;
}
@Override
public Set create(Object... elements) {
@SuppressWarnings("unchecked")
K[] keysArray = (K[]) elements;
// Start with a suitably shaped collection of entries
Collection> originalEntries = mapGenerator.getSampleElements(elements.length);
// Create a copy of that, with the desired value for each key
Collection> entries = new ArrayList<>(elements.length);
int i = 0;
for (Entry entry : originalEntries) {
entries.add(Helpers.mapEntry(keysArray[i++], entry.getValue()));
}
return mapGenerator.create(entries.toArray()).keySet();
}
@Override
public K[] createArray(int length) {
// TODO: with appropriate refactoring of OneSizeGenerator, we can perhaps
// tidy this up and get rid of the casts here and in
// MapValueCollectionGenerator.
return ((TestMapGenerator) mapGenerator.getInnerGenerator()).createKeyArray(length);
}
@Override
public Iterable order(List insertionOrder) {
V v = ((TestMapGenerator) mapGenerator.getInnerGenerator()).samples().e0().getValue();
List> entries = new ArrayList<>();
for (K element : insertionOrder) {
entries.add(mapEntry(element, v));
}
List keys = new ArrayList<>();
for (Entry entry : mapGenerator.order(entries)) {
keys.add(entry.getKey());
}
return keys;
}
@Override
public OneSizeTestContainerGenerator, Entry> getInnerGenerator() {
return mapGenerator;
}
}
public static class MapSortedKeySetGenerator<
K extends @Nullable Object, V extends @Nullable Object>
extends MapKeySetGenerator implements TestSortedSetGenerator, DerivedGenerator {
private final TestSortedMapGenerator delegate;
public MapSortedKeySetGenerator(
OneSizeTestContainerGenerator, Entry> mapGenerator) {
super(mapGenerator);
this.delegate = (TestSortedMapGenerator) mapGenerator.getInnerGenerator();
}
@Override
public SortedSet create(Object... elements) {
return (SortedSet) super.create(elements);
}
@Override
public K belowSamplesLesser() {
return delegate.belowSamplesLesser().getKey();
}
@Override
public K belowSamplesGreater() {
return delegate.belowSamplesGreater().getKey();
}
@Override
public K aboveSamplesLesser() {
return delegate.aboveSamplesLesser().getKey();
}
@Override
public K aboveSamplesGreater() {
return delegate.aboveSamplesGreater().getKey();
}
}
public static class MapValueCollectionGenerator<
K extends @Nullable Object, V extends @Nullable Object>
implements TestCollectionGenerator, DerivedGenerator {
private final OneSizeTestContainerGenerator, Entry> mapGenerator;
private final SampleElements samples;
public MapValueCollectionGenerator(
OneSizeTestContainerGenerator, Entry> mapGenerator) {
this.mapGenerator = mapGenerator;
SampleElements> mapSamples = this.mapGenerator.samples();
this.samples =
new SampleElements<>(
mapSamples.e0().getValue(),
mapSamples.e1().getValue(),
mapSamples.e2().getValue(),
mapSamples.e3().getValue(),
mapSamples.e4().getValue());
}
@Override
public SampleElements samples() {
return samples;
}
@Override
public Collection create(Object... elements) {
@SuppressWarnings("unchecked")
V[] valuesArray = (V[]) elements;
// Start with a suitably shaped collection of entries
Collection> originalEntries = mapGenerator.getSampleElements(elements.length);
// Create a copy of that, with the desired value for each value
Collection> entries = new ArrayList<>(elements.length);
int i = 0;
for (Entry entry : originalEntries) {
entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
}
return mapGenerator.create(entries.toArray()).values();
}
@Override
public V[] createArray(int length) {
// noinspection UnnecessaryLocalVariable
V[] vs = ((TestMapGenerator) mapGenerator.getInnerGenerator()).createValueArray(length);
return vs;
}
@Override
public Iterable order(List insertionOrder) {
List> orderedEntries =
castOrCopyToList(mapGenerator.order(castOrCopyToList(mapGenerator.getSampleElements(5))));
sort(
insertionOrder,
new Comparator() {
@Override
public int compare(V left, V right) {
// The indexes are small enough for the subtraction trick to be safe.
return indexOfEntryWithValue(left) - indexOfEntryWithValue(right);
}
int indexOfEntryWithValue(V value) {
for (int i = 0; i < orderedEntries.size(); i++) {
if (equal(orderedEntries.get(i).getValue(), value)) {
return i;
}
}
throw new IllegalArgumentException(
"Map.values generator can order only sample values");
}
});
return insertionOrder;
}
@Override
public OneSizeTestContainerGenerator, Entry> getInnerGenerator() {
return mapGenerator;
}
}
// TODO(cpovirk): could something like this be used elsewhere, e.g., ReserializedListGenerator?
static class ForwardingTestMapGenerator
implements TestMapGenerator {
TestMapGenerator delegate;
ForwardingTestMapGenerator(TestMapGenerator delegate) {
this.delegate = delegate;
}
@Override
public Iterable> order(List> insertionOrder) {
return delegate.order(insertionOrder);
}
@Override
public K[] createKeyArray(int length) {
return delegate.createKeyArray(length);
}
@Override
public V[] createValueArray(int length) {
return delegate.createValueArray(length);
}
@Override
public SampleElements> samples() {
return delegate.samples();
}
@Override
public Map create(Object... elements) {
return delegate.create(elements);
}
@Override
public Entry[] createArray(int length) {
return delegate.createArray(length);
}
}
/** Two bounds (from and to) define how to build a subMap. */
public enum Bound {
INCLUSIVE,
EXCLUSIVE,
NO_BOUND;
}
public static class SortedSetSubsetTestSetGenerator
implements TestSortedSetGenerator {
final Bound to;
final Bound from;
final E firstInclusive;
final E lastInclusive;
private final Comparator super E> comparator;
private final TestSortedSetGenerator delegate;
public SortedSetSubsetTestSetGenerator(
TestSortedSetGenerator delegate, Bound to, Bound from) {
this.to = to;
this.from = from;
this.delegate = delegate;
SortedSet emptySet = delegate.create();
this.comparator = emptySet.comparator();
SampleElements samples = delegate.samples();
List samplesList = new ArrayList<>(samples.asList());
Collections.sort(samplesList, comparator);
this.firstInclusive = samplesList.get(0);
this.lastInclusive = samplesList.get(samplesList.size() - 1);
}
public final TestSortedSetGenerator getInnerGenerator() {
return delegate;
}
public final Bound getTo() {
return to;
}
public final Bound getFrom() {
return from;
}
@Override
public SampleElements samples() {
return delegate.samples();
}
@Override
public E[] createArray(int length) {
return delegate.createArray(length);
}
@Override
public Iterable order(List insertionOrder) {
return delegate.order(insertionOrder);
}
@Override
public SortedSet create(Object... elements) {
List> normalValues = (List>) Arrays.asList(elements);
List extremeValues = new ArrayList<>();
// nulls are usually out of bounds for a subset, so ban them altogether
for (Object o : elements) {
if (o == null) {
throw new NullPointerException();
}
}
// prepare extreme values to be filtered out of view
E firstExclusive = delegate.belowSamplesGreater();
E lastExclusive = delegate.aboveSamplesLesser();
if (from != Bound.NO_BOUND) {
extremeValues.add(delegate.belowSamplesLesser());
extremeValues.add(delegate.belowSamplesGreater());
}
if (to != Bound.NO_BOUND) {
extremeValues.add(delegate.aboveSamplesLesser());
extremeValues.add(delegate.aboveSamplesGreater());
}
// the regular values should be visible after filtering
List<@Nullable Object> allEntries = new ArrayList<>();
allEntries.addAll(extremeValues);
allEntries.addAll(normalValues);
SortedSet set = delegate.create(allEntries.toArray());
return createSubSet(set, firstExclusive, lastExclusive);
}
/** Calls the smallest subSet overload that filters out the extreme values. */
SortedSet createSubSet(SortedSet set, E firstExclusive, E lastExclusive) {
if (from == Bound.NO_BOUND && to == Bound.EXCLUSIVE) {
return set.headSet(lastExclusive);
} else if (from == Bound.INCLUSIVE && to == Bound.NO_BOUND) {
return set.tailSet(firstInclusive);
} else if (from == Bound.INCLUSIVE && to == Bound.EXCLUSIVE) {
return set.subSet(firstInclusive, lastExclusive);
} else {
throw new IllegalArgumentException();
}
}
@Override
public E belowSamplesLesser() {
throw new UnsupportedOperationException();
}
@Override
public E belowSamplesGreater() {
throw new UnsupportedOperationException();
}
@Override
public E aboveSamplesLesser() {
throw new UnsupportedOperationException();
}
@Override
public E aboveSamplesGreater() {
throw new UnsupportedOperationException();
}
}
/*
* TODO(cpovirk): surely we can find a less ugly solution than a class that accepts 3 parameters,
* exposes as many getters, does work in the constructor, and has both a superclass and a subclass
*/
public static class SortedMapSubmapTestMapGenerator<
K extends @Nullable Object, V extends @Nullable Object>
extends ForwardingTestMapGenerator implements TestSortedMapGenerator {
final Bound to;
final Bound from;
final K firstInclusive;
final K lastInclusive;
private final Comparator> entryComparator;
public SortedMapSubmapTestMapGenerator(
TestSortedMapGenerator delegate, Bound to, Bound from) {
super(delegate);
this.to = to;
this.from = from;
SortedMap emptyMap = delegate.create();
this.entryComparator = Helpers.entryComparator(emptyMap.comparator());
// derive values for inclusive filtering from the input samples
SampleElements> samples = delegate.samples();
List> samplesList =
Arrays.asList(samples.e0(), samples.e1(), samples.e2(), samples.e3(), samples.e4());
Collections.sort(samplesList, entryComparator);
this.firstInclusive = samplesList.get(0).getKey();
this.lastInclusive = samplesList.get(samplesList.size() - 1).getKey();
}
@Override
public SortedMap create(Object... entries) {
List> extremeValues = new ArrayList<>();
// prepare extreme values to be filtered out of view
K firstExclusive = getInnerGenerator().belowSamplesGreater().getKey();
K lastExclusive = getInnerGenerator().aboveSamplesLesser().getKey();
if (from != Bound.NO_BOUND) {
extremeValues.add(getInnerGenerator().belowSamplesLesser());
extremeValues.add(getInnerGenerator().belowSamplesGreater());
}
if (to != Bound.NO_BOUND) {
extremeValues.add(getInnerGenerator().aboveSamplesLesser());
extremeValues.add(getInnerGenerator().aboveSamplesGreater());
}
// the regular values should be visible after filtering
List> allEntries = new ArrayList<>();
allEntries.addAll(extremeValues);
for (Object entry : entries) {
allEntries.add((Entry, ?>) entry);
}
SortedMap map = (SortedMap) delegate.create(allEntries.toArray());
return createSubMap(map, firstExclusive, lastExclusive);
}
/**
* Calls the smallest subMap overload that filters out the extreme values. This method is
* overridden in NavigableMapTestSuiteBuilder.
*/
SortedMap createSubMap(SortedMap map, K firstExclusive, K lastExclusive) {
if (from == Bound.NO_BOUND && to == Bound.EXCLUSIVE) {
return map.headMap(lastExclusive);
} else if (from == Bound.INCLUSIVE && to == Bound.NO_BOUND) {
return map.tailMap(firstInclusive);
} else if (from == Bound.INCLUSIVE && to == Bound.EXCLUSIVE) {
return map.subMap(firstInclusive, lastExclusive);
} else {
throw new IllegalArgumentException();
}
}
public final Bound getTo() {
return to;
}
public final Bound getFrom() {
return from;
}
public final TestSortedMapGenerator getInnerGenerator() {
return (TestSortedMapGenerator) delegate;
}
@Override
public Entry belowSamplesLesser() {
// should never reach here!
throw new UnsupportedOperationException();
}
@Override
public Entry belowSamplesGreater() {
// should never reach here!
throw new UnsupportedOperationException();
}
@Override
public Entry aboveSamplesLesser() {
// should never reach here!
throw new UnsupportedOperationException();
}
@Override
public Entry aboveSamplesGreater() {
// should never reach here!
throw new UnsupportedOperationException();
}
}
private DerivedCollectionGenerators() {}
}