📄 testmap.java
字号:
/*
* Copyright 1999-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;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Tests base {@link java.util.Map} methods and contracts.
* <p>
* The forces at work here are similar to those in {@link TestCollection}.
* 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 implemenation is wierd, 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 #useDuplicateValues()}
* <LI> {@link #useNullKey()}
* <LI> {@link #useNullValue()}
* <LI> {@link #isAddRemoveModifiable()}
* <LI> {@link #isChangeable()}
* </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, {@link 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 {@link
* 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 #useDuplicateValues()} and have it return <code>false</code>
*
* @author Michael Smith
* @author Rodney Waldhoff
* @author Paul Jack
* @version $Id: TestMap.java,v 1.20.2.1 2004/05/22 12:14:05 scolebourne Exp $
*/
public abstract class TestMap extends TestObject {
// 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;
public TestMap(String testName) {
super(testName);
}
/**
* Override if your map does not allow a <code>null</code> key. The
* default implementation returns <code>true</code>
**/
protected boolean useNullKey() {
return true;
}
/**
* Override if your map does not allow <code>null</code> values. The
* default implementation returns <code>true</code>.
**/
protected boolean useNullValue() {
return true;
}
/**
* Override if your map does not allow duplicate values. The default
* implementation returns <code>true</code>.
**/
protected boolean useDuplicateValues() {
return true;
}
/**
* Override if your map allows its mappings to be changed to new values.
* The default implementation returns <code>true</code>.
**/
protected boolean isChangeable() {
return true;
}
/**
* Override if your map does not allow add/remove modifications. The
* default implementation returns <code>true</code>.
**/
protected boolean isAddRemoveModifiable() {
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 #useNullKey()} returns <code>true</code>.
**/
protected Object[] getSampleKeys() {
Object[] result = new Object[] {
"blah", "foo", "bar", "baz", "tmp", "gosh", "golly", "gee",
"hello", "goodbye", "we'll", "see", "you", "all", "again",
"key",
"key2",
(useNullKey()) ? null : "nonnullkey"
};
return result;
}
protected Object[] getOtherKeys() {
return TestCollection.getOtherNonNullStringElements();
}
protected Object[] getOtherValues() {
return TestCollection.getOtherNonNullStringElements();
}
/**
* 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 contructs a set of
* String values and includes a single null value if {@link
* #useNullValue()} returns <code>true</code>, and includes two values
* that are the same if {@link #useDuplicateValues()} returns
* <code>true</code>.
**/
protected Object[] getSampleValues() {
Object[] result = new Object[] {
"blahv", "foov", "barv", "bazv", "tmpv", "goshv", "gollyv", "geev",
"hellov", "goodbyev", "we'llv", "seev", "youv", "allv", "againv",
(useNullValue()) ? null : "nonnullvalue",
"value",
(useDuplicateValues()) ? "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
* array with the same length as {@link #getSampleValues()}. The values
* returned from this method should not be the same as those returned from
* {@link #getSampleValues()}. The default implementation constructs a
* set of String values and includes a single null value if {@link
* #useNullValue()} returns <code>true</code>, and includes two values
* that are the same if {@link #useDuplicateValues()} returns
* <code>true</code>.
**/
protected Object[] getNewSampleValues() {
Object[] result = new Object[] {
(useNullValue()) ? null : "newnonnullvalue",
"newvalue",
(useDuplicateValues()) ? "newvalue" : "newvalue2",
"newblahv", "newfoov", "newbarv", "newbazv", "newtmpv", "newgoshv",
"newgollyv", "newgeev", "newhellov", "newgoodbyev", "newwe'llv",
"newseev", "newyouv", "newallv", "newagainv",
};
return result;
}
/**
* Helper method to add all the mappings described by {@link
* #getSampleKeys()} and {@link #getSampleValues()}.
**/
protected void addSampleMappings(Map m) {
Object[] keys = getSampleKeys();
Object[] values = getSampleValues();
for(int i = 0; i < keys.length; i++) {
try {
m.put(keys[i], values[i]);
} catch (NullPointerException exception) {
assertTrue("NullPointerException only allowed to be thrown " +
"if either the key or value is null.",
keys[i] == null || values[i] == null);
assertTrue("NullPointerException on null key, but " +
"useNullKey is not overridden to return false.",
keys[i] == null || !useNullKey());
assertTrue("NullPointerException on null value, but " +
"useNullValue is not overridden to return false.",
values[i] == null || !useNullValue());
assertTrue("Unknown reason for NullPointer.", false);
}
}
assertEquals("size must reflect number of mappings added.",
keys.length, m.size());
}
/**
* Return a new, empty {@link Map} to be used for testing.
*/
protected abstract Map makeEmptyMap();
/**
* Return a new, populated map. The mappings in the map should match the
* keys and values returned from {@link #getSampleKeys()} and {@link
* #getSampleValues()}. The default implementation uses makeEmptyMap()
* and calls {@link #addSampleMappings()} to add all the mappings to the
* map.
**/
protected Map makeFullMap() {
Map m = makeEmptyMap();
addSampleMappings(m);
return m;
}
public Object makeObject() {
return makeEmptyMap();
}
/**
* Test to ensure the test setup is working properly. This method checks
* to ensure that the getSampleKeys and getSampleValues methods are
* returning results that look appropriate. That is, they both return a
* non-null array of equal length. The keys array must not have any
* duplicate values, and may only contain a (single) null key if
* useNullKey() returns true. The values array must only have a null
* value if useNullValue() is true and may only have duplicate values if
* useDuplicateValues() returns true.
**/
public void testSampleMappings() {
Object[] keys = getSampleKeys();
Object[] values = getSampleValues();
Object[] newValues = getNewSampleValues();
assertTrue("failure in test: Must have keys returned from " +
"getSampleKeys.", keys != null);
assertTrue("failure in test: Must have values returned from " +
"getSampleValues.", values != null);
// verify keys and values have equivalent lengths (in case getSampleX are
// overridden)
assertEquals("failure in test: not the same number of sample " +
"keys and values.", keys.length, values.length);
assertEquals("failure in test: not the same number of values and new values.",
values.length, newValues.length);
// verify there aren't duplicate keys, and check values
for(int i = 0; i < keys.length - 1; i++) {
for(int j = i + 1; j < keys.length; j++) {
assertTrue("failure in test: duplicate null keys.",
(keys[i] != null || keys[j] != null));
assertTrue("failure in test: duplicate non-null key.",
(keys[i] == null || keys[j] == null ||
(!keys[i].equals(keys[j]) &&
!keys[j].equals(keys[i]))));
}
assertTrue("failure in test: found null key, but useNullKey " +
"is false.", keys[i] != null || useNullKey());
assertTrue("failure in test: found null value, but useNullValue " +
"is false.", values[i] != null || useNullValue());
assertTrue("failure in test: found null new value, but useNullValue " +
"is false.", newValues[i] != null || useNullValue());
assertTrue("failure in test: values should not be the same as new value",
values[i] != newValues[i] &&
(values[i] == null || !values[i].equals(newValues[i])));
}
}
// tests begin here. Each test adds a little bit of tested functionality.
// Many methods assume previous methods passed. That is, they do not
// exhaustively recheck things that have already been checked in a previous
// test methods.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -