Refactor tests to allow more flexibility in subclasses
For Apache Commons BeanUtils bean map tests
This commit is contained in:
parent
a685fae36f
commit
08b4cdb884
|
@ -40,6 +40,7 @@ import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.apache.commons.collections4.AbstractObjectTest;
|
import org.apache.commons.collections4.AbstractObjectTest;
|
||||||
|
@ -598,6 +599,17 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
return new TestMapValues();
|
return new TestMapValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses can override for special cases, like Apache Commons BeanUtils.
|
||||||
|
*
|
||||||
|
* @param key See @{link {@link Map#computeIfAbsent(Object, Function)}.
|
||||||
|
* @param mappingFunction See @{link {@link Map#computeIfAbsent(Object, Function)}.
|
||||||
|
* @return See @{link {@link Map#computeIfAbsent(Object, Function)}.
|
||||||
|
*/
|
||||||
|
protected V computeIfAbsent(final K key, final Function<? super K, ? extends V> mappingFunction) {
|
||||||
|
return getMap().computeIfAbsent(key, mappingFunction);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <E> List<E> getAsList(final Object[] o) {
|
protected <E> List<E> getAsList(final Object[] o) {
|
||||||
final ArrayList<E> result = new ArrayList<>();
|
final ArrayList<E> result = new ArrayList<>();
|
||||||
|
@ -787,15 +799,15 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isLazyMapTest() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// tests begin here. Each test adds a little bit of tested functionality.
|
// tests begin here. Each test adds a little bit of tested functionality.
|
||||||
// Many methods assume previous methods passed. That is, they do not
|
// Many methods assume previous methods passed. That is, they do not
|
||||||
// exhaustively recheck things that have already been checked in a previous
|
// exhaustively recheck things that have already been checked in a previous
|
||||||
// test methods.
|
// test methods.
|
||||||
|
|
||||||
|
protected boolean isLazyMapTest() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the maps produced by {@link #makeObject()} and {@link #makeFullMap()} support the {@link Map#put(Object, Object)} and
|
* Returns true if the maps produced by {@link #makeObject()} and {@link #makeFullMap()} support the {@link Map#put(Object, Object)} and
|
||||||
* {@link Map#putAll(Map)} operations adding new mappings.
|
* {@link Map#putAll(Map)} operations adding new mappings.
|
||||||
|
@ -914,6 +926,17 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
@Override
|
@Override
|
||||||
public abstract M makeObject();
|
public abstract M makeObject();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses can override for special cases, like Apache Commons BeanUtils.
|
||||||
|
*
|
||||||
|
* @param key See @{link {@link Map#putIfAbsent(Object, Object)}.
|
||||||
|
* @param value See @{link {@link Map#putIfAbsent(Object, Object)}.
|
||||||
|
* @return See @{link {@link Map#putIfAbsent(Object, Object)}.
|
||||||
|
*/
|
||||||
|
protected V putIfAbsent(final K key, final V value) {
|
||||||
|
return getMap().putIfAbsent(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the {@link #map}, {@link #entrySet}, {@link #keySet}, {@link #values} and {@link #confirmed} fields to empty.
|
* Resets the {@link #map}, {@link #entrySet}, {@link #keySet}, {@link #values} and {@link #confirmed} fields to empty.
|
||||||
*/
|
*/
|
||||||
|
@ -1403,7 +1426,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
final V value = values[i];
|
final V value = values[i];
|
||||||
final boolean expectKey = key != null && value != null || key == null && !getMap().containsKey(key);
|
final boolean expectKey = key != null && value != null || key == null && !getMap().containsKey(key);
|
||||||
final Map<K, V> oldMap = new HashMap<>(getMap());
|
final Map<K, V> oldMap = new HashMap<>(getMap());
|
||||||
final Object currValue = getMap().computeIfAbsent(key, k -> value);
|
final Object currValue = computeIfAbsent(key, k -> value);
|
||||||
// map is updated if new value is not null
|
// map is updated if new value is not null
|
||||||
getConfirmed().computeIfAbsent(key, k -> value);
|
getConfirmed().computeIfAbsent(key, k -> value);
|
||||||
if (!isLazyMapTest()) {
|
if (!isLazyMapTest()) {
|
||||||
|
@ -1431,7 +1454,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
final boolean valueAlreadyPresent = getMap().containsValue(value);
|
final boolean valueAlreadyPresent = getMap().containsValue(value);
|
||||||
final V prevValue = getMap().get(key);
|
final V prevValue = getMap().get(key);
|
||||||
final Map<K, V> oldMap = new HashMap<>(getMap());
|
final Map<K, V> oldMap = new HashMap<>(getMap());
|
||||||
final Object computedValue = getMap().computeIfAbsent(key, k -> value);
|
final Object computedValue = computeIfAbsent(key, k -> value);
|
||||||
getConfirmed().computeIfAbsent(key, k -> value);
|
getConfirmed().computeIfAbsent(key, k -> value);
|
||||||
if (!isLazyMapTest()) {
|
if (!isLazyMapTest()) {
|
||||||
// TODO LazyMap tests do not like this check
|
// TODO LazyMap tests do not like this check
|
||||||
|
@ -1471,7 +1494,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
// two possible exception here, either valid
|
// two possible exception here, either valid
|
||||||
getMap().computeIfAbsent(keys[0], k -> newValues[0]);
|
computeIfAbsent(keys[0], k -> newValues[0]);
|
||||||
fail("Expected IllegalArgumentException or UnsupportedOperationException on putIfAbsent (change)");
|
fail("Expected IllegalArgumentException or UnsupportedOperationException on putIfAbsent (change)");
|
||||||
} catch (final IllegalArgumentException | UnsupportedOperationException ex) {
|
} catch (final IllegalArgumentException | UnsupportedOperationException ex) {
|
||||||
// ignore
|
// ignore
|
||||||
|
@ -1480,7 +1503,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
} else if (isPutChangeSupported()) {
|
} else if (isPutChangeSupported()) {
|
||||||
resetEmpty();
|
resetEmpty();
|
||||||
try {
|
try {
|
||||||
getMap().computeIfAbsent(keys[0], k -> values[0]);
|
computeIfAbsent(keys[0], k -> values[0]);
|
||||||
fail("Expected UnsupportedOperationException or IllegalArgumentException on putIfAbsent (add) when fixed size");
|
fail("Expected UnsupportedOperationException or IllegalArgumentException on putIfAbsent (add) when fixed size");
|
||||||
} catch (final IllegalArgumentException | UnsupportedOperationException ex) {
|
} catch (final IllegalArgumentException | UnsupportedOperationException ex) {
|
||||||
// ignore
|
// ignore
|
||||||
|
@ -1656,14 +1679,12 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (getMap().containsKey(keys[0])) {
|
||||||
|
assertThrows(UnsupportedOperationException.class, () -> getMap().computeIfPresent(keys[0], (k, v) -> values[0]),
|
||||||
|
"Expected UnsupportedOperationException on put (add)");
|
||||||
} else {
|
} else {
|
||||||
if (getMap().containsKey(keys[0])) {
|
// doesn't throw
|
||||||
assertThrows(UnsupportedOperationException.class, () -> getMap().computeIfPresent(keys[0], (k, v) -> values[0]),
|
getMap().computeIfPresent(keys[0], (k, v) -> values[0]);
|
||||||
"Expected UnsupportedOperationException on put (add)");
|
|
||||||
} else {
|
|
||||||
// doesn't throw
|
|
||||||
getMap().computeIfPresent(keys[0], (k, v) -> values[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1981,7 +2002,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
for (int i = 0; i < keys.length; i++) {
|
for (int i = 0; i < keys.length; i++) {
|
||||||
final K key = keys[i];
|
final K key = keys[i];
|
||||||
final V value = values[i];
|
final V value = values[i];
|
||||||
final Object o = getMap().putIfAbsent(key, value);
|
final Object o = putIfAbsent(key, value);
|
||||||
getConfirmed().putIfAbsent(key, value);
|
getConfirmed().putIfAbsent(key, value);
|
||||||
verify();
|
verify();
|
||||||
assertNull(o, "First map.putIfAbsent should return null");
|
assertNull(o, "First map.putIfAbsent should return null");
|
||||||
|
@ -1995,7 +2016,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
final V newValue = newValues[i];
|
final V newValue = newValues[i];
|
||||||
final boolean newValueAlready = getMap().containsValue(newValue);
|
final boolean newValueAlready = getMap().containsValue(newValue);
|
||||||
final V prevValue = getMap().get(key);
|
final V prevValue = getMap().get(key);
|
||||||
final Object oldValue = getMap().putIfAbsent(key, newValue);
|
final Object oldValue = putIfAbsent(key, newValue);
|
||||||
getConfirmed().putIfAbsent(key, newValue);
|
getConfirmed().putIfAbsent(key, newValue);
|
||||||
verify();
|
verify();
|
||||||
final V arrValue = values[i];
|
final V arrValue = values[i];
|
||||||
|
@ -2023,7 +2044,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
// two possible exception here, either valid
|
// two possible exception here, either valid
|
||||||
getMap().putIfAbsent(keys[0], newValues[0]);
|
putIfAbsent(keys[0], newValues[0]);
|
||||||
fail("Expected IllegalArgumentException or UnsupportedOperationException on putIfAbsent (change)");
|
fail("Expected IllegalArgumentException or UnsupportedOperationException on putIfAbsent (change)");
|
||||||
} catch (final IllegalArgumentException | UnsupportedOperationException ex) {
|
} catch (final IllegalArgumentException | UnsupportedOperationException ex) {
|
||||||
// ignore
|
// ignore
|
||||||
|
@ -2031,11 +2052,21 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
}
|
}
|
||||||
} else if (isPutChangeSupported()) {
|
} else if (isPutChangeSupported()) {
|
||||||
resetEmpty();
|
resetEmpty();
|
||||||
try {
|
final K key0 = keys[0];
|
||||||
getMap().putIfAbsent(keys[0], values[0]);
|
final V value0 = values[0];
|
||||||
fail("Expected UnsupportedOperationException or IllegalArgumentException on putIfAbsent (add) when fixed size");
|
if (getMap().containsKey(key0)) {
|
||||||
} catch (final IllegalArgumentException | UnsupportedOperationException ex) {
|
// don't throw
|
||||||
// ignore
|
assertEquals(getMap().get(key0), putIfAbsent(key0, value0));
|
||||||
|
} else if (isPutAddSupported()) {
|
||||||
|
putIfAbsent(key0, value0);
|
||||||
|
} else {
|
||||||
|
// throw (fixed size for example)
|
||||||
|
try {
|
||||||
|
putIfAbsent(key0, value0);
|
||||||
|
fail("Expected UnsupportedOperationException or IllegalArgumentException on putIfAbsent (add) when fixed size");
|
||||||
|
} catch (final IllegalArgumentException | UnsupportedOperationException ex) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
resetFull();
|
resetFull();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -2044,7 +2075,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
final V newValue = newValues[i];
|
final V newValue = newValues[i];
|
||||||
final boolean newValueAlready = getMap().containsValue(newValue);
|
final boolean newValueAlready = getMap().containsValue(newValue);
|
||||||
final V prevValue = getMap().get(key);
|
final V prevValue = getMap().get(key);
|
||||||
final V oldValue = getMap().putIfAbsent(key, newValue);
|
final V oldValue = putIfAbsent(key, newValue);
|
||||||
final V value = getConfirmed().putIfAbsent(key, newValue);
|
final V value = getConfirmed().putIfAbsent(key, newValue);
|
||||||
verify();
|
verify();
|
||||||
assertEquals(value, oldValue, "Map.putIfAbsent should return previous value when changed");
|
assertEquals(value, oldValue, "Map.putIfAbsent should return previous value when changed");
|
||||||
|
@ -2067,8 +2098,7 @@ public abstract class AbstractMapTest<M extends Map<K, V>, K, V> extends Abstrac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assertThrows(UnsupportedOperationException.class, () -> getMap().putIfAbsent(keys[0], values[0]),
|
assertThrows(UnsupportedOperationException.class, () -> putIfAbsent(keys[0], values[0]), "Expected UnsupportedOperationException on put (add)");
|
||||||
"Expected UnsupportedOperationException on put (add)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue