📄 abstracttestmap.java
字号:
/*
* Copyright 2001-2004 The Apache Software Foundation
*
* 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 org.apache.commons.collections.map;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.AbstractTestObject;
import org.apache.commons.collections.BulkTest;
import org.apache.commons.collections.collection.AbstractTestCollection;
import org.apache.commons.collections.set.AbstractTestSet;
/**
* Abstract test class for {@link java.util.Map} methods and contracts.
* <p>
* The forces at work here are similar to those in {@link AbstractTestCollection}.
* If your class implements the full Map interface, including optional
* operations, simply extend this class, and implement the
* {@link #makeEmptyMap()} method.
* <p>
* On the other hand, if your map implementation is weird, you may have to
* override one or more of the other protected methods. They're described
* below.
* <p>
* <b>Entry Population Methods</b>
* <p>
* Override these methods if your map requires special entries:
*
* <ul>
* <li>{@link #getSampleKeys()}
* <li>{@link #getSampleValues()}
* <li>{@link #getNewSampleValues()}
* <li>{@link #getOtherKeys()}
* <li>{@link #getOtherValues()}
* </ul>
*
* <b>Supported Operation Methods</b>
* <p>
* Override these methods if your map doesn't support certain operations:
*
* <ul>
* <li> {@link #isPutAddSupported()}
* <li> {@link #isPutChangeSupported()}
* <li> {@link #isSetValueSupported()}
* <li> {@link #isRemoveSupported()}
* <li> {@link #isGetStructuralModify()}
* <li> {@link #isAllowDuplicateValues()}
* <li> {@link #isAllowNullKey()}
* <li> {@link #isAllowNullValue()}
* </ul>
*
* <b>Fixture Methods</b>
* <p>
* For tests on modification operations (puts and removes), fixtures are used
* to verify that that operation results in correct state for the map and its
* collection views. Basically, the modification is performed against your
* map implementation, and an identical modification is performed against
* a <I>confirmed</I> map implementation. A confirmed map implementation is
* something like <Code>java.util.HashMap</Code>, which is known to conform
* exactly to the {@link Map} contract. After the modification takes place
* on both your map implementation and the confirmed map implementation, the
* two maps are compared to see if their state is identical. The comparison
* also compares the collection views to make sure they're still the same.<P>
*
* The upshot of all that is that <I>any</I> test that modifies the map in
* <I>any</I> way will verify that <I>all</I> of the map's state is still
* correct, including the state of its collection views. So for instance
* if a key is removed by the map's key set's iterator, then the entry set
* is checked to make sure the key/value pair no longer appears.<P>
*
* The {@link #map} field holds an instance of your collection implementation.
* The {@link #entrySet}, {@link #keySet} and {@link #values} fields hold
* that map's collection views. And the {@link #confirmed} field holds
* an instance of the confirmed collection implementation. The
* {@link #resetEmpty()} and {@link #resetFull()} methods set these fields to
* empty or full maps, so that tests can proceed from a known state.<P>
*
* After a modification operation to both {@link #map} and {@link #confirmed},
* the {@link #verify()} method is invoked to compare the results. The
* {@link #verify} method calls separate methods to verify the map and its three
* collection views ({@link #verifyMap}, {@link #verifyEntrySet},
* {@link #verifyKeySet}, and {@link #verifyValues}). You may want to override
* one of the verification methodsto perform additional verifications. For
* instance, TestDoubleOrderedMap would want override its
* {@link #verifyValues()} method to verify that the values are unique and in
* ascending order.<P>
*
* <b>Other Notes</b>
* <p>
* If your {@link Map} fails one of these tests by design, you may still use
* this base set of cases. Simply override the test case (method) your map
* fails and/or the methods that define the assumptions used by the test
* cases. For example, if your map does not allow duplicate values, override
* {@link #isAllowDuplicateValues()} and have it return <code>false</code>
*
* @author Michael Smith
* @author Rodney Waldhoff
* @author Paul Jack
* @author Stephen Colebourne
* @version $Revision: 169097 $ $Date: 2005-05-07 18:13:40 +0100 (Sat, 07 May 2005) $
*/
public abstract class AbstractTestMap extends AbstractTestObject {
/**
* JDK1.2 has bugs in null handling of Maps, especially HashMap.Entry.toString
* This avoids nulls for JDK1.2
*/
private static final boolean JDK12;
static {
String str = System.getProperty("java.version");
JDK12 = str.startsWith("1.2");
}
// These instance variables are initialized with the reset method.
// Tests for map methods that alter the map (put, putAll, remove)
// first call reset() to create the map and its views; then perform
// the modification on the map; perform the same modification on the
// confirmed; and then call verify() to ensure that the map is equal
// to the confirmed, that the already-constructed collection views
// are still equal to the confirmed's collection views.
/** Map created by reset(). */
protected Map map;
/** Entry set of map created by reset(). */
protected Set entrySet;
/** Key set of map created by reset(). */
protected Set keySet;
/** Values collection of map created by reset(). */
protected Collection values;
/** HashMap created by reset(). */
protected Map confirmed;
/**
* JUnit constructor.
*
* @param testName the test name
*/
public AbstractTestMap(String testName) {
super(testName);
}
/**
* Returns true if the maps produced by
* {@link #makeEmptyMap()} and {@link #makeFullMap()}
* support the <code>put</code> and <code>putAll</code> operations
* adding new mappings.
* <p>
* Default implementation returns true.
* Override if your collection class does not support put adding.
*/
public boolean isPutAddSupported() {
return true;
}
/**
* Returns true if the maps produced by
* {@link #makeEmptyMap()} and {@link #makeFullMap()}
* support the <code>put</code> and <code>putAll</code> operations
* changing existing mappings.
* <p>
* Default implementation returns true.
* Override if your collection class does not support put changing.
*/
public boolean isPutChangeSupported() {
return true;
}
/**
* Returns true if the maps produced by
* {@link #makeEmptyMap()} and {@link #makeFullMap()}
* support the <code>setValue</code> operation on entrySet entries.
* <p>
* Default implementation returns isPutChangeSupported().
* Override if your collection class does not support setValue but does
* support put changing.
*/
public boolean isSetValueSupported() {
return isPutChangeSupported();
}
/**
* Returns true if the maps produced by
* {@link #makeEmptyMap()} and {@link #makeFullMap()}
* support the <code>remove</code> and <code>clear</code> operations.
* <p>
* Default implementation returns true.
* Override if your collection class does not support removal operations.
*/
public boolean isRemoveSupported() {
return true;
}
/**
* Returns true if the maps produced by
* {@link #makeEmptyMap()} and {@link #makeFullMap()}
* can cause structural modification on a get(). The example is LRUMap.
* <p>
* Default implementation returns false.
* Override if your map class structurally modifies on get.
*/
public boolean isGetStructuralModify() {
return false;
}
/**
* Returns whether the sub map views of SortedMap are serializable.
* If the class being tested is based around a TreeMap then you should
* override and return false as TreeMap has a bug in deserialization.
*
* @return false
*/
public boolean isSubMapViewsSerializable() {
return true;
}
/**
* Returns true if the maps produced by
* {@link #makeEmptyMap()} and {@link #makeFullMap()}
* supports null keys.
* <p>
* Default implementation returns true.
* Override if your collection class does not support null keys.
*/
public boolean isAllowNullKey() {
return true;
}
/**
* Returns true if the maps produced by
* {@link #makeEmptyMap()} and {@link #makeFullMap()}
* supports null values.
* <p>
* Default implementation returns true.
* Override if your collection class does not support null values.
*/
public boolean isAllowNullValue() {
return true;
}
/**
* Returns true if the maps produced by
* {@link #makeEmptyMap()} and {@link #makeFullMap()}
* supports duplicate values.
* <p>
* Default implementation returns true.
* Override if your collection class does not support duplicate values.
*/
public boolean isAllowDuplicateValues() {
return true;
}
/**
* Returns the set of keys in the mappings used to test the map. This
* method must return an array with the same length as {@link
* #getSampleValues()} and all array elements must be different. The
* default implementation constructs a set of String keys, and includes a
* single null key if {@link #isAllowNullKey()} returns <code>true</code>.
*/
public Object[] getSampleKeys() {
Object[] result = new Object[] {
"blah", "foo", "bar", "baz", "tmp", "gosh", "golly", "gee",
"hello", "goodbye", "we'll", "see", "you", "all", "again",
"key",
"key2",
(isAllowNullKey() && !JDK12) ? null : "nonnullkey"
};
return result;
}
public Object[] getOtherKeys() {
return getOtherNonNullStringElements();
}
public Object[] getOtherValues() {
return getOtherNonNullStringElements();
}
/**
* Returns a list of string elements suitable for return by
* {@link #getOtherKeys()} or {@link #getOtherValues}.
*
* <p>Override getOtherElements to returnthe results of this method if your
* collection does not support heterogenous elements or the null element.
* </p>
*/
public Object[] getOtherNonNullStringElements() {
return new Object[] {
"For","then","despite",/* of */"space","I","would","be","brought",
"From","limits","far","remote","where","thou","dost","stay"
};
}
/**
* Returns the set of values in the mappings used to test the map. This
* method must return an array with the same length as
* {@link #getSampleKeys()}. The default implementation constructs a set of
* String values and includes a single null value if
* {@link #isAllowNullValue()} returns <code>true</code>, and includes
* two values that are the same if {@link #isAllowDuplicateValues()} returns
* <code>true</code>.
*/
public Object[] getSampleValues() {
Object[] result = new Object[] {
"blahv", "foov", "barv", "bazv", "tmpv", "goshv", "gollyv", "geev",
"hellov", "goodbyev", "we'llv", "seev", "youv", "allv", "againv",
(isAllowNullValue() && !JDK12) ? null : "nonnullvalue",
"value",
(isAllowDuplicateValues()) ? "value" : "value2",
};
return result;
}
/**
* Returns a the set of values that can be used to replace the values
* returned from {@link #getSampleValues()}. This method must return an
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -