Removing collections tests - far too complex a system for the comparators' needs. Will rewrite as standalone test classes
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1159018 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2c499868db
commit
4335b4067d
|
@ -1,227 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.commons.lang3.compare;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract test class for testing the Comparator interface.
|
|
||||||
* <p>
|
|
||||||
* Concrete subclasses declare the comparator to be tested.
|
|
||||||
* They also declare certain aspects of the tests.
|
|
||||||
*
|
|
||||||
* @author Stephen Colebourne
|
|
||||||
*/
|
|
||||||
public abstract class AbstractTestComparator<T> extends AbstractTestObject {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JUnit constructor.
|
|
||||||
*
|
|
||||||
* @param testName the test class name
|
|
||||||
*/
|
|
||||||
public AbstractTestComparator(String testName) {
|
|
||||||
super(testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implement this method to return a list of sorted objects.
|
|
||||||
*
|
|
||||||
* @return sorted objects
|
|
||||||
*/
|
|
||||||
public abstract List<T> getComparableObjectsOrdered();
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Implements the abstract superclass method to return the comparator.
|
|
||||||
*
|
|
||||||
* @return a full iterator
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public abstract Comparator<T> makeObject();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides superclass to block tests.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsEmptyCollections() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides superclass to block tests.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsFullCollections() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides superclass to set the compatability to version 2
|
|
||||||
* as there were no Comparators in version 1.x.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getCompatibilityVersion() {
|
|
||||||
return "2";
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Reverse the list.
|
|
||||||
*/
|
|
||||||
protected void reverseObjects(List<?> list) {
|
|
||||||
Collections.reverse(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Randomize the list.
|
|
||||||
*/
|
|
||||||
protected void randomizeObjects(List<?> list) {
|
|
||||||
Collections.shuffle(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort the list.
|
|
||||||
*/
|
|
||||||
protected void sortObjects(List<T> list, Comparator<? super T> comparator) {
|
|
||||||
Collections.sort(list, comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Test sorting an empty list
|
|
||||||
*/
|
|
||||||
public void testEmptyListSort() {
|
|
||||||
List<T> list = new LinkedList<T>();
|
|
||||||
sortObjects(list, makeObject());
|
|
||||||
|
|
||||||
List<T> list2 = new LinkedList<T>();
|
|
||||||
|
|
||||||
assertTrue("Comparator cannot sort empty lists", list2.equals(list));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test sorting a reversed list.
|
|
||||||
*/
|
|
||||||
public void testReverseListSort() {
|
|
||||||
Comparator<T> comparator = makeObject();
|
|
||||||
|
|
||||||
List<T> randomList = getComparableObjectsOrdered();
|
|
||||||
reverseObjects(randomList);
|
|
||||||
sortObjects(randomList, comparator);
|
|
||||||
|
|
||||||
List<T> orderedList = getComparableObjectsOrdered();
|
|
||||||
|
|
||||||
assertTrue("Comparator did not reorder the List correctly",
|
|
||||||
orderedList.equals(randomList));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test sorting a random list.
|
|
||||||
*/
|
|
||||||
public void testRandomListSort() {
|
|
||||||
Comparator<T> comparator = makeObject();
|
|
||||||
|
|
||||||
List<T> randomList = getComparableObjectsOrdered();
|
|
||||||
randomizeObjects(randomList);
|
|
||||||
sortObjects(randomList,comparator);
|
|
||||||
|
|
||||||
List<T> orderedList = getComparableObjectsOrdered();
|
|
||||||
|
|
||||||
/* debug
|
|
||||||
Iterator i = randomList.iterator();
|
|
||||||
while (i.hasNext()) {
|
|
||||||
System.out.println(i.next());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
assertTrue("Comparator did not reorder the List correctly",
|
|
||||||
orderedList.equals(randomList));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Nearly all Comparators should be Serializable.
|
|
||||||
*/
|
|
||||||
public void testComparatorIsSerializable() {
|
|
||||||
Comparator<T> comparator = makeObject();
|
|
||||||
assertTrue("This comparator should be Serializable.",
|
|
||||||
comparator instanceof Serializable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCanonicalComparatorName(Object object) {
|
|
||||||
StringBuilder retval = new StringBuilder();
|
|
||||||
retval.append("data/test/");
|
|
||||||
String colName = object.getClass().getName();
|
|
||||||
colName = colName.substring(colName.lastIndexOf(".")+1,colName.length());
|
|
||||||
retval.append(colName);
|
|
||||||
retval.append(".version");
|
|
||||||
retval.append(getCompatibilityVersion());
|
|
||||||
retval.append(".obj");
|
|
||||||
return retval.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare the current serialized form of the Comparator
|
|
||||||
* against the canonical version in SVN.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testComparatorCompatibility() throws IOException, ClassNotFoundException {
|
|
||||||
if (!skipSerializedCanonicalTests()) {
|
|
||||||
Comparator<T> comparator = null;
|
|
||||||
|
|
||||||
// test to make sure the canonical form has been preserved
|
|
||||||
try {
|
|
||||||
comparator = (Comparator<T>) readExternalFormFromDisk(getCanonicalComparatorName(makeObject()));
|
|
||||||
} catch (FileNotFoundException exception) {
|
|
||||||
|
|
||||||
boolean autoCreateSerialized = false;
|
|
||||||
|
|
||||||
if (autoCreateSerialized) {
|
|
||||||
comparator = makeObject();
|
|
||||||
String fileName = getCanonicalComparatorName(comparator);
|
|
||||||
writeExternalFormToDisk((Serializable) comparator, fileName);
|
|
||||||
fail("Serialized form could not be found. A serialized version "
|
|
||||||
+ "has now been written (and should be added to CVS): " + fileName);
|
|
||||||
} else {
|
|
||||||
fail("The Serialized form could be located to test serialization "
|
|
||||||
+ "compatibility: " + exception.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// make sure the canonical form produces the ordering we currently
|
|
||||||
// expect
|
|
||||||
List<T> randomList = getComparableObjectsOrdered();
|
|
||||||
reverseObjects(randomList);
|
|
||||||
sortObjects(randomList, comparator);
|
|
||||||
|
|
||||||
List<T> orderedList = getComparableObjectsOrdered();
|
|
||||||
|
|
||||||
assertTrue("Comparator did not reorder the List correctly",
|
|
||||||
orderedList.equals(randomList));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.commons.lang3.compare;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import junit.framework.Test;
|
|
||||||
import junit.framework.TestSuite;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the NullComparator.
|
|
||||||
*
|
|
||||||
* @version $Revision$ $Date$
|
|
||||||
*
|
|
||||||
* @author Michael A. Smith
|
|
||||||
*/
|
|
||||||
public abstract class AbstractTestNullComparator extends AbstractTestComparator<Integer> {
|
|
||||||
|
|
||||||
public AbstractTestNullComparator(String testName) {
|
|
||||||
super(testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Test suite() {
|
|
||||||
TestSuite suite = new TestSuite(AbstractTestNullComparator.class.getName());
|
|
||||||
suite.addTest(new TestSuite(TestNullComparator1.class));
|
|
||||||
suite.addTest(new TestSuite(TestNullComparator2.class));
|
|
||||||
return suite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the NullComparator with nulls high, using comparable comparator
|
|
||||||
**/
|
|
||||||
public static class TestNullComparator1 extends AbstractTestNullComparator {
|
|
||||||
|
|
||||||
public TestNullComparator1(String testName) {
|
|
||||||
super(testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Comparator<Integer> makeObject() {
|
|
||||||
return new NullComparator<Integer>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Integer> getComparableObjectsOrdered() {
|
|
||||||
List<Integer> list = new LinkedList<Integer>();
|
|
||||||
list.add(new Integer(1));
|
|
||||||
list.add(new Integer(2));
|
|
||||||
list.add(new Integer(3));
|
|
||||||
list.add(new Integer(4));
|
|
||||||
list.add(new Integer(5));
|
|
||||||
list.add(null);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCanonicalComparatorName(Object object) {
|
|
||||||
return super.getCanonicalComparatorName(object) + "1";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the NullComparator with nulls low using the comparable comparator
|
|
||||||
**/
|
|
||||||
public static class TestNullComparator2 extends AbstractTestNullComparator {
|
|
||||||
|
|
||||||
public TestNullComparator2(String testName) {
|
|
||||||
super(testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Comparator<Integer> makeObject() {
|
|
||||||
return new NullComparator<Integer>(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Integer> getComparableObjectsOrdered() {
|
|
||||||
List<Integer> list = new LinkedList<Integer>();
|
|
||||||
list.add(null);
|
|
||||||
list.add(new Integer(1));
|
|
||||||
list.add(new Integer(2));
|
|
||||||
list.add(new Integer(3));
|
|
||||||
list.add(new Integer(4));
|
|
||||||
list.add(new Integer(5));
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCanonicalComparatorName(Object object) {
|
|
||||||
return super.getCanonicalComparatorName(object) + "2";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,334 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.commons.lang3.compare;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract test class for {@link java.lang.Object} methods and contracts.
|
|
||||||
* <p>
|
|
||||||
* To use, simply extend this class, and implement
|
|
||||||
* the {@link #makeObject()} method.
|
|
||||||
* <p>
|
|
||||||
* If your {@link Object} fails one of these tests by design,
|
|
||||||
* you may still use this base set of cases. Simply override the
|
|
||||||
* test case (method) your {@link Object} fails.
|
|
||||||
*
|
|
||||||
* @version $Revision$ $Date$
|
|
||||||
*
|
|
||||||
* @author Rodney Waldhoff
|
|
||||||
* @author Stephen Colebourne
|
|
||||||
* @author Anonymous
|
|
||||||
*/
|
|
||||||
abstract class AbstractTestObject extends BulkTest {
|
|
||||||
|
|
||||||
/** Current major release for Collections */
|
|
||||||
public static final int COLLECTIONS_MAJOR_VERSION = 3;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JUnit constructor.
|
|
||||||
*
|
|
||||||
* @param testName the test class name
|
|
||||||
*/
|
|
||||||
public AbstractTestObject(String testName) {
|
|
||||||
super(testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Implement this method to return the object to test.
|
|
||||||
*
|
|
||||||
* @return the object to test
|
|
||||||
*/
|
|
||||||
public abstract Object makeObject();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override this method if a subclass is testing an object
|
|
||||||
* that cannot serialize an "empty" Collection.
|
|
||||||
* (e.g. Comparators have no contents)
|
|
||||||
*
|
|
||||||
* @return true
|
|
||||||
*/
|
|
||||||
public boolean supportsEmptyCollections() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override this method if a subclass is testing an object
|
|
||||||
* that cannot serialize a "full" Collection.
|
|
||||||
* (e.g. Comparators have no contents)
|
|
||||||
*
|
|
||||||
* @return true
|
|
||||||
*/
|
|
||||||
public boolean supportsFullCollections() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is serialization testing supported.
|
|
||||||
* Default is true.
|
|
||||||
*/
|
|
||||||
public boolean isTestSerialization() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true to indicate that the collection supports equals() comparisons.
|
|
||||||
* This implementation returns true;
|
|
||||||
*/
|
|
||||||
public boolean isEqualsCheckable() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
public void testObjectEqualsSelf() {
|
|
||||||
Object obj = makeObject();
|
|
||||||
assertEquals("A Object should equal itself", obj, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testEqualsNull() {
|
|
||||||
Object obj = makeObject();
|
|
||||||
assertEquals(false, obj.equals(null)); // make sure this doesn't throw NPE either
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testObjectHashCodeEqualsSelfHashCode() {
|
|
||||||
Object obj = makeObject();
|
|
||||||
assertEquals("hashCode should be repeatable", obj.hashCode(), obj.hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testObjectHashCodeEqualsContract() {
|
|
||||||
Object obj1 = makeObject();
|
|
||||||
if (obj1.equals(obj1)) {
|
|
||||||
assertEquals(
|
|
||||||
"[1] When two objects are equal, their hashCodes should be also.",
|
|
||||||
obj1.hashCode(), obj1.hashCode());
|
|
||||||
}
|
|
||||||
Object obj2 = makeObject();
|
|
||||||
if (obj1.equals(obj2)) {
|
|
||||||
assertEquals(
|
|
||||||
"[2] When two objects are equal, their hashCodes should be also.",
|
|
||||||
obj1.hashCode(), obj2.hashCode());
|
|
||||||
assertTrue(
|
|
||||||
"When obj1.equals(obj2) is true, then obj2.equals(obj1) should also be true",
|
|
||||||
obj2.equals(obj1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Object serializeDeserialize(Object obj) throws Exception {
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
||||||
ObjectOutputStream out = new ObjectOutputStream(buffer);
|
|
||||||
out.writeObject(obj);
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
|
|
||||||
Object dest = in.readObject();
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSerializeDeserializeThenCompare() throws Exception {
|
|
||||||
Object obj = makeObject();
|
|
||||||
if (obj instanceof Serializable && isTestSerialization()) {
|
|
||||||
Object dest = serializeDeserialize(obj);
|
|
||||||
if (isEqualsCheckable()) {
|
|
||||||
assertEquals("obj != deserialize(serialize(obj))", obj, dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sanity check method, makes sure that any Serializable
|
|
||||||
* class can be serialized and de-serialized in memory,
|
|
||||||
* using the handy makeObject() method
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public void testSimpleSerialization() throws Exception {
|
|
||||||
Object o = makeObject();
|
|
||||||
if (o instanceof Serializable && isTestSerialization()) {
|
|
||||||
byte[] objekt = writeExternalFormToBytes((Serializable) o);
|
|
||||||
readExternalFormFromBytes(objekt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests serialization by comparing against a previously stored version in SVN.
|
|
||||||
* If the test object is serializable, confirm that a canonical form exists.
|
|
||||||
*/
|
|
||||||
public void testCanonicalEmptyCollectionExists() {
|
|
||||||
if (supportsEmptyCollections() && isTestSerialization() && !skipSerializedCanonicalTests()) {
|
|
||||||
Object object = makeObject();
|
|
||||||
if (object instanceof Serializable) {
|
|
||||||
String name = getCanonicalEmptyCollectionName(object);
|
|
||||||
assertTrue(
|
|
||||||
"Canonical empty collection (" + name + ") is not in SVN",
|
|
||||||
new File(name).exists());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests serialization by comparing against a previously stored version in SVN.
|
|
||||||
* If the test object is serializable, confirm that a canonical form exists.
|
|
||||||
*/
|
|
||||||
public void testCanonicalFullCollectionExists() {
|
|
||||||
if (supportsFullCollections() && isTestSerialization() && !skipSerializedCanonicalTests()) {
|
|
||||||
Object object = makeObject();
|
|
||||||
if (object instanceof Serializable) {
|
|
||||||
String name = getCanonicalFullCollectionName(object);
|
|
||||||
assertTrue(
|
|
||||||
"Canonical full collection (" + name + ") is not in SVN",
|
|
||||||
new File(name).exists());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// protected implementation
|
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Get the version of Collections that this object tries to
|
|
||||||
* maintain serialization compatibility with. Defaults to 1, the
|
|
||||||
* earliest Collections version. (Note: some collections did not
|
|
||||||
* even exist in this version).
|
|
||||||
*
|
|
||||||
* This constant makes it possible for TestMap (and other subclasses,
|
|
||||||
* if necessary) to automatically check SVN for a versionX copy of a
|
|
||||||
* Serialized object, so we can make sure that compatibility is maintained.
|
|
||||||
* See, for example, TestMap.getCanonicalFullMapName(Map map).
|
|
||||||
* Subclasses can override this variable, indicating compatibility
|
|
||||||
* with earlier Collections versions.
|
|
||||||
*
|
|
||||||
* @return The version, or <code>null</code> if this object shouldn't be
|
|
||||||
* tested for compatibility with previous versions.
|
|
||||||
*/
|
|
||||||
public String getCompatibilityVersion() {
|
|
||||||
return "1";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getCanonicalEmptyCollectionName(Object object) {
|
|
||||||
StringBuilder retval = new StringBuilder();
|
|
||||||
retval.append("data/test/");
|
|
||||||
String colName = object.getClass().getName();
|
|
||||||
colName = colName.substring(colName.lastIndexOf(".") + 1, colName.length());
|
|
||||||
retval.append(colName);
|
|
||||||
retval.append(".emptyCollection.version");
|
|
||||||
retval.append(getCompatibilityVersion());
|
|
||||||
retval.append(".obj");
|
|
||||||
return retval.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getCanonicalFullCollectionName(Object object) {
|
|
||||||
StringBuilder retval = new StringBuilder();
|
|
||||||
retval.append("data/test/");
|
|
||||||
String colName = object.getClass().getName();
|
|
||||||
colName = colName.substring(colName.lastIndexOf(".") + 1, colName.length());
|
|
||||||
retval.append(colName);
|
|
||||||
retval.append(".fullCollection.version");
|
|
||||||
retval.append(getCompatibilityVersion());
|
|
||||||
retval.append(".obj");
|
|
||||||
return retval.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a Serializable or Externalizable object as
|
|
||||||
* a file at the given path. NOT USEFUL as part
|
|
||||||
* of a unit test; this is just a utility method
|
|
||||||
* for creating disk-based objects in SVN that can become
|
|
||||||
* the basis for compatibility tests using
|
|
||||||
* readExternalFormFromDisk(String path)
|
|
||||||
*
|
|
||||||
* @param o Object to serialize
|
|
||||||
* @param path path to write the serialized Object
|
|
||||||
* @exception IOException
|
|
||||||
*/
|
|
||||||
protected void writeExternalFormToDisk(Serializable o, String path) throws IOException {
|
|
||||||
FileOutputStream fileStream = new FileOutputStream(path);
|
|
||||||
writeExternalFormToStream(o, fileStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a Serializable or Externalizable object to
|
|
||||||
* bytes. Useful for in-memory tests of serialization
|
|
||||||
*
|
|
||||||
* @param o Object to convert to bytes
|
|
||||||
* @return serialized form of the Object
|
|
||||||
* @exception IOException
|
|
||||||
*/
|
|
||||||
protected byte[] writeExternalFormToBytes(Serializable o) throws IOException {
|
|
||||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
|
||||||
writeExternalFormToStream(o, byteStream);
|
|
||||||
return byteStream.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a Serialized or Externalized Object from disk.
|
|
||||||
* Useful for creating compatibility tests between
|
|
||||||
* different SVN versions of the same class
|
|
||||||
*
|
|
||||||
* @param path path to the serialized Object
|
|
||||||
* @return the Object at the given path
|
|
||||||
* @exception IOException
|
|
||||||
* @exception ClassNotFoundException
|
|
||||||
*/
|
|
||||||
protected Object readExternalFormFromDisk(String path) throws IOException, ClassNotFoundException {
|
|
||||||
FileInputStream stream = new FileInputStream(path);
|
|
||||||
return readExternalFormFromStream(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a Serialized or Externalized Object from bytes.
|
|
||||||
* Useful for verifying serialization in memory.
|
|
||||||
*
|
|
||||||
* @param b byte array containing a serialized Object
|
|
||||||
* @return Object contained in the bytes
|
|
||||||
* @exception IOException
|
|
||||||
* @exception ClassNotFoundException
|
|
||||||
*/
|
|
||||||
protected Object readExternalFormFromBytes(byte[] b) throws IOException, ClassNotFoundException {
|
|
||||||
ByteArrayInputStream stream = new ByteArrayInputStream(b);
|
|
||||||
return readExternalFormFromStream(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean skipSerializedCanonicalTests() {
|
|
||||||
return Boolean.getBoolean("org.apache.commons.lang3:with-clover");
|
|
||||||
}
|
|
||||||
|
|
||||||
// private implementation
|
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
private Object readExternalFormFromStream(InputStream stream) throws IOException, ClassNotFoundException {
|
|
||||||
ObjectInputStream oStream = new ObjectInputStream(stream);
|
|
||||||
return oStream.readObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeExternalFormToStream(Serializable o, OutputStream stream) throws IOException {
|
|
||||||
ObjectOutputStream oStream = new ObjectOutputStream(stream);
|
|
||||||
oStream.writeObject(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,464 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.commons.lang3.compare;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
import junit.framework.TestSuite;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link TestCase} that can define both simple and bulk test methods.
|
|
||||||
* <p>
|
|
||||||
* A <I>simple test method</I> is the type of test traditionally
|
|
||||||
* supplied by by {@link TestCase}. To define a simple test, create a public
|
|
||||||
* no-argument method whose name starts with "test". You can specify the
|
|
||||||
* the name of simple test in the constructor of <code>BulkTest</code>;
|
|
||||||
* a subsequent call to {@link TestCase#run} will run that simple test.
|
|
||||||
* <p>
|
|
||||||
* A <I>bulk test method</I>, on the other hand, returns a new instance
|
|
||||||
* of <code>BulkTest</code>, which can itself define new simple and bulk
|
|
||||||
* test methods. By using the {@link #makeSuite} method, you can
|
|
||||||
* automatically create a hierarchal suite of tests and child bulk tests.
|
|
||||||
* <p>
|
|
||||||
* For instance, consider the following two classes:
|
|
||||||
*
|
|
||||||
* <Pre>
|
|
||||||
* public class TestSet extends BulkTest {
|
|
||||||
*
|
|
||||||
* private Set set;
|
|
||||||
*
|
|
||||||
* public TestSet(Set set) {
|
|
||||||
* this.set = set;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* public void testContains() {
|
|
||||||
* boolean r = set.contains(set.iterator().next()));
|
|
||||||
* assertTrue("Set should contain first element, r);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* public void testClear() {
|
|
||||||
* set.clear();
|
|
||||||
* assertTrue("Set should be empty after clear", set.isEmpty());
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* public class TestHashMap extends BulkTest {
|
|
||||||
*
|
|
||||||
* private Map makeFullMap() {
|
|
||||||
* HashMap result = new HashMap();
|
|
||||||
* result.put("1", "One");
|
|
||||||
* result.put("2", "Two");
|
|
||||||
* return result;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* public void testClear() {
|
|
||||||
* Map map = makeFullMap();
|
|
||||||
* map.clear();
|
|
||||||
* assertTrue("Map empty after clear", map.isEmpty());
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* public BulkTest bulkTestKeySet() {
|
|
||||||
* return new TestSet(makeFullMap().keySet());
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* public BulkTest bulkTestEntrySet() {
|
|
||||||
* return new TestSet(makeFullMap().entrySet());
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* </Pre>
|
|
||||||
*
|
|
||||||
* In the above examples, <code>TestSet</code> defines two
|
|
||||||
* simple test methods and no bulk test methods; <code>TestHashMap</code>
|
|
||||||
* defines one simple test method and two bulk test methods. When
|
|
||||||
* <code>makeSuite(TestHashMap.class).run</code> is executed,
|
|
||||||
* <I>five</I> simple test methods will be run, in this order:<P>
|
|
||||||
*
|
|
||||||
* <Ol>
|
|
||||||
* <Li>TestHashMap.testClear()
|
|
||||||
* <Li>TestHashMap.bulkTestKeySet().testContains();
|
|
||||||
* <Li>TestHashMap.bulkTestKeySet().testClear();
|
|
||||||
* <Li>TestHashMap.bulkTestEntrySet().testContains();
|
|
||||||
* <Li>TestHashMap.bulkTestEntrySet().testClear();
|
|
||||||
* </Ol>
|
|
||||||
*
|
|
||||||
* In the graphical junit test runners, the tests would be displayed in
|
|
||||||
* the following tree:<P>
|
|
||||||
*
|
|
||||||
* <UL>
|
|
||||||
* <LI>TestHashMap</LI>
|
|
||||||
* <UL>
|
|
||||||
* <LI>testClear
|
|
||||||
* <LI>bulkTestKeySet
|
|
||||||
* <UL>
|
|
||||||
* <LI>testContains
|
|
||||||
* <LI>testClear
|
|
||||||
* </UL>
|
|
||||||
* <LI>bulkTestEntrySet
|
|
||||||
* <UL>
|
|
||||||
* <LI>testContains
|
|
||||||
* <LI>testClear
|
|
||||||
* </UL>
|
|
||||||
* </UL>
|
|
||||||
* </UL>
|
|
||||||
*
|
|
||||||
* A subclass can override a superclass's bulk test by
|
|
||||||
* returning <code>null</code> from the bulk test method. If you only
|
|
||||||
* want to override specific simple tests within a bulk test, use the
|
|
||||||
* {@link #ignoredTests} method.<P>
|
|
||||||
*
|
|
||||||
* Note that if you want to use the bulk test methods, you <I>must</I>
|
|
||||||
* define your <code>suite()</code> method to use {@link #makeSuite}.
|
|
||||||
* The ordinary {@link TestSuite} constructor doesn't know how to
|
|
||||||
* interpret bulk test methods.
|
|
||||||
*
|
|
||||||
* @author Paul Jack
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
class BulkTest extends TestCase implements Cloneable {
|
|
||||||
|
|
||||||
|
|
||||||
// Note: BulkTest is Cloneable to make it easier to construct
|
|
||||||
// BulkTest instances for simple test methods that are defined in
|
|
||||||
// anonymous inner classes. Basically we don't have to worry about
|
|
||||||
// finding weird constructors. (And even if we found them, technically
|
|
||||||
// it'd be illegal for anyone but the outer class to invoke them).
|
|
||||||
// Given one BulkTest instance, we can just clone it and reset the
|
|
||||||
// method name for every simple test it defines.
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The full name of this bulk test instance. This is the full name
|
|
||||||
* that is compared to {@link #ignoredTests} to see if this
|
|
||||||
* test should be ignored. It's also displayed in the text runner
|
|
||||||
* to ease debugging.
|
|
||||||
*/
|
|
||||||
String verboseName;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new <code>BulkTest</code> instance that will run the
|
|
||||||
* specified simple test.
|
|
||||||
*
|
|
||||||
* @param name the name of the simple test method to run
|
|
||||||
*/
|
|
||||||
public BulkTest(String name) {
|
|
||||||
super(name);
|
|
||||||
this.verboseName = getClass().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a clone of this <code>BulkTest</code>.<P>
|
|
||||||
*
|
|
||||||
* @return a clone of this <code>BulkTest</code>
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object clone() {
|
|
||||||
try {
|
|
||||||
return super.clone();
|
|
||||||
} catch (CloneNotSupportedException e) {
|
|
||||||
throw new Error(); // should never happen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of test names to ignore.<P>
|
|
||||||
*
|
|
||||||
* If a test that's defined by this <code>BulkTest</code> or
|
|
||||||
* by one of its bulk test methods has a name that's in the returned
|
|
||||||
* array, then that simple test will not be executed.<P>
|
|
||||||
*
|
|
||||||
* A test's name is formed by taking the class name of the
|
|
||||||
* root <code>BulkTest</code>, eliminating the package name, then
|
|
||||||
* appending the names of any bulk test methods that were invoked
|
|
||||||
* to get to the simple test, and then appending the simple test
|
|
||||||
* method name. The method names are delimited by periods:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* TestHashMap.bulkTestEntrySet.testClear
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* is the name of one of the simple tests defined in the sample classes
|
|
||||||
* described above. If the sample <code>TestHashMap</code> class
|
|
||||||
* included this method:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* public String[] ignoredTests() {
|
|
||||||
* return new String[] { "TestHashMap.bulkTestEntrySet.testClear" };
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* then the entry set's clear method wouldn't be tested, but the key
|
|
||||||
* set's clear method would.
|
|
||||||
*
|
|
||||||
* @return an array of the names of tests to ignore, or null if
|
|
||||||
* no tests should be ignored
|
|
||||||
*/
|
|
||||||
public String[] ignoredTests() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the display name of this <code>BulkTest</code>.
|
|
||||||
*
|
|
||||||
* @return the display name of this <code>BulkTest</code>
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getName() + "(" + verboseName + ") ";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a {@link TestSuite} for testing all of the simple tests
|
|
||||||
* <I>and</I> all the bulk tests defined by the given class.<P>
|
|
||||||
*
|
|
||||||
* The class is examined for simple and bulk test methods; any child
|
|
||||||
* bulk tests are also examined recursively; and the results are stored
|
|
||||||
* in a hierarchal {@link TestSuite}.<P>
|
|
||||||
*
|
|
||||||
* The given class must be a subclass of <code>BulkTest</code> and must
|
|
||||||
* not be abstract.<P>
|
|
||||||
*
|
|
||||||
* @param c the class to examine for simple and bulk tests
|
|
||||||
* @return a {@link TestSuite} containing all the simple and bulk tests
|
|
||||||
* defined by that class
|
|
||||||
*/
|
|
||||||
public static TestSuite makeSuite(Class<? extends BulkTest> c) {
|
|
||||||
if (Modifier.isAbstract(c.getModifiers())) {
|
|
||||||
throw new IllegalArgumentException("Class must not be abstract.");
|
|
||||||
}
|
|
||||||
if (!BulkTest.class.isAssignableFrom(c)) {
|
|
||||||
throw new IllegalArgumentException("Class must extend BulkTest.");
|
|
||||||
}
|
|
||||||
return new BulkTestSuiteMaker(c).make();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// It was easier to use a separate class to do all the reflection stuff
|
|
||||||
// for making the TestSuite instances. Having permanent state around makes
|
|
||||||
// it easier to handle the recursion.
|
|
||||||
class BulkTestSuiteMaker {
|
|
||||||
|
|
||||||
/** The class that defines simple and bulk tests methods. */
|
|
||||||
private Class<? extends BulkTest> startingClass;
|
|
||||||
|
|
||||||
/** List of ignored simple test names. */
|
|
||||||
private List<String> ignored;
|
|
||||||
|
|
||||||
/** The TestSuite we're currently populating. Can change over time. */
|
|
||||||
private TestSuite result;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The prefix for simple test methods. Used to check if a test is in
|
|
||||||
* the ignored list.
|
|
||||||
*/
|
|
||||||
private String prefix;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param startingClass the starting class
|
|
||||||
*/
|
|
||||||
public BulkTestSuiteMaker(Class<? extends BulkTest> startingClass) {
|
|
||||||
this.startingClass = startingClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a hierarchal TestSuite based on the starting class.
|
|
||||||
*
|
|
||||||
* @return the hierarchal TestSuite for startingClass
|
|
||||||
*/
|
|
||||||
public TestSuite make() {
|
|
||||||
this.result = new TestSuite();
|
|
||||||
this.prefix = getBaseName(startingClass);
|
|
||||||
result.setName(prefix);
|
|
||||||
|
|
||||||
BulkTest bulk = makeFirstTestCase(startingClass);
|
|
||||||
ignored = new ArrayList<String>();
|
|
||||||
String[] s = bulk.ignoredTests();
|
|
||||||
if (s != null) {
|
|
||||||
ignored.addAll(Arrays.asList(s));
|
|
||||||
}
|
|
||||||
make(bulk);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Appends all the simple tests and bulk tests defined by the given
|
|
||||||
* instance's class to the current TestSuite.
|
|
||||||
*
|
|
||||||
* @param bulk An instance of the class that defines simple and bulk
|
|
||||||
* tests for us to append
|
|
||||||
*/
|
|
||||||
void make(BulkTest bulk) {
|
|
||||||
Class<? extends BulkTest> c = bulk.getClass();
|
|
||||||
Method[] all = c.getMethods();
|
|
||||||
for (int i = 0; i < all.length; i++) {
|
|
||||||
if (isTest(all[i])) addTest(bulk, all[i]);
|
|
||||||
if (isBulk(all[i])) addBulk(bulk, all[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the simple test defined by the given method to the TestSuite.
|
|
||||||
*
|
|
||||||
* @param bulk The instance of the class that defined the method
|
|
||||||
* (I know it's weird. But the point is, we can clone the instance
|
|
||||||
* and not have to worry about constructors.)
|
|
||||||
* @param m The simple test method
|
|
||||||
*/
|
|
||||||
void addTest(BulkTest bulk, Method m) {
|
|
||||||
BulkTest bulk2 = (BulkTest)bulk.clone();
|
|
||||||
bulk2.setName(m.getName());
|
|
||||||
bulk2.verboseName = prefix + "." + m.getName();
|
|
||||||
if (ignored.contains(bulk2.verboseName)) return;
|
|
||||||
result.addTest(bulk2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a whole new suite of tests that are defined by the result of
|
|
||||||
* the given bulk test method. In other words, the given bulk test
|
|
||||||
* method is invoked, and the resulting BulkTest instance is examined
|
|
||||||
* for yet more simple and bulk tests.
|
|
||||||
*
|
|
||||||
* @param bulk The instance of the class that defined the method
|
|
||||||
* @param m The bulk test method
|
|
||||||
*/
|
|
||||||
void addBulk(BulkTest bulk, Method m) {
|
|
||||||
String verboseName = prefix + "." + m.getName();
|
|
||||||
if (ignored.contains(verboseName)) return;
|
|
||||||
|
|
||||||
BulkTest bulk2;
|
|
||||||
try {
|
|
||||||
bulk2 = (BulkTest)m.invoke(bulk, (Object[]) null);
|
|
||||||
if (bulk2 == null) return;
|
|
||||||
} catch (InvocationTargetException ex) {
|
|
||||||
ex.getTargetException().printStackTrace();
|
|
||||||
throw new Error(); // FIXME;
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
throw new Error(); // FIXME;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save current state on the stack.
|
|
||||||
String oldPrefix = prefix;
|
|
||||||
TestSuite oldResult = result;
|
|
||||||
|
|
||||||
prefix = prefix + "." + m.getName();
|
|
||||||
result = new TestSuite();
|
|
||||||
result.setName(m.getName());
|
|
||||||
|
|
||||||
make(bulk2);
|
|
||||||
|
|
||||||
oldResult.addTest(result);
|
|
||||||
|
|
||||||
// Restore the old state
|
|
||||||
prefix = oldPrefix;
|
|
||||||
result = oldResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the base name of the given class.
|
|
||||||
*
|
|
||||||
* @param c the class
|
|
||||||
* @return the name of that class, minus any package names
|
|
||||||
*/
|
|
||||||
private static String getBaseName(Class<?> c) {
|
|
||||||
String name = c.getName();
|
|
||||||
int p = name.lastIndexOf('.');
|
|
||||||
if (p > 0) {
|
|
||||||
name = name.substring(p + 1);
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// These three methods are used to create a valid BulkTest instance
|
|
||||||
// from a class.
|
|
||||||
|
|
||||||
private static <T> Constructor<T> getTestCaseConstructor(Class<T> c) {
|
|
||||||
try {
|
|
||||||
return c.getConstructor(new Class[] { String.class });
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new IllegalArgumentException(c + " must provide " +
|
|
||||||
"a (String) constructor");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T extends BulkTest> BulkTest makeTestCase(Class<T> c, Method m) {
|
|
||||||
Constructor<T> con = getTestCaseConstructor(c);
|
|
||||||
try {
|
|
||||||
return con.newInstance(new Object[] { m.getName() });
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new RuntimeException(); // FIXME;
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new Error(); // should never occur
|
|
||||||
} catch (InstantiationException e) {
|
|
||||||
throw new RuntimeException(); // FIXME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T extends BulkTest> BulkTest makeFirstTestCase(Class<T> c) {
|
|
||||||
Method[] all = c.getMethods();
|
|
||||||
for (int i = 0; i < all.length; i++) {
|
|
||||||
if (isTest(all[i])) return makeTestCase(c, all[i]);
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException(c.getName() + " must provide "
|
|
||||||
+ " at least one test method.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given method is a simple test method.
|
|
||||||
*/
|
|
||||||
private static boolean isTest(Method m) {
|
|
||||||
if (!m.getName().startsWith("test")) return false;
|
|
||||||
if (m.getReturnType() != Void.TYPE) return false;
|
|
||||||
if (m.getParameterTypes().length != 0) return false;
|
|
||||||
int mods = m.getModifiers();
|
|
||||||
if (Modifier.isStatic(mods)) return false;
|
|
||||||
if (Modifier.isAbstract(mods)) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given method is a bulk test method.
|
|
||||||
*/
|
|
||||||
private static boolean isBulk(Method m) {
|
|
||||||
if (!m.getName().startsWith("bulkTest")) return false;
|
|
||||||
if (m.getReturnType() != BulkTest.class) return false;
|
|
||||||
if (m.getParameterTypes().length != 0) return false;
|
|
||||||
int mods = m.getModifiers();
|
|
||||||
if (Modifier.isStatic(mods)) return false;
|
|
||||||
if (Modifier.isAbstract(mods)) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.commons.lang3.compare;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for ComparableComparator.
|
|
||||||
*
|
|
||||||
* @version $Revision$ $Date$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("boxing")
|
|
||||||
public class TestComparableComparator extends AbstractTestComparator<Integer> {
|
|
||||||
|
|
||||||
public TestComparableComparator(String testName) {
|
|
||||||
super(testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Comparator<Integer> makeObject() {
|
|
||||||
return new ComparableComparator<Integer>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Integer> getComparableObjectsOrdered() {
|
|
||||||
List<Integer> list = new LinkedList<Integer>();
|
|
||||||
list.add(1);
|
|
||||||
list.add(2);
|
|
||||||
list.add(3);
|
|
||||||
list.add(4);
|
|
||||||
list.add(5);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,211 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.commons.lang3.compare;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for ComparatorChain.
|
|
||||||
*
|
|
||||||
* @version $Revision$ $Date$
|
|
||||||
*
|
|
||||||
* @author Unknown
|
|
||||||
*/
|
|
||||||
public class TestComparatorChain extends AbstractTestComparator<TestComparatorChain.PseudoRow> {
|
|
||||||
|
|
||||||
public TestComparatorChain(String testName) {
|
|
||||||
super(testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Comparator<PseudoRow> makeObject() {
|
|
||||||
ComparatorChain<PseudoRow> chain = new ComparatorChain<PseudoRow>(new ColumnComparator(0));
|
|
||||||
chain.addComparator(new ColumnComparator(1), true); // reverse the second column
|
|
||||||
chain.addComparator(new ColumnComparator(2), false);
|
|
||||||
return chain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNoopComparatorChain() {
|
|
||||||
ComparatorChain<Integer> chain = new ComparatorChain<Integer>();
|
|
||||||
Integer i1 = new Integer(4);
|
|
||||||
Integer i2 = new Integer(6);
|
|
||||||
chain.addComparator(new ComparableComparator<Integer>());
|
|
||||||
|
|
||||||
int correctValue = i1.compareTo(i2);
|
|
||||||
assertTrue("Comparison returns the right order", chain.compare(i1, i2) == correctValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testBadNoopComparatorChain() {
|
|
||||||
ComparatorChain<Integer> chain = new ComparatorChain<Integer>();
|
|
||||||
Integer i1 = new Integer(4);
|
|
||||||
Integer i2 = new Integer(6);
|
|
||||||
try {
|
|
||||||
chain.compare(i1,i2);
|
|
||||||
fail("An exception should be thrown when a chain contains zero comparators.");
|
|
||||||
} catch (UnsupportedOperationException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListComparatorChain() {
|
|
||||||
List<Comparator<Integer>> list = new LinkedList<Comparator<Integer>>();
|
|
||||||
list.add(new ComparableComparator<Integer>());
|
|
||||||
ComparatorChain<Integer> chain = new ComparatorChain<Integer>(list);
|
|
||||||
Integer i1 = new Integer(4);
|
|
||||||
Integer i2 = new Integer(6);
|
|
||||||
|
|
||||||
int correctValue = i1.compareTo(i2);
|
|
||||||
assertTrue("Comparison returns the right order", chain.compare(i1, i2) == correctValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testBadListComparatorChain() {
|
|
||||||
List<Comparator<Integer>> list = new LinkedList<Comparator<Integer>>();
|
|
||||||
ComparatorChain<Integer> chain = new ComparatorChain<Integer>(list);
|
|
||||||
Integer i1 = new Integer(4);
|
|
||||||
Integer i2 = new Integer(6);
|
|
||||||
try {
|
|
||||||
chain.compare(i1, i2);
|
|
||||||
fail("An exception should be thrown when a chain contains zero comparators.");
|
|
||||||
} catch (UnsupportedOperationException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testComparatorChainOnMinvaluedCompatator() {
|
|
||||||
// -1 * Integer.MIN_VALUE is less than 0,
|
|
||||||
// test that ComparatorChain handles this edge case correctly
|
|
||||||
ComparatorChain<Integer> chain = new ComparatorChain<Integer>();
|
|
||||||
chain.addComparator(new Comparator<Integer>() {
|
|
||||||
public int compare(Integer a, Integer b) {
|
|
||||||
int result = a.compareTo(b);
|
|
||||||
if (result < 0) {
|
|
||||||
return Integer.MIN_VALUE;
|
|
||||||
}
|
|
||||||
if (result > 0) {
|
|
||||||
return Integer.MAX_VALUE;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
assertTrue(chain.compare(new Integer(4), new Integer(5)) > 0);
|
|
||||||
assertTrue(chain.compare(new Integer(5), new Integer(4)) < 0);
|
|
||||||
assertTrue(chain.compare(new Integer(4), new Integer(4)) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<PseudoRow> getComparableObjectsOrdered() {
|
|
||||||
List<PseudoRow> list = new LinkedList<PseudoRow>();
|
|
||||||
// this is the correct order assuming a
|
|
||||||
// "0th forward, 1st reverse, 2nd forward" sort
|
|
||||||
list.add(new PseudoRow(1, 2, 3));
|
|
||||||
list.add(new PseudoRow(2, 3, 5));
|
|
||||||
list.add(new PseudoRow(2, 2, 4));
|
|
||||||
list.add(new PseudoRow(2, 2, 8));
|
|
||||||
list.add(new PseudoRow(3, 1, 0));
|
|
||||||
list.add(new PseudoRow(4, 4, 4));
|
|
||||||
list.add(new PseudoRow(4, 4, 7));
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public static class PseudoRow implements Serializable {
|
|
||||||
|
|
||||||
public int cols[] = new int[3];
|
|
||||||
|
|
||||||
public PseudoRow(int col1, int col2, int col3) {
|
|
||||||
cols[0] = col1;
|
|
||||||
cols[1] = col2;
|
|
||||||
cols[2] = col3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColumn(int colIndex) {
|
|
||||||
return cols[colIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
buf.append("[");
|
|
||||||
buf.append(cols[0]);
|
|
||||||
buf.append(",");
|
|
||||||
buf.append(cols[1]);
|
|
||||||
buf.append(",");
|
|
||||||
buf.append(cols[2]);
|
|
||||||
buf.append("]");
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (!(o instanceof PseudoRow)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PseudoRow row = (PseudoRow) o;
|
|
||||||
if (getColumn(0) != row.getColumn(0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getColumn(1) != row.getColumn(1)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getColumn(2) != row.getColumn(2)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ColumnComparator implements Comparator<PseudoRow>, Serializable {
|
|
||||||
private static final long serialVersionUID = -2284880866328872105L;
|
|
||||||
|
|
||||||
protected int colIndex = 0;
|
|
||||||
|
|
||||||
public ColumnComparator(int colIndex) {
|
|
||||||
this.colIndex = colIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compare(PseudoRow o1, PseudoRow o2) {
|
|
||||||
|
|
||||||
int col1 = o1.getColumn(colIndex);
|
|
||||||
int col2 = o2.getColumn(colIndex);
|
|
||||||
|
|
||||||
if (col1 > col2) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (col1 < col2) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return colIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object that) {
|
|
||||||
return that instanceof ColumnComparator && colIndex == ((ColumnComparator) that).colIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,225 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.commons.lang3.compare;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test class for FixedOrderComparator.
|
|
||||||
*
|
|
||||||
* @version $Revision$ $Date$
|
|
||||||
*
|
|
||||||
* @author David Leppik
|
|
||||||
* @author Stephen Colebourne
|
|
||||||
*/
|
|
||||||
public class TestFixedOrderComparator extends TestCase {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Top cities of the world, by population including metro areas.
|
|
||||||
*/
|
|
||||||
private static final String topCities[] = new String[] {
|
|
||||||
"Tokyo",
|
|
||||||
"Mexico City",
|
|
||||||
"Mumbai",
|
|
||||||
"Sao Paulo",
|
|
||||||
"New York",
|
|
||||||
"Shanghai",
|
|
||||||
"Lagos",
|
|
||||||
"Los Angeles",
|
|
||||||
"Calcutta",
|
|
||||||
"Buenos Aires"
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialization and busywork
|
|
||||||
//
|
|
||||||
|
|
||||||
public TestFixedOrderComparator(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set up and tear down
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// The tests
|
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests that the constructor plus add method compares items properly.
|
|
||||||
*/
|
|
||||||
public void testConstructorPlusAdd() {
|
|
||||||
FixedOrderComparator<String> comparator = new FixedOrderComparator<String>();
|
|
||||||
for (int i = 0; i < topCities.length; i++) {
|
|
||||||
comparator.add(topCities[i]);
|
|
||||||
}
|
|
||||||
String[] keys = topCities.clone();
|
|
||||||
assertComparatorYieldsOrder(keys, comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests that the array constructor compares items properly.
|
|
||||||
*/
|
|
||||||
public void testArrayConstructor() {
|
|
||||||
String[] keys = topCities.clone();
|
|
||||||
String[] topCitiesForTest = topCities.clone();
|
|
||||||
FixedOrderComparator<String> comparator = new FixedOrderComparator<String>(topCitiesForTest);
|
|
||||||
assertComparatorYieldsOrder(keys, comparator);
|
|
||||||
// test that changing input after constructor has no effect
|
|
||||||
topCitiesForTest[0] = "Brighton";
|
|
||||||
assertComparatorYieldsOrder(keys, comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the list constructor.
|
|
||||||
*/
|
|
||||||
public void testListConstructor() {
|
|
||||||
String[] keys = topCities.clone();
|
|
||||||
List<String> topCitiesForTest = new LinkedList<String>(Arrays.asList(topCities));
|
|
||||||
FixedOrderComparator<String> comparator = new FixedOrderComparator<String>(topCitiesForTest);
|
|
||||||
assertComparatorYieldsOrder(keys, comparator);
|
|
||||||
// test that changing input after constructor has no effect
|
|
||||||
topCitiesForTest.set(0, "Brighton");
|
|
||||||
assertComparatorYieldsOrder(keys, comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests addAsEqual method.
|
|
||||||
*/
|
|
||||||
public void testAddAsEqual() {
|
|
||||||
FixedOrderComparator<String> comparator = new FixedOrderComparator<String>(topCities);
|
|
||||||
comparator.addAsEqual("New York", "Minneapolis");
|
|
||||||
assertEquals(0, comparator.compare("New York", "Minneapolis"));
|
|
||||||
assertEquals(-1, comparator.compare("Tokyo", "Minneapolis"));
|
|
||||||
assertEquals(1, comparator.compare("Shanghai", "Minneapolis"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests whether or not updates are disabled after a comparison is made.
|
|
||||||
*/
|
|
||||||
public void testLock() {
|
|
||||||
FixedOrderComparator<String> comparator = new FixedOrderComparator<String>(topCities);
|
|
||||||
assertEquals(false, comparator.isLocked());
|
|
||||||
comparator.compare("New York", "Tokyo");
|
|
||||||
assertEquals(true, comparator.isLocked());
|
|
||||||
try {
|
|
||||||
comparator.add("Minneapolis");
|
|
||||||
fail("Should have thrown an UnsupportedOperationException");
|
|
||||||
} catch (UnsupportedOperationException e) {
|
|
||||||
// success -- ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
comparator.addAsEqual("New York", "Minneapolis");
|
|
||||||
fail("Should have thrown an UnsupportedOperationException");
|
|
||||||
} catch (UnsupportedOperationException e) {
|
|
||||||
// success -- ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testUnknownObjectBehavior() {
|
|
||||||
FixedOrderComparator<String> comparator = new FixedOrderComparator<String>(topCities);
|
|
||||||
try {
|
|
||||||
comparator.compare("New York", "Minneapolis");
|
|
||||||
fail("Should have thrown a IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// success-- ignore
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
comparator.compare("Minneapolis", "New York");
|
|
||||||
fail("Should have thrown a IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// success-- ignore
|
|
||||||
}
|
|
||||||
assertEquals(FixedOrderComparator.UnknownObjectBehavior.EXCEPTION, comparator.getUnknownObjectBehavior());
|
|
||||||
|
|
||||||
comparator = new FixedOrderComparator<String>(topCities);
|
|
||||||
comparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
|
|
||||||
assertEquals(FixedOrderComparator.UnknownObjectBehavior.BEFORE, comparator.getUnknownObjectBehavior());
|
|
||||||
LinkedList<String> keys = new LinkedList<String>(Arrays.asList(topCities));
|
|
||||||
keys.addFirst("Minneapolis");
|
|
||||||
assertComparatorYieldsOrder(keys.toArray(new String[0]), comparator);
|
|
||||||
|
|
||||||
assertEquals(-1, comparator.compare("Minneapolis", "New York"));
|
|
||||||
assertEquals( 1, comparator.compare("New York", "Minneapolis"));
|
|
||||||
assertEquals( 0, comparator.compare("Minneapolis", "St Paul"));
|
|
||||||
|
|
||||||
comparator = new FixedOrderComparator<String>(topCities);
|
|
||||||
comparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.AFTER);
|
|
||||||
keys = new LinkedList<String>(Arrays.asList(topCities));
|
|
||||||
keys.add("Minneapolis");
|
|
||||||
assertComparatorYieldsOrder(keys.toArray(new String[0]), comparator);
|
|
||||||
|
|
||||||
assertEquals( 1, comparator.compare("Minneapolis", "New York"));
|
|
||||||
assertEquals(-1, comparator.compare("New York", "Minneapolis"));
|
|
||||||
assertEquals( 0, comparator.compare("Minneapolis", "St Paul"));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Helper methods
|
|
||||||
//
|
|
||||||
|
|
||||||
/** Shuffles the keys and asserts that the comparator sorts them back to
|
|
||||||
* their original order.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private void assertComparatorYieldsOrder(String[] orderedObjects,
|
|
||||||
Comparator<String> comparator) {
|
|
||||||
String[] keys = orderedObjects.clone();
|
|
||||||
|
|
||||||
// shuffle until the order changes. It's extremely rare that
|
|
||||||
// this requires more than one shuffle.
|
|
||||||
|
|
||||||
boolean isInNewOrder = false;
|
|
||||||
Random rand = new Random();
|
|
||||||
while (keys.length > 1 && isInNewOrder == false) {
|
|
||||||
// shuffle:
|
|
||||||
for (int i = keys.length-1; i > 0; i--) {
|
|
||||||
String swap = keys[i];
|
|
||||||
int j = rand.nextInt(i+1);
|
|
||||||
keys[i] = keys[j];
|
|
||||||
keys[j] = swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// testShuffle
|
|
||||||
for (int i = 0; i < keys.length && !isInNewOrder; i++) {
|
|
||||||
if( !orderedObjects[i].equals(keys[i])) {
|
|
||||||
isInNewOrder = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The real test: sort and make sure they come out right.
|
|
||||||
|
|
||||||
Arrays.sort(keys, comparator);
|
|
||||||
|
|
||||||
for (int i = 0; i < orderedObjects.length; i++) {
|
|
||||||
assertEquals(orderedObjects[i], keys[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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 org.apache.commons.lang3.compare;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for ReverseComparator.
|
|
||||||
*
|
|
||||||
* @version $Revision$ $Date$
|
|
||||||
*
|
|
||||||
* @author Unknown
|
|
||||||
*/
|
|
||||||
public class TestReverseComparator extends AbstractTestComparator<Integer> {
|
|
||||||
|
|
||||||
public TestReverseComparator(String testName) {
|
|
||||||
super(testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For the purposes of this test, return a
|
|
||||||
* ReverseComparator that wraps the java.util.Collections.reverseOrder()
|
|
||||||
* Comparator. The resulting comparator should
|
|
||||||
* sort according to natural Order. (Note: we wrap
|
|
||||||
* a Comparator taken from the JDK so that we can
|
|
||||||
* save a "canonical" form in SVN.
|
|
||||||
*
|
|
||||||
* @return Comparator that returns "natural" order
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Comparator<Integer> makeObject() {
|
|
||||||
return new ReverseComparator<Integer>(Collections.<Integer>reverseOrder());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Integer> getComparableObjectsOrdered() {
|
|
||||||
List<Integer> list = new LinkedList<Integer>();
|
|
||||||
list.add(new Integer(1));
|
|
||||||
list.add(new Integer(2));
|
|
||||||
list.add(new Integer(3));
|
|
||||||
list.add(new Integer(4));
|
|
||||||
list.add(new Integer(5));
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override this inherited test since Collections.reverseOrder
|
|
||||||
* doesn't adhere to the "soft" Comparator contract, and we've
|
|
||||||
* already "cannonized" the comparator returned by makeComparator.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testSerializeDeserializeThenCompare() throws Exception {
|
|
||||||
Comparator comp = new ReverseComparator(new ComparableComparator());
|
|
||||||
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
||||||
ObjectOutputStream out = new ObjectOutputStream(buffer);
|
|
||||||
out.writeObject(comp);
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
|
|
||||||
Object dest = in.readObject();
|
|
||||||
in.close();
|
|
||||||
assertEquals("obj != deserialize(serialize(obj))",comp,dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue