com.google.common.collect.testing.Helpers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of guava-testlib-jdk5 Show documentation
Show all versions of guava-testlib-jdk5 Show documentation
Guava testlib is a set of java classes used for more convenient
unit testing - particularly to assist the tests for Guava itself.
/*
* Copyright (C) 2009 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 java.util.Collections.sort;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@GwtCompatible(emulated = true)
public class Helpers {
// Clone of Objects.equal
static boolean equal(Object a, Object b) {
return a == b || (a != null && a.equals(b));
}
// Clone of Lists.newArrayList
public static List copyToList(Iterable extends E> elements) {
List list = new ArrayList();
addAll(list, elements);
return list;
}
public static List copyToList(E[] elements) {
return copyToList(Arrays.asList(elements));
}
// Clone of Sets.newLinkedHashSet
public static Set copyToSet(Iterable extends E> elements) {
Set set = new LinkedHashSet();
addAll(set, elements);
return set;
}
public static Set copyToSet(E[] elements) {
return copyToSet(Arrays.asList(elements));
}
// Would use Maps.immutableEntry
public static Entry mapEntry(K key, V value) {
return Collections.singletonMap(key, value).entrySet().iterator().next();
}
public static void assertEqualIgnoringOrder(
Iterable> expected, Iterable> actual) {
List> exp = copyToList(expected);
List> act = copyToList(actual);
String actString = act.toString();
// Of course we could take pains to give the complete description of the
// problem on any failure.
// Yeah it's n^2.
for (Object object : exp) {
if (!act.remove(object)) {
Assert.fail("did not contain expected element " + object + ", "
+ "expected = " + exp + ", actual = " + actString);
}
}
assertTrue("unexpected elements: " + act, act.isEmpty());
}
public static void assertContentsAnyOrder(
Iterable> actual, Object... expected) {
assertEqualIgnoringOrder(Arrays.asList(expected), actual);
}
public static boolean addAll(
Collection addTo, Iterable extends E> elementsToAdd) {
boolean modified = false;
for (E e : elementsToAdd) {
modified |= addTo.add(e);
}
return modified;
}
static Iterable reverse(final List list) {
return new Iterable() {
@Override
public Iterator iterator() {
final ListIterator listIter = list.listIterator(list.size());
return new Iterator() {
@Override
public boolean hasNext() {
return listIter.hasPrevious();
}
@Override
public T next() {
return listIter.previous();
}
@Override
public void remove() {
listIter.remove();
}
};
}
};
}
static Iterator cycle(final Iterable iterable) {
return new Iterator() {
Iterator iterator = Collections.emptySet().iterator();
@Override
public boolean hasNext() {
return true;
}
@Override
public T next() {
if (!iterator.hasNext()) {
iterator = iterable.iterator();
}
return iterator.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
static T get(Iterator iterator, int position) {
for (int i = 0; i < position; i++) {
iterator.next();
}
return iterator.next();
}
static void fail(Throwable cause, Object message) {
AssertionFailedError assertionFailedError =
new AssertionFailedError(String.valueOf(message));
assertionFailedError.initCause(cause);
throw assertionFailedError;
}
public static Comparator> entryComparator(
final Comparator super K> keyComparator) {
return new Comparator>() {
@Override
@SuppressWarnings("unchecked") // no less safe than putting it in the map!
public int compare(Entry a, Entry b) {
return (keyComparator == null)
? ((Comparable) a.getKey()).compareTo(b.getKey())
: keyComparator.compare(a.getKey(), b.getKey());
}
};
}
public static void testComparator(
Comparator super T> comparator, T... valuesInExpectedOrder) {
testComparator(comparator, Arrays.asList(valuesInExpectedOrder));
}
public static void testComparator(
Comparator super T> comparator, List valuesInExpectedOrder) {
// This does an O(n^2) test of all pairs of values in both orders
for (int i = 0; i < valuesInExpectedOrder.size(); i++) {
T t = valuesInExpectedOrder.get(i);
for (int j = 0; j < i; j++) {
T lesser = valuesInExpectedOrder.get(j);
assertTrue(comparator + ".compare(" + lesser + ", " + t + ")",
comparator.compare(lesser, t) < 0);
}
assertEquals(comparator + ".compare(" + t + ", " + t + ")",
0, comparator.compare(t, t));
for (int j = i + 1; j < valuesInExpectedOrder.size(); j++) {
T greater = valuesInExpectedOrder.get(j);
assertTrue(comparator + ".compare(" + greater + ", " + t + ")",
comparator.compare(greater, t) > 0);
}
}
}
public static > void testCompareToAndEquals(
List valuesInExpectedOrder) {
// This does an O(n^2) test of all pairs of values in both orders
for (int i = 0; i < valuesInExpectedOrder.size(); i++) {
T t = valuesInExpectedOrder.get(i);
for (int j = 0; j < i; j++) {
T lesser = valuesInExpectedOrder.get(j);
assertTrue(lesser + ".compareTo(" + t + ')', lesser.compareTo(t) < 0);
assertFalse(lesser.equals(t));
}
assertEquals(t + ".compareTo(" + t + ')', 0, t.compareTo(t));
assertTrue(t.equals(t));
for (int j = i + 1; j < valuesInExpectedOrder.size(); j++) {
T greater = valuesInExpectedOrder.get(j);
assertTrue(greater + ".compareTo(" + t + ')', greater.compareTo(t) > 0);
assertFalse(greater.equals(t));
}
}
}
/**
* Returns a collection that simulates concurrent modification by
* having its size method return incorrect values. This is useful
* for testing methods that must treat the return value from size()
* as a hint only.
*
* @param delta the difference between the true size of the
* collection and the values returned by the size method
*/
public static Collection misleadingSizeCollection(final int delta) {
// It would be nice to be able to return a real concurrent
// collection like ConcurrentLinkedQueue, so that e.g. concurrent
// iteration would work, but that would not be GWT-compatible.
return new ArrayList() {
@Override public int size() { return Math.max(0, super.size() + delta); }
};
}
/**
* Returns a "nefarious" map entry with the specified key and value,
* meaning an entry that is suitable for testing that map entries cannot be
* modified via a nefarious implementation of equals. This is used for testing
* unmodifiable collections of map entries; for example, it should not be
* possible to access the raw (modifiable) map entry via a nefarious equals
* method.
*/
public static Map.Entry nefariousMapEntry(final K key,
final V value) {
return new Map.Entry() {
@Override public K getKey() {
return key;
}
@Override public V getValue() {
return value;
}
@Override public V setValue(V value) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("unchecked")
@Override public boolean equals(Object o) {
if (o instanceof Map.Entry) {
Map.Entry e = (Map.Entry) o;
e.setValue(value); // muhahaha!
return equal(this.getKey(), e.getKey())
&& equal(this.getValue(), e.getValue());
}
return false;
}
@Override public int hashCode() {
K k = getKey();
V v = getValue();
return ((k == null) ?
0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode());
}
/**
* Returns a string representation of the form {key}={value}
.
*/
@Override public String toString() {
return getKey() + "=" + getValue();
}
};
}
static List castOrCopyToList(Iterable iterable) {
if (iterable instanceof List) {
return (List) iterable;
}
List list = new ArrayList();
for (E e : iterable) {
list.add(e);
}
return list;
}
private static final Comparator NATURAL_ORDER = new Comparator() {
@SuppressWarnings("unchecked") // assume any Comparable is Comparable
@Override public int compare(Comparable left, Comparable right) {
return left.compareTo(right);
}
};
public static Iterable> orderEntriesByKey(
List> insertionOrder) {
sort(insertionOrder, Helpers.entryComparator(NATURAL_ORDER));
return insertionOrder;
}
/**
* Private replacement for {@link com.google.gwt.user.client.rpc.GwtTransient} to work around
* build-system quirks.
*/
private @interface GwtTransient {}
/**
* Compares strings in natural order except that null comes immediately before a given value. This
* works better than Ordering.natural().nullsFirst() because, if null comes before all other
* values, it lies outside the submap/submultiset ranges we test, and the variety of tests that
* exercise null handling fail on those subcollections.
*/
public abstract static class NullsBefore implements Comparator, Serializable {
/*
* We don't serialize this class in GWT, so we don't care about whether GWT will serialize this
* field.
*/
@GwtTransient private final String justAfterNull;
protected NullsBefore(String justAfterNull) {
if (justAfterNull == null) {
throw new NullPointerException();
}
this.justAfterNull = justAfterNull;
}
@Override
public int compare(String lhs, String rhs) {
if (lhs == rhs) {
return 0;
}
if (lhs == null) {
// lhs (null) comes just before justAfterNull.
// If rhs is b, lhs comes first.
if (rhs.equals(justAfterNull)) {
return -1;
}
return justAfterNull.compareTo(rhs);
}
if (rhs == null) {
// rhs (null) comes just before justAfterNull.
// If lhs is b, rhs comes first.
if (lhs.equals(justAfterNull)) {
return 1;
}
return lhs.compareTo(justAfterNull);
}
return lhs.compareTo(rhs);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof NullsBefore) {
NullsBefore other = (NullsBefore) obj;
return justAfterNull.equals(other.justAfterNull);
}
return false;
}
@Override
public int hashCode() {
return justAfterNull.hashCode();
}
}
public static final class NullsBeforeB extends NullsBefore {
public static final NullsBeforeB INSTANCE = new NullsBeforeB();
private NullsBeforeB() {
super("b");
}
}
public static final class NullsBeforeTwo extends NullsBefore {
public static final NullsBeforeTwo INSTANCE = new NullsBeforeTwo();
private NullsBeforeTwo() {
super("two"); // from TestStringSortedMapGenerator's sample keys
}
}
@GwtIncompatible("reflection")
public static Method getMethod(Class> clazz, String name) {
try {
return clazz.getMethod(name);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy