diff --git a/common/common-lang/src/test/java/com/twelvemonkeys/util/MapAbstractTestCase.java b/common/common-lang/src/test/java/com/twelvemonkeys/util/MapAbstractTestCase.java index d0acb17b..3b54c3cb 100755 --- a/common/common-lang/src/test/java/com/twelvemonkeys/util/MapAbstractTestCase.java +++ b/common/common-lang/src/test/java/com/twelvemonkeys/util/MapAbstractTestCase.java @@ -20,20 +20,20 @@ import java.util.*; /** * Abstract test class for {@link java.util.Map} methods and contracts. - *

+ *

* The forces at work here are similar to those in {@link CollectionAbstractTestCase}. * If your class implements the full Map interface, including optional * operations, simply extend this class, and implement the * {@link #makeEmptyMap()} method. - *

+ *

* 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. - *

+ *

* Entry Population Methods - *

+ *

* Override these methods if your map requires special entries: - * + *

*

- * + *

* Supported Operation Methods - *

+ *

* Override these methods if your map doesn't support certain operations: - * + *

*

- * + *

* Fixture Methods - *

+ *

* 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 @@ -69,20 +69,20 @@ import java.util.*; * 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.

- * + *

* The upshot of all that is that any test that modifies the map in * any way will verify that all 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.

- * + *

* 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.

- * + *

* After a modification operation to both {@link #map} and {@link #confirmed}, * the {@link #verifyAll()} method is invoked to compare the results. The * {@link # verify0} method calls separate methods to verify the map and its three @@ -92,9 +92,9 @@ import java.util.*; * instance, TestDoubleOrderedMap would want override its * {@link #verifyValues()} method to verify that the values are unique and in * ascending order.

- * + *

* Other Notes - *

+ *

* 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 @@ -153,7 +153,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * {@link #makeEmptyMap()} and {@link #makeFullMap()} * support the {@code put} and {@code putAll} operations * adding new mappings. - *

+ *

* Default implementation returns true. * Override if your collection class does not support put adding. */ @@ -166,7 +166,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * {@link #makeEmptyMap()} and {@link #makeFullMap()} * support the {@code put} and {@code putAll} operations * changing existing mappings. - *

+ *

* Default implementation returns true. * Override if your collection class does not support put changing. */ @@ -178,7 +178,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * Returns true if the maps produced by * {@link #makeEmptyMap()} and {@link #makeFullMap()} * support the {@code setValue} operation on entrySet entries. - *

+ *

* Default implementation returns isPutChangeSupported(). * Override if your collection class does not support setValue but does * support put changing. @@ -191,7 +191,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * Returns true if the maps produced by * {@link #makeEmptyMap()} and {@link #makeFullMap()} * support the {@code remove} and {@code clear} operations. - *

+ *

* Default implementation returns true. * Override if your collection class does not support removal operations. */ @@ -203,7 +203,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * Returns true if the maps produced by * {@link #makeEmptyMap()} and {@link #makeFullMap()} * can cause structural modification on a get(). The example is LRUMap. - *

+ *

* Default implementation returns false. * Override if your map class structurally modifies on get. */ @@ -226,7 +226,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * Returns true if the maps produced by * {@link #makeEmptyMap()} and {@link #makeFullMap()} * supports null keys. - *

+ *

* Default implementation returns true. * Override if your collection class does not support null keys. */ @@ -238,7 +238,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * Returns true if the maps produced by * {@link #makeEmptyMap()} and {@link #makeFullMap()} * supports null values. - *

+ *

* Default implementation returns true. * Override if your collection class does not support null values. */ @@ -250,7 +250,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * Returns true if the maps produced by * {@link #makeEmptyMap()} and {@link #makeFullMap()} * supports duplicate values. - *

+ *

* Default implementation returns true. * Override if your collection class does not support duplicate values. */ @@ -259,24 +259,23 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { } /** - * 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}. + * 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}. */ 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" + "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(); } @@ -288,15 +287,15 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { /** * Returns a list of string elements suitable for return by * {@link #getOtherKeys()} or {@link #getOtherValues}. - * + *

*

Override getOtherElements to returnthe results of this method if your * collection does not support heterogenous elements or the null element. *

*/ public Object[] getOtherNonNullStringElements() { return new Object[] { - "For","then","despite",/* of */"space","I","would","be","brought", - "From","limits","far","remote","where","thou","dost","stay" + "For", "then", "despite",/* of */"space", "I", "would", "be", "brought", + "From", "limits", "far", "remote", "where", "thou", "dost", "stay" }; } @@ -311,11 +310,11 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { */ 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", + "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; } @@ -333,18 +332,18 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { */ public Object[] getNewSampleValues() { Object[] result = new Object[] { - (isAllowNullValue() && !JDK12 && isAllowDuplicateValues()) ? null : "newnonnullvalue", - "newvalue", - (isAllowDuplicateValues()) ? "newvalue" : "newvalue2", - "newblahv", "newfoov", "newbarv", "newbazv", "newtmpv", "newgoshv", - "newgollyv", "newgeev", "newhellov", "newgoodbyev", "newwe'llv", - "newseev", "newyouv", "newallv", "newagainv", + (isAllowNullValue() && !JDK12 && isAllowDuplicateValues()) ? null : "newnonnullvalue", + "newvalue", + (isAllowDuplicateValues()) ? "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 + * Helper method to add all the mappings described by * {@link #getSampleKeys()} and {@link #getSampleValues()}. */ public void addSampleMappings(Map m) { @@ -352,30 +351,28 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { Object[] keys = getSampleKeys(); Object[] values = getSampleValues(); - for(int i = 0; i < keys.length; i++) { + 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); + } + 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 " + - "isAllowNullKey is not overridden to return false.", - keys[i] == null || !isAllowNullKey()); + assertTrue("NullPointerException on null key, but isAllowNullKey is not overridden to return false.", + keys[i] == null || !isAllowNullKey()); - assertTrue("NullPointerException on null value, but " + - "isAllowNullValue is not overridden to return false.", - values[i] == null || !isAllowNullValue()); + assertTrue("NullPointerException on null value, but isAllowNullValue is not overridden to return false.", + values[i] == null || !isAllowNullValue()); assertTrue("Unknown reason for NullPointer.", false); } } - assertEquals("size must reflect number of mappings added.", - keys.length, m.size()); + assertEquals("size must reflect number of mappings added.", keys.length, m.size()); } //----------------------------------------------------------------------- + /** * Return a new, empty {@link Map} to be used for testing. * @@ -431,7 +428,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { public String getCompatibilityVersion() { return super.getCompatibilityVersion(); } + //----------------------------------------------------------------------- + /** * Test to ensure the test setup is working properly. This method checks * to ensure that the getSampleKeys and getSampleValues methods are @@ -443,45 +442,32 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * isAllowDuplicateValues() returns true. */ public void testSampleMappings() { - Object[] keys = getSampleKeys(); - Object[] values = getSampleValues(); - Object[] newValues = getNewSampleValues(); + 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 keys returned from getSampleKeys.", keys != null); + assertTrue("failure in test: Must have values returned from getSampleValues.", values != 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 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); + // 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])))); + } - - 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 isNullKeySupported " + - "is false.", keys[i] != null || isAllowNullKey()); - assertTrue("failure in test: found null value, but isNullValueSupported " + - "is false.", values[i] != null || isAllowNullValue()); - assertTrue("failure in test: found null new value, but isNullValueSupported " + - "is false.", newValues[i] != null || isAllowNullValue()); - 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]))); - } + assertTrue("failure in test: found null key, but isNullKeySupported is false.", keys[i] != null || isAllowNullKey()); + assertTrue("failure in test: found null value, but isNullValueSupported is false.", values[i] != null || isAllowNullValue()); + assertTrue("failure in test: found null new value, but isNullValueSupported is false.", newValues[i] != null || isAllowNullValue()); + 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. @@ -495,26 +481,18 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { */ public void testMakeMap() { Map em = makeEmptyMap(); - assertTrue("failure in test: makeEmptyMap must return a non-null map.", - em != null); + assertTrue("failure in test: makeEmptyMap must return a non-null map.", em != null); Map em2 = makeEmptyMap(); - assertTrue("failure in test: makeEmptyMap must return a non-null map.", - em != null); - - assertTrue("failure in test: makeEmptyMap must return a new map " + - "with each invocation.", em != em2); + assertTrue("failure in test: makeEmptyMap must return a non-null map.", em2 != null); + assertTrue("failure in test: makeEmptyMap must return a new map with each invocation.", em != em2); Map fm = makeFullMap(); - assertTrue("failure in test: makeFullMap must return a non-null map.", - fm != null); + assertTrue("failure in test: makeFullMap must return a non-null map.", fm != null); Map fm2 = makeFullMap(); - assertTrue("failure in test: makeFullMap must return a non-null map.", - fm != null); - - assertTrue("failure in test: makeFullMap must return a new map " + - "with each invocation.", fm != fm2); + assertTrue("failure in test: makeFullMap must return a non-null map.", fm2 != null); + assertTrue("failure in test: makeFullMap must return a new map with each invocation.", fm != fm2); } /** @@ -522,13 +500,11 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { */ public void testMapIsEmpty() { resetEmpty(); - assertEquals("Map.isEmpty() should return true with an empty map", - true, map.isEmpty()); + assertEquals("Map.isEmpty() should return true with an empty map", true, map.isEmpty()); verifyAll(); resetFull(); - assertEquals("Map.isEmpty() should return false with a non-empty map", - false, map.isEmpty()); + assertEquals("Map.isEmpty() should return false with a non-empty map", false, map.isEmpty()); verifyAll(); } @@ -537,13 +513,11 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { */ public void testMapSize() { resetEmpty(); - assertEquals("Map.size() should be 0 with an empty map", - 0, map.size()); + assertEquals("Map.size() should be 0 with an empty map", 0, map.size()); verifyAll(); resetFull(); - assertEquals("Map.size() should equal the number of entries " + - "in the map", getSampleKeys().length, map.size()); + assertEquals("Map.size() should equal the number of entries in the map", getSampleKeys().length, map.size()); verifyAll(); } @@ -561,7 +535,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { resetFull(); map.clear(); fail("Expected UnsupportedOperationException on clear"); - } catch (UnsupportedOperationException ex) {} + } + catch (UnsupportedOperationException ex) { + } return; } @@ -576,7 +552,6 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { verifyAll(); } - /** * Tests Map.containsKey(Object) by verifying it returns false for all * sample keys on a map created using an empty map and returns true for @@ -586,16 +561,14 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { Object[] keys = getSampleKeys(); resetEmpty(); - for(int i = 0; i < keys.length; i++) { - assertTrue("Map must not contain key when map is empty", - !map.containsKey(keys[i])); + for (Object key : keys) { + assertTrue("Map must not contain key when map is empty", !map.containsKey(key)); } verifyAll(); resetFull(); - for(int i = 0; i < keys.length; i++) { - assertTrue("Map must contain key for a mapping in the map. " + - "Missing: " + keys[i], map.containsKey(keys[i])); + for (Object key : keys) { + assertTrue("Map must contain key for a mapping in the map. Missing: " + key, map.containsKey(key)); } verifyAll(); } @@ -609,21 +582,18 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { Object[] values = getSampleValues(); resetEmpty(); - for(int i = 0; i < values.length; i++) { - assertTrue("Empty map must not contain value", - !map.containsValue(values[i])); + for (Object value : values) { + assertTrue("Empty map must not contain value", !map.containsValue(value)); } verifyAll(); resetFull(); - for(int i = 0; i < values.length; i++) { - assertTrue("Map must contain value for a mapping in the map.", - map.containsValue(values[i])); + for (Object value : values) { + assertTrue("Map must contain value for a mapping in the map.", map.containsValue(value)); } verifyAll(); } - /** * Tests Map.equals(Object) */ @@ -646,12 +616,10 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { resetFull(); assertTrue("equals(null) returned true.", !map.equals(null)); - assertTrue("equals(new Object()) returned true.", - !map.equals(new Object())); + assertTrue("equals(new Object()) returned true.", !map.equals(new Object())); verifyAll(); } - /** * Tests Map.get(Object) */ @@ -661,16 +629,15 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { Object[] keys = getSampleKeys(); Object[] values = getSampleValues(); - for (int i = 0; i < keys.length; i++) { - assertTrue("Empty map.get() should return null.", - map.get(keys[i]) == null); + for (Object key : keys) { + assertTrue("Empty map.get() should return null.", map.get(key) == null); } + verifyAll(); resetFull(); for (int i = 0; i < keys.length; i++) { - assertEquals("Full map.get() should return value from mapping.", - values[i], map.get(keys[i])); + assertEquals("Full map.get() should return value from mapping.", values[i], map.get(keys[i])); } } @@ -679,12 +646,10 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { */ public void testMapHashCode() { resetEmpty(); - assertTrue("Empty maps have different hashCodes.", - map.hashCode() == confirmed.hashCode()); + assertTrue("Empty maps have different hashCodes.", map.hashCode() == confirmed.hashCode()); resetFull(); - assertTrue("Equal maps have different hashCodes.", - map.hashCode() == confirmed.hashCode()); + assertTrue("Equal maps have different hashCodes.", map.hashCode() == confirmed.hashCode()); } /** @@ -698,17 +663,14 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { */ public void testMapToString() { resetEmpty(); - assertTrue("Empty map toString() should not return null", - map.toString() != null); + assertTrue("Empty map toString() should not return null", map.toString() != null); verifyAll(); resetFull(); - assertTrue("Empty map toString() should not return null", - map.toString() != null); + assertTrue("Empty map toString() should not return null", map.toString() != null); verifyAll(); } - /** * Compare the current serialized form of the Map * against the canonical version in CVS. @@ -737,13 +699,13 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * against the canonical version in CVS. */ //public void testFullMapCompatibility() throws Exception { - /** - * Create canonical objects with this code - Map map = makeFullMap(); - if (!(map instanceof Serializable)) return; + /** + * Create canonical objects with this code + Map map = makeFullMap(); + if (!(map instanceof Serializable)) return; - writeExternalFormToDisk((Serializable) map, getCanonicalFullCollectionName(map)); - */ + writeExternalFormToDisk((Serializable) map, getCanonicalFullCollectionName(map)); + */ /* // test to make sure the canonical form has been preserved Map map = makeFullMap(); @@ -769,9 +731,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { verifyAll(); assertTrue("First map.put should return null", o == null); assertTrue("Map should contain key after put", - map.containsKey(keys[i])); + map.containsKey(keys[i])); assertTrue("Map should contain value after put", - map.containsValue(values[i])); + map.containsValue(values[i])); } if (isPutChangeSupported()) { for (int i = 0; i < keys.length; i++) { @@ -779,35 +741,41 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { confirmed.put(keys[i], newValues[i]); verifyAll(); assertEquals("Map.put should return previous value when changed", - values[i], o); + values[i], o); assertTrue("Map should still contain key after put when changed", - map.containsKey(keys[i])); + map.containsKey(keys[i])); assertTrue("Map should contain new value after put when changed", - map.containsValue(newValues[i])); + map.containsValue(newValues[i])); // if duplicates are allowed, we're not guaranteed that the value // no longer exists, so don't try checking that. if (!isAllowDuplicateValues()) { assertTrue("Map should not contain old value after put when changed", - !map.containsValue(values[i])); + !map.containsValue(values[i])); } } - } else { + } + else { try { // two possible exception here, either valid map.put(keys[0], newValues[0]); fail("Expected IllegalArgumentException or UnsupportedOperationException on put (change)"); - } catch (IllegalArgumentException ex) { - } catch (UnsupportedOperationException ex) {} + } + catch (IllegalArgumentException ex) { + } + catch (UnsupportedOperationException ex) { + } } - - } else if (isPutChangeSupported()) { + } + else if (isPutChangeSupported()) { resetEmpty(); try { map.put(keys[0], values[0]); fail("Expected UnsupportedOperationException or IllegalArgumentException on put (add) when fixed size"); - } catch (IllegalArgumentException ex) { - } catch (UnsupportedOperationException ex) { + } + catch (IllegalArgumentException ex) { + } + catch (UnsupportedOperationException ex) { } resetFull(); @@ -818,24 +786,27 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { Object value = confirmed.put(key, newValues[i]); verifyAll(); assertEquals("Map.put should return previous value when changed", - value, o); + value, o); assertTrue("Map should still contain key after put when changed", - map.containsKey(key)); + map.containsKey(key)); assertTrue("Map should contain new value after put when changed", - map.containsValue(newValues[i])); + map.containsValue(newValues[i])); // if duplicates are allowed, we're not guaranteed that the value // no longer exists, so don't try checking that. if (!isAllowDuplicateValues()) { assertTrue("Map should not contain old value after put when changed", - !map.containsValue(values[i])); + !map.containsValue(values[i])); } } - } else { + } + else { try { map.put(keys[0], values[0]); fail("Expected UnsupportedOperationException on put (add)"); - } catch (UnsupportedOperationException ex) {} + } + catch (UnsupportedOperationException ex) { + } } } @@ -849,12 +820,16 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { if (isPutAddSupported()) { if (isAllowNullKey()) { map.put(null, values[0]); - } else { + } + else { try { map.put(null, values[0]); fail("put(null, value) should throw NPE/IAE"); - } catch (NullPointerException ex) { - } catch (IllegalArgumentException ex) {} + } + catch (NullPointerException ex) { + } + catch (IllegalArgumentException ex) { + } } } } @@ -869,12 +844,16 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { if (isPutAddSupported()) { if (isAllowNullValue()) { map.put(keys[0], null); - } else { + } + else { try { map.put(keys[0], null); fail("put(key, null) should throw NPE/IAE"); - } catch (NullPointerException ex) { - } catch (IllegalArgumentException ex) {} + } + catch (NullPointerException ex) { + } + catch (IllegalArgumentException ex) { + } } } } @@ -890,7 +869,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { try { map.putAll(temp); fail("Expected UnsupportedOperationException on putAll"); - } catch (UnsupportedOperationException ex) {} + } + catch (UnsupportedOperationException ex) { + } } return; } @@ -908,7 +889,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { m2 = makeConfirmedMap(); Object[] keys = getSampleKeys(); Object[] values = getSampleValues(); - for(int i = 0; i < keys.length; i++) { + for (int i = 0; i < keys.length; i++) { m2.put(keys[i], values[i]); } @@ -926,7 +907,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { resetFull(); map.remove(map.keySet().iterator().next()); fail("Expected UnsupportedOperationException on remove"); - } catch (UnsupportedOperationException ex) {} + } + catch (UnsupportedOperationException ex) { + } return; } @@ -934,7 +917,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { Object[] keys = getSampleKeys(); Object[] values = getSampleValues(); - for(int i = 0; i < keys.length; i++) { + for (int i = 0; i < keys.length; i++) { Object o = map.remove(keys[i]); assertTrue("First map.remove should return null", o == null); } @@ -942,13 +925,13 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { resetFull(); - for(int i = 0; i < keys.length; i++) { + for (int i = 0; i < keys.length; i++) { Object o = map.remove(keys[i]); confirmed.remove(keys[i]); verifyAll(); assertEquals("map.remove with valid key should return value", - values[i], o); + values[i], o); } Object[] other = getOtherKeys(); @@ -958,20 +941,23 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { for (int i = 0; i < other.length; i++) { Object o = map.remove(other[i]); assertEquals("map.remove for nonexistent key should return null", - o, null); + o, null); assertEquals("map.remove for nonexistent key should not " + - "shrink map", size, map.size()); + "shrink map", size, map.size()); } verifyAll(); } //----------------------------------------------------------------------- + /** * Tests that the {@link Map#values} collection is backed by * the underlying map for clear(). */ public void testValuesClearChangesMap() { - if (!isRemoveSupported()) return; + if (!isRemoveSupported()) { + return; + } // clear values, reflected in map resetFull(); @@ -997,7 +983,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * the underlying map for clear(). */ public void testKeySetClearChangesMap() { - if (!isRemoveSupported()) return; + if (!isRemoveSupported()) { + return; + } // clear values, reflected in map resetFull(); @@ -1023,7 +1011,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * the underlying map for clear(). */ public void testEntrySetClearChangesMap() { - if (!isRemoveSupported()) return; + if (!isRemoveSupported()) { + return; + } // clear values, reflected in map resetFull(); @@ -1051,6 +1041,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { Map.Entry entry = (Map.Entry) entrySet.iterator().next(); assertEquals(true, entrySet.contains(entry)); } + public void testEntrySetContains2() { resetFull(); Set entrySet = map.entrySet(); @@ -1058,6 +1049,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { Map.Entry test = cloneMapEntry(entry); assertEquals(true, entrySet.contains(test)); } + public void testEntrySetContains3() { resetFull(); Set entrySet = map.entrySet(); @@ -1069,7 +1061,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { } public void testEntrySetRemove1() { - if (!isRemoveSupported()) return; + if (!isRemoveSupported()) { + return; + } resetFull(); int size = map.size(); Set entrySet = map.entrySet(); @@ -1080,8 +1074,11 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { assertEquals(false, map.containsKey(key)); assertEquals(size - 1, map.size()); } + public void testEntrySetRemove2() { - if (!isRemoveSupported()) return; + if (!isRemoveSupported()) { + return; + } resetFull(); int size = map.size(); Set entrySet = map.entrySet(); @@ -1093,8 +1090,11 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { assertEquals(false, map.containsKey(key)); assertEquals(size - 1, map.size()); } + public void testEntrySetRemove3() { - if (!isRemoveSupported()) return; + if (!isRemoveSupported()) { + return; + } resetFull(); int size = map.size(); Set entrySet = map.entrySet(); @@ -1110,6 +1110,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { } //----------------------------------------------------------------------- + /** * Tests that the {@link Map#values} collection is backed by * the underlying map by removing from the values collection @@ -1135,7 +1136,8 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { while (values.contains(sampleValues[i]) && j < 10000) { try { values.remove(sampleValues[i]); - } catch (UnsupportedOperationException e) { + } + catch (UnsupportedOperationException e) { // if values.remove is unsupported, just skip this test return; } @@ -1143,8 +1145,8 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { } assertTrue("values().remove(obj) is broken", j < 10000); assertTrue( - "Value should have been removed from the underlying map.", - !map.containsValue(sampleValues[i])); + "Value should have been removed from the underlying map.", + !map.containsValue(sampleValues[i])); } } } @@ -1161,13 +1163,14 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { for (int i = 0; i < sampleKeys.length; i++) { try { keys.remove(sampleKeys[i]); - } catch (UnsupportedOperationException e) { + } + catch (UnsupportedOperationException e) { // if key.remove is unsupported, just skip this test return; } assertTrue( - "Key should have been removed from the underlying map.", - !map.containsKey(sampleKeys[i])); + "Key should have been removed from the underlying map.", + !map.containsKey(sampleKeys[i])); } } @@ -1176,13 +1179,12 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { // same for EntrySet/KeySet/values's // Iterator.remove, removeAll, retainAll - /** * Utility methods to create an array of Map.Entry objects * out of the given key and value arrays.

* - * @param keys the array of keys - * @param values the array of values + * @param keys the array of keys + * @param values the array of values * @return an array of Map.Entry of those keys to those values */ private Map.Entry[] makeEntryArray(Object[] keys, Object[] values) { @@ -1195,7 +1197,6 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { return result; } - /** * Bulk test {@link Map#entrySet()}. This method runs through all of * the tests in {@link SetAbstractTestCase}. @@ -1238,13 +1239,16 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { // Collection views don't support add operations. return false; } + public boolean isRemoveSupported() { // Entry set should only support remove if map does return MapAbstractTestCase.this.isRemoveSupported(); } + public boolean isGetStructuralModify() { return MapAbstractTestCase.this.isGetStructuralModify(); } + public boolean isTestSerialization() { return false; } @@ -1279,9 +1283,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { public void testMapEntrySetIteratorEntrySetValue() { Object key1 = getSampleKeys()[0]; - Object key2 = (getSampleKeys().length ==1 ? getSampleKeys()[0] : getSampleKeys()[1]); + Object key2 = (getSampleKeys().length == 1 ? getSampleKeys()[0] : getSampleKeys()[1]); Object newValue1 = getNewSampleValues()[0]; - Object newValue2 = (getNewSampleValues().length ==1 ? getNewSampleValues()[0] : getNewSampleValues()[1]); + Object newValue2 = (getNewSampleValues().length == 1 ? getNewSampleValues()[0] : getNewSampleValues()[1]); resetFull(); // explicitly get entries as sample values/keys are connected for some maps @@ -1299,7 +1303,8 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { if (isSetValueSupported() == false) { try { entry1.setValue(newValue1); - } catch (UnsupportedOperationException ex) { + } + catch (UnsupportedOperationException ex) { } return; } @@ -1338,7 +1343,8 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { entry = temp; break; } - } else if (temp.getKey().equals(key)) { + } + else if (temp.getKey().equals(key)) { entry = temp; break; } @@ -1348,7 +1354,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { } public void testMapEntrySetRemoveNonMapEntry() { - if (isRemoveSupported() == false) return; + if (isRemoveSupported() == false) { + return; + } resetFull(); assertEquals(false, getSet().remove(null)); assertEquals(false, getSet().remove(new Object())); @@ -1360,7 +1368,6 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { } } - /** * Bulk test {@link Map#keySet()}. This method runs through all of * the tests in {@link SetAbstractTestCase}. @@ -1395,12 +1402,15 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { public boolean isNullSupported() { return MapAbstractTestCase.this.isAllowNullKey(); } + public boolean isAddSupported() { return false; } + public boolean isRemoveSupported() { return MapAbstractTestCase.this.isRemoveSupported(); } + public boolean isTestSerialization() { return false; } @@ -1423,7 +1433,6 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { } } - /** * Bulk test {@link Map#values()}. This method runs through all of * the tests in {@link CollectionAbstractTestCase}. @@ -1431,7 +1440,7 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { * that the map and the other collection views are still valid. * * @return a {@link CollectionAbstractTestCase} instance for testing the map's - * values collection + * values collection */ /* public BulkTest bulkTestMapValues() { @@ -1459,12 +1468,15 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { public boolean isNullSupported() { return MapAbstractTestCase.this.isAllowNullKey(); } + public boolean isAddSupported() { return false; } + public boolean isRemoveSupported() { return MapAbstractTestCase.this.isRemoveSupported(); } + public boolean isTestSerialization() { return false; } @@ -1507,7 +1519,6 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { // the value equal to the value returned from the values iterator. } - /** * Resets the {@link #map}, {@link #entrySet}, {@link #keySet}, * {@link #values} and {@link #confirmed} fields to empty. @@ -1533,7 +1544,6 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { } } - /** * Resets the collection view fields. */ @@ -1543,7 +1553,6 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { this.entrySet = map.entrySet(); } - /** * Verifies that {@link #map} is still equal to {@link #confirmed}. * This method checks that the map is equal to the HashMap, @@ -1564,12 +1573,9 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { public void verifyMap() { int size = confirmed.size(); boolean empty = confirmed.isEmpty(); - assertEquals("Map should be same size as HashMap", - size, map.size()); - assertEquals("Map should be empty if HashMap is", - empty, map.isEmpty()); - assertEquals("hashCodes should be the same", - confirmed.hashCode(), map.hashCode()); + assertEquals("Map should be same size as HashMap", size, map.size()); + assertEquals("Map should be empty if HashMap is", empty, map.isEmpty()); + assertEquals("hashCodes should be the same", confirmed.hashCode(), map.hashCode()); // this fails for LRUMap because confirmed.equals() somehow modifies // map, causing concurrent modification exceptions. //assertEquals("Map should still equal HashMap", confirmed, map); @@ -1584,39 +1590,29 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { public void verifyEntrySet() { int size = confirmed.size(); boolean empty = confirmed.isEmpty(); - assertEquals("entrySet should be same size as HashMap's" + - "\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(), - size, entrySet.size()); - assertEquals("entrySet should be empty if HashMap is" + - "\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(), - empty, entrySet.isEmpty()); - assertTrue("entrySet should contain all HashMap's elements" + - "\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(), - entrySet.containsAll(confirmed.entrySet())); - assertEquals("entrySet hashCodes should be the same" + - "\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(), - confirmed.entrySet().hashCode(), entrySet.hashCode()); - assertEquals("Map's entry set should still equal HashMap's", - confirmed.entrySet(), entrySet); + assertEquals("entrySet should be same size as HashMap's\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(), + size, entrySet.size()); + assertEquals("entrySet should be empty if HashMap is\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(), + empty, entrySet.isEmpty()); + assertTrue("entrySet should contain all HashMap's elements\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(), + entrySet.containsAll(confirmed.entrySet())); + assertEquals("entrySet hashCodes should be the same\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(), + confirmed.entrySet().hashCode(), entrySet.hashCode()); + assertEquals("Map's entry set should still equal HashMap's", confirmed.entrySet(), entrySet); } public void verifyKeySet() { int size = confirmed.size(); boolean empty = confirmed.isEmpty(); - assertEquals("keySet should be same size as HashMap's" + - "\nTest: " + keySet + "\nReal: " + confirmed.keySet(), - size, keySet.size()); - assertEquals("keySet should be empty if HashMap is" + - "\nTest: " + keySet + "\nReal: " + confirmed.keySet(), - empty, keySet.isEmpty()); - assertTrue("keySet should contain all HashMap's elements" + - "\nTest: " + keySet + "\nReal: " + confirmed.keySet(), - keySet.containsAll(confirmed.keySet())); - assertEquals("keySet hashCodes should be the same" + - "\nTest: " + keySet + "\nReal: " + confirmed.keySet(), - confirmed.keySet().hashCode(), keySet.hashCode()); - assertEquals("Map's key set should still equal HashMap's", - confirmed.keySet(), keySet); + assertEquals("keySet should be same size as HashMap's\nTest: " + keySet + "\nReal: " + confirmed.keySet(), + size, keySet.size()); + assertEquals("keySet should be empty if HashMap is\nTest: " + keySet + "\nReal: " + confirmed.keySet(), + empty, keySet.isEmpty()); + assertTrue("keySet should contain all HashMap's elements\nTest: " + keySet + "\nReal: " + confirmed.keySet(), + keySet.containsAll(confirmed.keySet())); + assertEquals("keySet hashCodes should be the same\nTest: " + keySet + "\nReal: " + confirmed.keySet(), + confirmed.keySet().hashCode(), keySet.hashCode()); + assertEquals("Map's key set should still equal HashMap's", confirmed.keySet(), keySet); } public void verifyValues() { @@ -1625,27 +1621,20 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { int size = confirmed.size(); boolean empty = confirmed.isEmpty(); - assertEquals("values should be same size as HashMap's" + - "\nTest: " + test + "\nReal: " + known, - size, values.size()); - assertEquals("values should be empty if HashMap is" + - "\nTest: " + test + "\nReal: " + known, - empty, values.isEmpty()); - assertTrue("values should contain all HashMap's elements" + - "\nTest: " + test + "\nReal: " + known, - test.containsAll(known)); - assertTrue("values should contain all HashMap's elements" + - "\nTest: " + test + "\nReal: " + known, - known.containsAll(test)); - // originally coded to use a HashBag, but now separate jar so... - for (Iterator it = known.iterator(); it.hasNext();) { - boolean removed = test.remove(it.next()); + + assertEquals("values should be same size as HashMap's\nTest: " + test + "\nReal: " + known, size, values.size()); + assertEquals("values should be empty if HashMap is\nTest: " + test + "\nReal: " + known, empty, values.isEmpty()); + assertTrue("values should contain all HashMap's elements\nTest: " + test + "\nReal: " + known, test.containsAll(known)); + assertTrue("values should contain all HashMap's elements\nTest: " + test + "\nReal: " + known, known.containsAll(test)); + + for (Object aKnown : known) { + boolean removed = test.remove(aKnown); assertTrue("Map's values should still equal HashMap's", removed); } + assertTrue("Map's values should still equal HashMap's", test.isEmpty()); } - /** * Erases any leftover instance variables by setting them to null. */ @@ -1656,5 +1645,4 @@ public abstract class MapAbstractTestCase extends ObjectAbstractTestCase { values = null; confirmed = null; } - } diff --git a/common/common-lang/src/test/java/com/twelvemonkeys/util/ObjectAbstractTestCase.java b/common/common-lang/src/test/java/com/twelvemonkeys/util/ObjectAbstractTestCase.java index 7efbc438..c781d776 100755 --- a/common/common-lang/src/test/java/com/twelvemonkeys/util/ObjectAbstractTestCase.java +++ b/common/common-lang/src/test/java/com/twelvemonkeys/util/ObjectAbstractTestCase.java @@ -15,7 +15,7 @@ */ package com.twelvemonkeys.util; -import org.jmock.cglib.MockObjectTestCase; +import junit.framework.TestCase; import java.io.*; @@ -35,9 +35,9 @@ import java.io.*; * @author Stephen Colebourne * @author Anonymous */ -public abstract class ObjectAbstractTestCase extends MockObjectTestCase { - +public abstract class ObjectAbstractTestCase extends TestCase { //----------------------------------------------------------------------- + /** * Implement this method to return the object to test. * diff --git a/common/pom.xml b/common/pom.xml index cc1a87ee..f537ad61 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -52,12 +52,5 @@ 4.7 test - - - jmock - jmock-cglib - 1.0.1 - test - diff --git a/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/wmf/WMFImageReader.java b/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/wmf/WMFImageReader.java index 31829a10..5391a2a1 100755 --- a/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/wmf/WMFImageReader.java +++ b/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/wmf/WMFImageReader.java @@ -81,6 +81,7 @@ public class WMFImageReader extends ImageReaderBase { processReadAborted(); return image; } + processImageProgress(100f); processImageComplete(); diff --git a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTestCase.java b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTestCase.java index 6821bc33..a3772238 100755 --- a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTestCase.java +++ b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTestCase.java @@ -43,7 +43,7 @@ import java.util.List; * @version $Id: SVGImageReaderTestCase.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$ */ public class SVGImageReaderTestCase extends ImageReaderAbstractTestCase { - private SVGImageReaderSpi mSVGImageReaderSpi = new SVGImageReaderSpi(); + private SVGImageReaderSpi provider = new SVGImageReaderSpi(); protected List getTestData() { return Arrays.asList( @@ -52,7 +52,7 @@ public class SVGImageReaderTestCase extends ImageReaderAbstractTestCase { - private WMFImageReaderSpi mSVGImageReaderSpi = new WMFImageReaderSpi(); + private WMFImageReaderSpi provider = new WMFImageReaderSpi(); protected List getTestData() { return Arrays.asList( @@ -53,7 +53,7 @@ public class WMFImageReaderTestCase extends ImageReaderAbstractTestCase extends MockObjectTestCase { +public abstract class ImageReaderAbstractTestCase { // TODO: Should we really test if he provider is installed? // - Pro: Tests the META-INF/services config // - Con: Not all providers should be installed at runtime... @@ -948,8 +950,7 @@ public abstract class ImageReaderAbstractTestCase extends @Test public void testAddIIOReadProgressListener() { ImageReader reader = createReader(); - Mock mockListener = new Mock(IIOReadProgressListener.class); - reader.addIIOReadProgressListener((IIOReadProgressListener) mockListener.proxy()); + reader.addIIOReadProgressListener(mock(IIOReadProgressListener.class)); } @Test @@ -964,13 +965,8 @@ public abstract class ImageReaderAbstractTestCase extends TestData data = getTestData().get(0); reader.setInput(data.getInputStream()); - Mock mockListener = new Mock(IIOReadProgressListener.class); - String started = "Started"; - mockListener.expects(once()).method("imageStarted").withAnyArguments().id(started); - mockListener.stubs().method("imageProgress").withAnyArguments().after(started); - mockListener.expects(once()).method("imageComplete").withAnyArguments().after(started); - - reader.addIIOReadProgressListener((IIOReadProgressListener) mockListener.proxy()); + IIOReadProgressListener listener = mock(IIOReadProgressListener.class); + reader.addIIOReadProgressListener(listener); try { reader.read(0); @@ -980,7 +976,10 @@ public abstract class ImageReaderAbstractTestCase extends } // At least imageStarted and imageComplete, plus any number of imageProgress - mockListener.verify(); + InOrder ordered = inOrder(listener); + ordered.verify(listener).imageStarted(reader, 0); + ordered.verify(listener, atLeastOnce()).imageProgress(eq(reader), anyInt()); + ordered.verify(listener).imageComplete(reader); } @Test @@ -989,28 +988,13 @@ public abstract class ImageReaderAbstractTestCase extends TestData data = getTestData().get(0); reader.setInput(data.getInputStream()); - Mock mockListener = new Mock(IIOReadProgressListener.class); - String started = "Started"; - mockListener.expects(once()).method("imageStarted").withAnyArguments().id(started); - mockListener.stubs().method("imageProgress").withAnyArguments().after(started); - mockListener.expects(once()).method("imageComplete").withAnyArguments().after(started); + IIOReadProgressListener listener = mock(IIOReadProgressListener.class); + IIOReadProgressListener listenerToo = mock(IIOReadProgressListener.class); + IIOReadProgressListener listenerThree = mock(IIOReadProgressListener.class); - Mock mockListenerToo = new Mock(IIOReadProgressListener.class); - String startedToo = "Started Two"; - mockListenerToo.expects(once()).method("imageStarted").withAnyArguments().id(startedToo); - mockListenerToo.stubs().method("imageProgress").withAnyArguments().after(startedToo); - mockListenerToo.expects(once()).method("imageComplete").withAnyArguments().after(startedToo); - - Mock mockListenerThree = new Mock(IIOReadProgressListener.class); - String startedThree = "Started Three"; - mockListenerThree.expects(once()).method("imageStarted").withAnyArguments().id(startedThree); - mockListenerThree.stubs().method("imageProgress").withAnyArguments().after(startedThree); - mockListenerThree.expects(once()).method("imageComplete").withAnyArguments().after(startedThree); - - - reader.addIIOReadProgressListener((IIOReadProgressListener) mockListener.proxy()); - reader.addIIOReadProgressListener((IIOReadProgressListener) mockListenerToo.proxy()); - reader.addIIOReadProgressListener((IIOReadProgressListener) mockListenerThree.proxy()); + reader.addIIOReadProgressListener(listener); + reader.addIIOReadProgressListener(listenerToo); + reader.addIIOReadProgressListener(listenerThree); try { reader.read(0); @@ -1020,9 +1004,19 @@ public abstract class ImageReaderAbstractTestCase extends } // At least imageStarted and imageComplete, plus any number of imageProgress - mockListener.verify(); - mockListenerToo.verify(); - mockListenerThree.verify(); + InOrder ordered = inOrder(listener, listenerToo, listenerThree); + + ordered.verify(listener).imageStarted(reader, 0); + ordered.verify(listenerToo).imageStarted(reader, 0); + ordered.verify(listenerThree).imageStarted(reader, 0); + + ordered.verify(listener, atLeastOnce()).imageProgress(eq(reader), anyInt()); + ordered.verify(listenerToo, atLeastOnce()).imageProgress(eq(reader), anyInt()); + ordered.verify(listenerThree, atLeastOnce()).imageProgress(eq(reader), anyInt()); + + ordered.verify(listener).imageComplete(reader); + ordered.verify(listenerToo).imageComplete(reader); + ordered.verify(listenerThree).imageComplete(reader); } @Test @@ -1034,8 +1028,7 @@ public abstract class ImageReaderAbstractTestCase extends @Test public void testRemoveIIOReadProgressListenerNone() { ImageReader reader = createReader(); - Mock mockListener = new Mock(IIOReadProgressListener.class); - reader.removeIIOReadProgressListener((IIOReadProgressListener) mockListener.proxy()); + reader.removeIIOReadProgressListener(mock(IIOReadProgressListener.class)); } @Test @@ -1043,8 +1036,8 @@ public abstract class ImageReaderAbstractTestCase extends ImageReader reader = createReader(); TestData data = getTestData().get(0); reader.setInput(data.getInputStream()); - Mock mockListener = new Mock(IIOReadProgressListener.class); - IIOReadProgressListener listener = (IIOReadProgressListener) mockListener.proxy(); + + IIOReadProgressListener listener = mock(IIOReadProgressListener.class); reader.addIIOReadProgressListener(listener); reader.removeIIOReadProgressListener(listener); @@ -1056,7 +1049,7 @@ public abstract class ImageReaderAbstractTestCase extends } // Should not have called any methods... - mockListener.verify(); + verifyZeroInteractions(listener); } @Test @@ -1065,15 +1058,11 @@ public abstract class ImageReaderAbstractTestCase extends TestData data = getTestData().get(0); reader.setInput(data.getInputStream()); - Mock mockListener = new Mock(IIOReadProgressListener.class, "Listener1"); - IIOReadProgressListener listener = (IIOReadProgressListener) mockListener.proxy(); + IIOReadProgressListener listener = mock(IIOReadProgressListener.class, "Listener1"); reader.addIIOReadProgressListener(listener); - Mock mockListenerToo = new Mock(IIOReadProgressListener.class, "Listener2"); - mockListenerToo.expects(once()).method("imageStarted").with(eq(reader), eq(0)); - mockListenerToo.stubs().method("imageProgress").withAnyArguments(); - mockListenerToo.expects(once()).method("imageComplete").with(eq(reader)); - IIOReadProgressListener listenerToo = (IIOReadProgressListener) mockListenerToo.proxy(); + + IIOReadProgressListener listenerToo = mock(IIOReadProgressListener.class, "Listener2"); reader.addIIOReadProgressListener(listenerToo); reader.removeIIOReadProgressListener(listener); @@ -1085,9 +1074,13 @@ public abstract class ImageReaderAbstractTestCase extends fail("Could not read image"); } - // Should not have called any methods... - mockListener.verify(); - mockListenerToo.verify(); + // Should not have called any methods on listener1... + verifyZeroInteractions(listener); + + InOrder ordered = inOrder(listenerToo); + ordered.verify(listenerToo).imageStarted(reader, 0); + ordered.verify(listenerToo, atLeastOnce()).imageProgress(eq(reader), anyInt()); + ordered.verify(listenerToo).imageComplete(reader); } @Test @@ -1096,8 +1089,8 @@ public abstract class ImageReaderAbstractTestCase extends TestData data = getTestData().get(0); reader.setInput(data.getInputStream()); - Mock mockListener = new Mock(IIOReadProgressListener.class); - reader.addIIOReadProgressListener((IIOReadProgressListener) mockListener.proxy()); + IIOReadProgressListener listener = mock(IIOReadProgressListener.class); + reader.addIIOReadProgressListener(listener); reader.removeAllIIOReadProgressListeners(); @@ -1109,7 +1102,7 @@ public abstract class ImageReaderAbstractTestCase extends } // Should not have called any methods... - mockListener.verify(); + verifyZeroInteractions(listener); } @Test @@ -1118,11 +1111,11 @@ public abstract class ImageReaderAbstractTestCase extends TestData data = getTestData().get(0); reader.setInput(data.getInputStream()); - Mock mockListener = new Mock(IIOReadProgressListener.class); - reader.addIIOReadProgressListener((IIOReadProgressListener) mockListener.proxy()); + IIOReadProgressListener listener = mock(IIOReadProgressListener.class); + reader.addIIOReadProgressListener(listener); - Mock mockListenerToo = new Mock(IIOReadProgressListener.class); - reader.addIIOReadProgressListener((IIOReadProgressListener) mockListenerToo.proxy()); + IIOReadProgressListener listenerToo = mock(IIOReadProgressListener.class); + reader.addIIOReadProgressListener(listenerToo); reader.removeAllIIOReadProgressListeners(); @@ -1134,8 +1127,8 @@ public abstract class ImageReaderAbstractTestCase extends } // Should not have called any methods... - mockListener.verify(); - mockListenerToo.verify(); + verifyZeroInteractions(listener); + verifyZeroInteractions(listenerToo); } @Test @@ -1144,41 +1137,24 @@ public abstract class ImageReaderAbstractTestCase extends TestData data = getTestData().get(0); reader.setInput(data.getInputStream()); - Mock mockListener = new Mock(IIOReadProgressListener.class, "Progress1"); - mockListener.stubs().method("imageStarted").withAnyArguments(); - mockListener.stubs().method("imageProgress").withAnyArguments(); - mockListener.expects(once()).method("readAborted").with(eq(reader)); - mockListener.stubs().method("imageComplete").withAnyArguments(); - IIOReadProgressListener listener = (IIOReadProgressListener) mockListener.proxy(); + IIOReadProgressListener listener = mock(IIOReadProgressListener.class, "Progress1"); reader.addIIOReadProgressListener(listener); - Mock mockListenerToo = new Mock(IIOReadProgressListener.class, "Progress2"); - mockListenerToo.stubs().method("imageStarted").withAnyArguments(); - mockListenerToo.stubs().method("imageProgress").withAnyArguments(); - mockListenerToo.expects(once()).method("readAborted").with(eq(reader)); - mockListenerToo.stubs().method("imageComplete").withAnyArguments(); - IIOReadProgressListener listenerToo = (IIOReadProgressListener) mockListenerToo.proxy(); + IIOReadProgressListener listenerToo = mock(IIOReadProgressListener.class, "Progress2"); reader.addIIOReadProgressListener(listenerToo); // Create a listener that just makes the reader abort immediately... - Mock abortingListener = new Mock(IIOReadProgressListener.class, "Aborter"); - abortingListener.stubs().method("readAborted").withAnyArguments(); - abortingListener.stubs().method("imageComplete").withAnyArguments(); - Stub abort = new Stub() { - public Object invoke(Invocation pInvocation) throws Throwable { + IIOReadProgressListener abortingListener = mock(IIOReadProgressListener.class, "Aborter"); + Answer abort = new Answer() { + public Void answer(InvocationOnMock invocation) throws Throwable { reader.abort(); return null; } - - public StringBuffer describeTo(StringBuffer pStringBuffer) { - pStringBuffer.append("aborting"); - return pStringBuffer; - } }; - abortingListener.stubs().method("imageProgress").will(abort); - abortingListener.stubs().method("imageStarted").will(abort); + doAnswer(abort).when(abortingListener).imageStarted(any(ImageReader.class), anyInt()); + doAnswer(abort).when(abortingListener).imageProgress(any(ImageReader.class), anyInt()); - reader.addIIOReadProgressListener((IIOReadProgressListener) abortingListener.proxy()); + reader.addIIOReadProgressListener(abortingListener); try { reader.read(0); @@ -1187,8 +1163,8 @@ public abstract class ImageReaderAbstractTestCase extends failBecause("Image could not be read", e); } - mockListener.verify(); - mockListenerToo.verify(); + verify(listener).readAborted(reader); + verify(listenerToo).readAborted(reader); } @Test diff --git a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageWriterAbstractTestCase.java b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageWriterAbstractTestCase.java index 13373a4e..53096429 100755 --- a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageWriterAbstractTestCase.java +++ b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/util/ImageWriterAbstractTestCase.java @@ -28,8 +28,8 @@ package com.twelvemonkeys.imageio.util; -import org.jmock.Mock; -import org.jmock.cglib.MockObjectTestCase; +import org.junit.Test; +import org.mockito.InOrder; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; @@ -39,6 +39,10 @@ import java.awt.image.RenderedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; +import static org.junit.Assert.*; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.*; + /** * ImageReaderAbstractTestCase class description. * @@ -46,12 +50,13 @@ import java.io.IOException; * @author last modified by $Author: haku $ * @version $Id: ImageReaderAbstractTestCase.java,v 1.0 18.nov.2004 17:38:33 haku Exp $ */ -public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { +public abstract class ImageWriterAbstractTestCase { protected abstract ImageWriter createImageWriter(); protected abstract RenderedImage getTestData(); + @Test public void testSetOutput() throws IOException { // Should just pass with no exceptions ImageWriter writer = createImageWriter(); @@ -59,6 +64,7 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { writer.setOutput(ImageIO.createImageOutputStream(new ByteArrayOutputStream())); } + @Test public void testSetOutputNull() { // Should just pass with no exceptions ImageWriter writer = createImageWriter(); @@ -66,25 +72,30 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { writer.setOutput(null); } + @Test public void testWrite() throws IOException { ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); writer.setOutput(ImageIO.createImageOutputStream(buffer)); + try { writer.write(getTestData()); } catch (IOException e) { fail(e.getMessage()); } + assertTrue("No image data written", buffer.size() > 0); } + @Test public void testWrite2() { // Note: There's a difference between new ImageOutputStreamImpl and // ImageIO.createImageOutputStream... Make sure writers handle both // cases ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + try { writer.setOutput(ImageIO.createImageOutputStream(buffer)); writer.write(getTestData()); @@ -96,10 +107,12 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { assertTrue("No image data written", buffer.size() > 0); } + @Test public void testWriteNull() throws IOException { ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); writer.setOutput(ImageIO.createImageOutputStream(buffer)); + try { writer.write((RenderedImage) null); } @@ -108,11 +121,14 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { catch (IOException e) { fail(e.getMessage()); } + assertTrue("Image data written", buffer.size() == 0); } + @Test public void testWriteNoOutput() { ImageWriter writer = createImageWriter(); + try { writer.write(getTestData()); } @@ -123,6 +139,7 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { } } + @Test public void testGetDefaultWriteParam() { ImageWriter writer = createImageWriter(); ImageWriteParam param = writer.getDefaultWriteParam(); @@ -132,29 +149,26 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { // TODO: Test writing with params // TODO: Source region and subsampling at least + @Test public void testAddIIOWriteProgressListener() { ImageWriter writer = createImageWriter(); - Mock mockListener = new Mock(IIOWriteProgressListener.class); - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListener.proxy()); + writer.addIIOWriteProgressListener(mock(IIOWriteProgressListener.class)); } + @Test public void testAddIIOWriteProgressListenerNull() { ImageWriter writer = createImageWriter(); writer.addIIOWriteProgressListener(null); } + @Test public void testAddIIOWriteProgressListenerCallbacks() throws IOException { ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); writer.setOutput(ImageIO.createImageOutputStream(buffer)); - Mock mockListener = new Mock(IIOWriteProgressListener.class); - String started = "Started"; - mockListener.expects(once()).method("imageStarted").withAnyArguments().id(started); - mockListener.stubs().method("imageProgress").withAnyArguments().after(started); - mockListener.expects(once()).method("imageComplete").withAnyArguments().after(started); - - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListener.proxy()); + IIOWriteProgressListener listener = mock(IIOWriteProgressListener.class); + writer.addIIOWriteProgressListener(listener); try { writer.write(getTestData()); @@ -164,36 +178,25 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { } // At least imageStarted and imageComplete, plus any number of imageProgress - mockListener.verify(); + InOrder ordered = inOrder(listener); + ordered.verify(listener).imageStarted(writer, 0); + ordered.verify(listener, atLeastOnce()).imageProgress(eq(writer), anyInt()); + ordered.verify(listener).imageComplete(writer); } + @Test public void testMultipleAddIIOWriteProgressListenerCallbacks() throws IOException { ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); writer.setOutput(ImageIO.createImageOutputStream(buffer)); - Mock mockListener = new Mock(IIOWriteProgressListener.class); - String started = "Started"; - mockListener.expects(once()).method("imageStarted").withAnyArguments().id(started); - mockListener.stubs().method("imageProgress").withAnyArguments().after(started); - mockListener.expects(once()).method("imageComplete").withAnyArguments().after(started); + IIOWriteProgressListener listener = mock(IIOWriteProgressListener.class); + IIOWriteProgressListener listenerToo = mock(IIOWriteProgressListener.class); + IIOWriteProgressListener listenerThree = mock(IIOWriteProgressListener.class); - Mock mockListenerToo = new Mock(IIOWriteProgressListener.class); - String startedToo = "Started Two"; - mockListenerToo.expects(once()).method("imageStarted").withAnyArguments().id(startedToo); - mockListenerToo.stubs().method("imageProgress").withAnyArguments().after(startedToo); - mockListenerToo.expects(once()).method("imageComplete").withAnyArguments().after(startedToo); - - Mock mockListenerThree = new Mock(IIOWriteProgressListener.class); - String startedThree = "Started Three"; - mockListenerThree.expects(once()).method("imageStarted").withAnyArguments().id(startedThree); - mockListenerThree.stubs().method("imageProgress").withAnyArguments().after(startedThree); - mockListenerThree.expects(once()).method("imageComplete").withAnyArguments().after(startedThree); - - - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListener.proxy()); - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListenerToo.proxy()); - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListenerThree.proxy()); + writer.addIIOWriteProgressListener(listener); + writer.addIIOWriteProgressListener(listenerToo); + writer.addIIOWriteProgressListener(listenerThree); try { writer.write(getTestData()); @@ -203,30 +206,40 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { } // At least imageStarted and imageComplete, plus any number of imageProgress - mockListener.verify(); - mockListenerToo.verify(); - mockListenerThree.verify(); + InOrder ordered = inOrder(listener, listenerToo, listenerThree); + + ordered.verify(listener).imageStarted(writer, 0); + ordered.verify(listenerToo).imageStarted(writer, 0); + ordered.verify(listenerThree).imageStarted(writer, 0); + + ordered.verify(listener, atLeastOnce()).imageProgress(eq(writer), anyInt()); + ordered.verify(listenerToo, atLeastOnce()).imageProgress(eq(writer), anyInt()); + ordered.verify(listenerThree, atLeastOnce()).imageProgress(eq(writer), anyInt()); + + ordered.verify(listener).imageComplete(writer); + ordered.verify(listenerToo).imageComplete(writer); + ordered.verify(listenerThree).imageComplete(writer); } - + @Test public void testRemoveIIOWriteProgressListenerNull() { ImageWriter writer = createImageWriter(); writer.removeIIOWriteProgressListener(null); } + @Test public void testRemoveIIOWriteProgressListenerNone() { ImageWriter writer = createImageWriter(); - Mock mockListener = new Mock(IIOWriteProgressListener.class); - writer.removeIIOWriteProgressListener((IIOWriteProgressListener) mockListener.proxy()); + writer.removeIIOWriteProgressListener(mock(IIOWriteProgressListener.class)); } + @Test public void testRemoveIIOWriteProgressListener() throws IOException { ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); writer.setOutput(ImageIO.createImageOutputStream(buffer)); - Mock mockListener = new Mock(IIOWriteProgressListener.class); - IIOWriteProgressListener listener = (IIOWriteProgressListener) mockListener.proxy(); + IIOWriteProgressListener listener = mock(IIOWriteProgressListener.class); writer.addIIOWriteProgressListener(listener); writer.removeIIOWriteProgressListener(listener); @@ -238,25 +251,22 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { } // Should not have called any methods... - mockListener.verify(); + verifyZeroInteractions(listener); } + @Test public void testRemoveIIOWriteProgressListenerMultiple() throws IOException { ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); writer.setOutput(ImageIO.createImageOutputStream(buffer)); + IIOWriteProgressListener listener = mock(IIOWriteProgressListener.class); + writer.addIIOWriteProgressListener(listener); - Mock mockListener = new Mock(IIOWriteProgressListener.class); - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListener.proxy()); + IIOWriteProgressListener listenerToo = mock(IIOWriteProgressListener.class); + writer.addIIOWriteProgressListener(listenerToo); - Mock mockListenerToo = new Mock(IIOWriteProgressListener.class); - mockListenerToo.stubs().method("imageStarted").withAnyArguments(); - mockListenerToo.stubs().method("imageProgress").withAnyArguments(); - mockListenerToo.stubs().method("imageComplete").withAnyArguments(); - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListenerToo.proxy()); - - writer.removeIIOWriteProgressListener((IIOWriteProgressListener) mockListener.proxy()); + writer.removeIIOWriteProgressListener(listener); try { writer.write(getTestData()); @@ -266,19 +276,25 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { } // Should not have called any methods... - mockListener.verify(); - mockListenerToo.verify(); + verifyZeroInteractions(listener); + + // At least imageStarted and imageComplete, plus any number of imageProgress + InOrder ordered = inOrder(listenerToo); + ordered.verify(listenerToo).imageStarted(writer, 0); + ordered.verify(listenerToo, atLeastOnce()).imageProgress(eq(writer), anyInt()); + ordered.verify(listenerToo).imageComplete(writer); + } - + @Test public void testRemoveAllIIOWriteProgressListeners() throws IOException { ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); writer.setOutput(ImageIO.createImageOutputStream(buffer)); - Mock mockListener = new Mock(IIOWriteProgressListener.class); - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListener.proxy()); + IIOWriteProgressListener listener = mock(IIOWriteProgressListener.class); + writer.addIIOWriteProgressListener(listener); writer.removeAllIIOWriteProgressListeners(); @@ -290,20 +306,21 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { } // Should not have called any methods... - mockListener.verify(); + verifyZeroInteractions(listener); } + @Test public void testRemoveAllIIOWriteProgressListenersMultiple() throws IOException { ImageWriter writer = createImageWriter(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); writer.setOutput(ImageIO.createImageOutputStream(buffer)); - Mock mockListener = new Mock(IIOWriteProgressListener.class); - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListener.proxy()); + IIOWriteProgressListener listener = mock(IIOWriteProgressListener.class); + writer.addIIOWriteProgressListener(listener); - Mock mockListenerToo = new Mock(IIOWriteProgressListener.class); - writer.addIIOWriteProgressListener((IIOWriteProgressListener) mockListenerToo.proxy()); + IIOWriteProgressListener listenerToo = mock(IIOWriteProgressListener.class); + writer.addIIOWriteProgressListener(listenerToo); writer.removeAllIIOWriteProgressListeners(); @@ -315,8 +332,7 @@ public abstract class ImageWriterAbstractTestCase extends MockObjectTestCase { } // Should not have called any methods... - mockListener.verify(); - mockListenerToo.verify(); + verifyZeroInteractions(listener); + verifyZeroInteractions(listenerToo); } - } \ No newline at end of file diff --git a/imageio/imageio-ico/src/test/java/com/twelvemonkeys/imageio/plugins/ico/CURImageReaderTestCase.java b/imageio/imageio-ico/src/test/java/com/twelvemonkeys/imageio/plugins/ico/CURImageReaderTestCase.java index 6de82c79..305b6576 100755 --- a/imageio/imageio-ico/src/test/java/com/twelvemonkeys/imageio/plugins/ico/CURImageReaderTestCase.java +++ b/imageio/imageio-ico/src/test/java/com/twelvemonkeys/imageio/plugins/ico/CURImageReaderTestCase.java @@ -1,6 +1,7 @@ package com.twelvemonkeys.imageio.plugins.ico; import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase; +import org.junit.Test; import javax.imageio.ImageReadParam; import javax.imageio.spi.ImageReaderSpi; @@ -10,6 +11,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import static org.junit.Assert.*; + /** * CURImageReaderTestCase * @@ -74,19 +77,23 @@ public class CURImageReaderTestCase extends ImageReaderAbstractTestCase { - private BMPImageReaderSpi mProvider = new BMPImageReaderSpi(); + private BMPImageReaderSpi provider = new BMPImageReaderSpi(); protected List getTestData() { return Arrays.asList( @@ -63,7 +63,7 @@ public class BMPImageReaderTestCase extends JMagickImageReaderAbstractTestCase extends ImageReaderAbstractTestCase { - - @Override - protected void runTest() throws Throwable { - if (JMagickImageReaderSpiSupport.AVAILABLE) { - super.runTest(); + @Rule + public MethodRule rule = new MethodRule() { + public Statement apply(final Statement base, final FrameworkMethod method, final Object target) { + if (JMagickImageReaderSpiSupport.AVAILABLE) { + return base; + } + + return new Statement() { + @Override + public void evaluate() throws Throwable { + // TODO: Make this increase "skipped" count, rather than run/success + System.err.println("WARNING: JMagick not installed. Skipping test " + method.getName()); + } + }; } - else { - System.err.println("WARNING: JMagick not installed. Skipping test " + getName()); - } - } + }; } diff --git a/imageio/imageio-jmagick/todo.txt b/imageio/imageio-jmagick/todo.txt index 1d35e265..bd5338cc 100755 --- a/imageio/imageio-jmagick/todo.txt +++ b/imageio/imageio-jmagick/todo.txt @@ -1,5 +1,5 @@ - These readers/writers could probably benefit alot from using JNI with nio bytechannel buffers... RFE to JMagick guys? -- Create stream providers and allow creatig a ImageInputStream from a +- Create stream providers and allow creating an ImageInputStream from a MagickImage? Does that even make sense? Or maybe create File based streams that exposes the file name for JMagick to write directly. \ No newline at end of file diff --git a/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java b/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java index 8a02dea1..6b08185e 100644 --- a/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java +++ b/imageio/imageio-pict/src/test/java/com/twelvemonkeys/imageio/plugins/pict/PICTImageReaderTestCase.java @@ -1,6 +1,7 @@ package com.twelvemonkeys.imageio.plugins.pict; import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase; +import org.junit.Test; import javax.imageio.spi.ImageReaderSpi; import java.awt.*; @@ -8,6 +9,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import static org.junit.Assert.*; + /** * ICOImageReaderTestCase * @@ -59,11 +62,12 @@ public class PICTImageReaderTestCase extends ImageReaderAbstractTestCase { private static final boolean IS_JAVA_6 = SystemUtil.isClassAvailable("java.util.Deque"); - private ThumbsDBImageReaderSpi mProvider = new ThumbsDBImageReaderSpi(); + private ThumbsDBImageReaderSpi provider = new ThumbsDBImageReaderSpi(); protected List getTestData() { return Arrays.asList( @@ -82,12 +83,12 @@ public class ThumbsDBImageReaderTestCase extends ImageReaderAbstractTestCase getReaderClass() { @@ -106,6 +107,7 @@ public class ThumbsDBImageReaderTestCase extends ImageReaderAbstractTestCasetest - - jmock - jmock-cglib - test - @@ -102,14 +97,7 @@ junit junit - 4.3.1 - test - - - - jmock - jmock-cglib - 1.0.1 + 4.7 test diff --git a/sandbox/sandbox-common/pom.xml b/sandbox/sandbox-common/pom.xml index e713c7eb..4a304af7 100644 --- a/sandbox/sandbox-common/pom.xml +++ b/sandbox/sandbox-common/pom.xml @@ -12,7 +12,7 @@ jar TwelveMonkeys :: Sandbox :: Common - The TwelveMonkeys Sandbox Common. Experimental stuff. + The TwelveMonkeys Common Sandbox. Experimental stuff. @@ -28,6 +28,12 @@ compile + + com.twelvemonkeys.imageio + imageio-core + compile + + com.twelvemonkeys.common common-io diff --git a/sandbox/sandbox-swing/pom.xml b/sandbox/sandbox-swing/pom.xml index 79e5b06e..16936b35 100644 --- a/sandbox/sandbox-swing/pom.xml +++ b/sandbox/sandbox-swing/pom.xml @@ -12,7 +12,7 @@ jar TwelveMonkeys :: Sandbox :: Swing - The TwelveMonkeys Sandbox Swing. Experimental stuff. + The TwelveMonkeys Swing Sandbox. Experimental stuff. diff --git a/servlet/pom.xml b/servlet/pom.xml index c6932e13..12078e74 100644 --- a/servlet/pom.xml +++ b/servlet/pom.xml @@ -81,17 +81,10 @@ test - - jmock - jmock-cglib - 1.0.1 - test - - org.mockito mockito-all - 1.8.0 + 1.8.5 diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/FilterAbstractTestCase.java b/servlet/src/test/java/com/twelvemonkeys/servlet/FilterAbstractTestCase.java index be971086..88570a3c 100755 --- a/servlet/src/test/java/com/twelvemonkeys/servlet/FilterAbstractTestCase.java +++ b/servlet/src/test/java/com/twelvemonkeys/servlet/FilterAbstractTestCase.java @@ -115,17 +115,13 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase { } static class MockFilterConfig implements FilterConfig { - private final Map mParams; + private final Map params; - MockFilterConfig() { - this(new HashMap()); - } - - MockFilterConfig(Map pParams) { + MockFilterConfig(Map pParams) { if (pParams == null) { throw new IllegalArgumentException("params == null"); } - mParams = pParams; + params = pParams; } public String getFilterName() { @@ -133,11 +129,11 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase { } public String getInitParameter(String pName) { - return (String) mParams.get(pName); + return params.get(pName); } public Enumeration getInitParameterNames() { - return Collections.enumeration(mParams.keySet()); + return Collections.enumeration(params.keySet()); } public ServletContext getServletContext() { @@ -145,20 +141,20 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase { } private static class MockServletContext implements ServletContext { - private final Map mAttributes; - private final Map mParams; + private final Map attributes; + private final Map params; MockServletContext() { - mAttributes = new HashMap(); - mParams = new HashMap(); + attributes = new HashMap(); + params = new HashMap(); } public Object getAttribute(String s) { - return mAttributes.get(s); + return attributes.get(s); } public Enumeration getAttributeNames() { - return Collections.enumeration(mAttributes.keySet()); + return Collections.enumeration(attributes.keySet()); } public ServletContext getContext(String s) { @@ -166,11 +162,11 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase { } public String getInitParameter(String s) { - return (String) mParams.get(s); + return (String) params.get(s); } public Enumeration getInitParameterNames() { - return Collections.enumeration(mParams.keySet()); + return Collections.enumeration(params.keySet()); } public int getMajorVersion() { @@ -230,40 +226,37 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase { } public void log(Exception exception, String s) { - // TODO: Implement } public void log(String s) { - // TODO: Implement } public void log(String s, Throwable throwable) { - // TODO: Implement } public void removeAttribute(String s) { - mAttributes.remove(s); + attributes.remove(s); } public void setAttribute(String s, Object obj) { - mAttributes.put(s, obj); + attributes.put(s, obj); } } } static class MockServletRequest implements ServletRequest { - final private Map mAttributes; + final private Map attributes; public MockServletRequest() { - mAttributes = new HashMap(); + attributes = new HashMap(); } public Object getAttribute(String pKey) { - return mAttributes.get(pKey); + return attributes.get(pKey); } public Enumeration getAttributeNames() { - return Collections.enumeration(mAttributes.keySet()); + return Collections.enumeration(attributes.keySet()); } public String getCharacterEncoding() { @@ -331,11 +324,11 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase { } public void setAttribute(String pKey, Object pValue) { - mAttributes.put(pKey, pValue); + attributes.put(pKey, pValue); } public void removeAttribute(String pKey) { - mAttributes.remove(pKey); + attributes.remove(pKey); } public Locale getLocale() { diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTestCase.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTestCase.java index b27e6dc6..e462b92f 100755 --- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTestCase.java +++ b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTestCase.java @@ -1,20 +1,21 @@ package com.twelvemonkeys.servlet; import com.twelvemonkeys.util.MapAbstractTestCase; -import org.jmock.Mock; -import org.jmock.core.Invocation; -import org.jmock.core.Stub; -import org.jmock.core.stub.CustomStub; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import javax.servlet.http.HttpServletRequest; import java.util.*; +import static org.mockito.Mockito.when; + /** * ServletConfigMapAdapterTestCase *

* * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTestCase.java#1 $ + * @version $Id: ServletHeadersMapAdapterTestCase.java#1 $ */ public class ServletHeadersMapAdapterTestCase extends MapAbstractTestCase { private static final List HEADER_VALUE_ETAG = Arrays.asList("\"1234567890abcdef\""); @@ -43,24 +44,21 @@ public class ServletHeadersMapAdapterTestCase extends MapAbstractTestCase { } public Map makeEmptyMap() { - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getHeaderNames").will(returnValue(Collections.enumeration(Collections.emptyList()))); - mockRequest.stubs().method("getHeaders").will(returnValue(null)); + HttpServletRequest request = Mockito.mock(HttpServletRequest.class); + when(request.getHeaderNames()).thenAnswer(returnEnumeration(Collections.emptyList())); - return new ServletHeadersMapAdapter((HttpServletRequest) mockRequest.proxy()); + return new ServletHeadersMapAdapter(request); } @Override public Map makeFullMap() { - Mock mockRequest = mock(HttpServletRequest.class); + HttpServletRequest request = Mockito.mock(HttpServletRequest.class); + when(request.getHeaderNames()).thenAnswer(returnEnumeration(Arrays.asList(getSampleKeys()))); + when(request.getHeaders("Date")).thenAnswer(returnEnumeration(HEADER_VALUE_DATE)); + when(request.getHeaders("ETag")).thenAnswer(returnEnumeration(HEADER_VALUE_ETAG)); + when(request.getHeaders("X-Foo")).thenAnswer(returnEnumeration(HEADER_VALUE_FOO)); - mockRequest.stubs().method("getHeaderNames").will(returnEnumeration("ETag", "Date", "X-Foo")); - mockRequest.stubs().method("getHeaders").with(eq("Date")).will(returnEnumeration(HEADER_VALUE_DATE)); - mockRequest.stubs().method("getHeaders").with(eq("ETag")).will(returnEnumeration(HEADER_VALUE_ETAG)); - mockRequest.stubs().method("getHeaders").with(eq("X-Foo")).will(returnEnumeration(HEADER_VALUE_FOO)); - mockRequest.stubs().method("getHeaders").with(not(or(eq("Date"), or(eq("ETag"), eq("X-Foo"))))).will(returnValue(null)); - - return new ServletHeadersMapAdapter((HttpServletRequest) mockRequest.proxy()); + return new ServletHeadersMapAdapter(request); } @Override @@ -73,31 +71,25 @@ public class ServletHeadersMapAdapterTestCase extends MapAbstractTestCase { return new Object[] {HEADER_VALUE_DATE, HEADER_VALUE_ETAG, HEADER_VALUE_FOO}; } - @Override public Object[] getNewSampleValues() { // Needs to be same length but different values return new Object[3]; } - protected Stub returnEnumeration(final Object... pValues) { - return new EnumerationStub(Arrays.asList(pValues)); + protected static ReturnNewEnumeration returnEnumeration(final Collection collection) { + return new ReturnNewEnumeration(collection); } - protected Stub returnEnumeration(final List pValues) { - return new EnumerationStub(pValues); - } + private static class ReturnNewEnumeration implements Answer> { + private final Collection collection; - private static class EnumerationStub extends CustomStub { - private List mValues; - - public EnumerationStub(final List pValues) { - super("Returns a new enumeration"); - mValues = pValues; + private ReturnNewEnumeration(final Collection collection) { + this.collection = collection; } - public Object invoke(Invocation invocation) throws Throwable { - return Collections.enumeration(mValues); + public Enumeration answer(InvocationOnMock invocation) throws Throwable { + return Collections.enumeration(collection); } } -} \ No newline at end of file +} diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletParametersMapAdapterTestCase.java b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletParametersMapAdapterTestCase.java index c24e84f3..9af1ad34 100755 --- a/servlet/src/test/java/com/twelvemonkeys/servlet/ServletParametersMapAdapterTestCase.java +++ b/servlet/src/test/java/com/twelvemonkeys/servlet/ServletParametersMapAdapterTestCase.java @@ -1,14 +1,15 @@ package com.twelvemonkeys.servlet; import com.twelvemonkeys.util.MapAbstractTestCase; -import org.jmock.Mock; -import org.jmock.core.Invocation; -import org.jmock.core.Stub; -import org.jmock.core.stub.CustomStub; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import javax.servlet.http.HttpServletRequest; import java.util.*; +import static org.mockito.Mockito.when; + /** * ServletConfigMapAdapterTestCase *

@@ -43,24 +44,22 @@ public class ServletParametersMapAdapterTestCase extends MapAbstractTestCase { } public Map makeEmptyMap() { - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getParameterNames").will(returnValue(Collections.enumeration(Collections.emptyList()))); - mockRequest.stubs().method("getParameterValues").will(returnValue(null)); + HttpServletRequest request = Mockito.mock(HttpServletRequest.class); + when(request.getParameterNames()).thenAnswer(returnEnumeration(Collections.emptyList())); - return new ServletParametersMapAdapter((HttpServletRequest) mockRequest.proxy()); + return new ServletParametersMapAdapter(request); } @Override public Map makeFullMap() { - Mock mockRequest = mock(HttpServletRequest.class); + HttpServletRequest request = Mockito.mock(HttpServletRequest.class); - mockRequest.stubs().method("getParameterNames").will(returnEnumeration("tag", "date", "foo")); - mockRequest.stubs().method("getParameterValues").with(eq("date")).will(returnValue(PARAM_VALUE_DATE.toArray(new String[PARAM_VALUE_DATE.size()]))); - mockRequest.stubs().method("getParameterValues").with(eq("tag")).will(returnValue(PARAM_VALUE_ETAG.toArray(new String[PARAM_VALUE_ETAG.size()]))); - mockRequest.stubs().method("getParameterValues").with(eq("foo")).will(returnValue(PARAM_VALUE_FOO.toArray(new String[PARAM_VALUE_FOO.size()]))); - mockRequest.stubs().method("getParameterValues").with(not(or(eq("date"), or(eq("tag"), eq("foo"))))).will(returnValue(null)); + when(request.getParameterNames()).thenAnswer(returnEnumeration(Arrays.asList("tag", "date", "foo"))); + when(request.getParameterValues("date")).thenReturn(PARAM_VALUE_DATE.toArray(new String[PARAM_VALUE_DATE.size()])); + when(request.getParameterValues("tag")).thenReturn(PARAM_VALUE_ETAG.toArray(new String[PARAM_VALUE_ETAG.size()])); + when(request.getParameterValues("foo")).thenReturn(PARAM_VALUE_FOO.toArray(new String[PARAM_VALUE_FOO.size()])); - return new ServletParametersMapAdapter((HttpServletRequest) mockRequest.proxy()); + return new ServletParametersMapAdapter(request); } @Override @@ -79,24 +78,19 @@ public class ServletParametersMapAdapterTestCase extends MapAbstractTestCase { return new Object[3]; } - protected Stub returnEnumeration(final Object... pValues) { - return new EnumerationStub(Arrays.asList(pValues)); + protected static ReturnNewEnumeration returnEnumeration(final Collection collection) { + return new ReturnNewEnumeration(collection); } - protected Stub returnEnumeration(final List pValues) { - return new EnumerationStub(pValues); - } + private static class ReturnNewEnumeration implements Answer> { + private final Collection collection; - private static class EnumerationStub extends CustomStub { - private List mValues; - - public EnumerationStub(final List pValues) { - super("Returns a new enumeration"); - mValues = pValues; + private ReturnNewEnumeration(final Collection collection) { + this.collection = collection; } - public Object invoke(Invocation invocation) throws Throwable { - return Collections.enumeration(mValues); + public Enumeration answer(InvocationOnMock invocation) throws Throwable { + return Collections.enumeration(collection); } } } \ No newline at end of file diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTestCase.java b/servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTestCase.java index 4c3b11b5..b5b69f45 100755 --- a/servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTestCase.java +++ b/servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTestCase.java @@ -1,19 +1,26 @@ package com.twelvemonkeys.servlet.cache; -import com.twelvemonkeys.io.FileUtil; import com.twelvemonkeys.net.NetUtil; -import org.jmock.Mock; -import org.jmock.cglib.MockObjectTestCase; -import org.jmock.core.Invocation; -import org.jmock.core.stub.CustomStub; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; +import org.mockito.InOrder; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.*; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + /** * CacheManagerTestCase * @@ -21,31 +28,38 @@ import java.util.*; * @author last modified by $Author: haku $ * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/cache/HTTPCacheTestCase.java#2 $ */ -public class HTTPCacheTestCase extends MockObjectTestCase { - // TODO: Clean up! +public class HTTPCacheTestCase { + @Rule + public final TestName name = new TestName(); - private static final File TEMP_ROOT = new File(FileUtil.getTempDirFile(), "cache-test"); + // TODO: Replace with rule: TemporaryFolder + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); - @Override - protected void setUp() throws Exception { - super.setUp(); - - assertTrue("Could not create temp dir, tests can not run", (TEMP_ROOT.exists() && TEMP_ROOT.isDirectory()) || TEMP_ROOT.mkdirs()); - // Clear temp dir - File[] files = TEMP_ROOT.listFiles(); - for (File file : files) { - file.delete(); - } + private File getTempRoot() { + return temporaryFolder.newFolder("cache-test"); } - @Override - protected void tearDown() throws Exception { - super.tearDown(); + private CacheRequest configureRequest(CacheRequest request, String pRequestURI) { + return configureRequest(request, "GET", pRequestURI, null, null); } + private CacheRequest configureRequest(CacheRequest request, String pMethod, String pRequestURI, Map> pParameters, final Map> pHeaders) { + reset(request); + + when(request.getRequestURI()).thenReturn(URI.create(pRequestURI)); + when(request.getParameters()).thenReturn(pParameters == null ? Collections.>emptyMap() : pParameters); + when(request.getHeaders()).thenReturn(pHeaders == null ? Collections.>emptyMap() : pHeaders); + when(request.getMethod()).thenReturn(pMethod); + + return request; + } + + @SuppressWarnings("deprecation") + @Test public void testCreateNegativeNoName() { try { - new HTTPCache(null, (ServletContext) newDummy(ServletContext.class), 500, 0, 10, true); + new HTTPCache(null, mock(ServletContext.class), 500, 0, 10, true); fail("Expected creation failure, no name"); } catch (IllegalArgumentException expected) { @@ -55,7 +69,7 @@ public class HTTPCacheTestCase extends MockObjectTestCase { } try { - new HTTPCache("", (ServletContext) newDummy(ServletContext.class), 500, 0, 10, true); + new HTTPCache("", mock(ServletContext.class), 500, 0, 10, true); fail("Expected creation failure, empty name"); } catch (IllegalArgumentException expected) { @@ -65,6 +79,8 @@ public class HTTPCacheTestCase extends MockObjectTestCase { } } + @SuppressWarnings("deprecation") + @Test public void testCreateNegativeNoContext() { try { new HTTPCache("Dummy", null, 500, 0, 10, true); @@ -78,6 +94,7 @@ public class HTTPCacheTestCase extends MockObjectTestCase { } + @Test public void testCreateNegativeNoTempFolder() { try { new HTTPCache(null, 500, 0, 10, true); @@ -91,9 +108,10 @@ public class HTTPCacheTestCase extends MockObjectTestCase { } } + @Test public void testCreateNegativeValues() { try { - new HTTPCache(TEMP_ROOT, -1, 0, 10, true); + new HTTPCache(getTempRoot(), -1, 0, 10, true); fail("Expected creation failure"); } catch (IllegalArgumentException expected) { @@ -103,7 +121,7 @@ public class HTTPCacheTestCase extends MockObjectTestCase { } try { - new HTTPCache(TEMP_ROOT, 1000, -1, 10, false); + new HTTPCache(getTempRoot(), 1000, -1, 10, false); fail("Expected creation failure"); } catch (IllegalArgumentException expected) { @@ -113,7 +131,7 @@ public class HTTPCacheTestCase extends MockObjectTestCase { } try { - new HTTPCache(TEMP_ROOT, 1000, 128, -1, true); + new HTTPCache(getTempRoot(), 1000, 128, -1, true); fail("Expected creation failure"); } catch (IllegalArgumentException expected) { @@ -123,216 +141,152 @@ public class HTTPCacheTestCase extends MockObjectTestCase { } } + @Test public void testCreate() { - new HTTPCache(TEMP_ROOT, 500, 0, 10, true); + new HTTPCache(getTempRoot(), 500, 0, 10, true); } + @SuppressWarnings("deprecation") + @Test public void testCreateServletContext() { - Mock mockContext = mock(ServletContext.class); + ServletContext mockContext = mock(ServletContext.class); // Currently context is used for tempdir and logging - mockContext.stubs().method("getAttribute").with(eq("javax.servlet.context.tempdir")).will(returnValue(TEMP_ROOT)); - new HTTPCache("cache", (ServletContext) mockContext.proxy(), 500, 0, 10, true); + when(mockContext.getAttribute(eq("javax.servlet.context.tempdir"))).thenReturn(getTempRoot()); + + new HTTPCache("cache", mockContext, 500, 0, 10, true); } + @Test public void testCacheableRequest() throws IOException, CacheException { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } private String createRequestURI() { - return "http://www.foo.com/" + getName() + ".bar"; + return "http://www.foo.com/" + name.getMethodName() + ".bar"; } + @Test public void testCacheableRequestWithParameters() throws IOException, CacheException { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); Map> parameters = new HashMap>(); parameters.put("foo", Collections.singletonList("bar")); parameters.put("params", Arrays.asList("une", "due", "tres")); - CacheRequest request = configureRequest(mockRequest, "GET", createRequestURI(), parameters, null); + CacheRequest request = configureRequest(mock(CacheRequest.class), "GET", createRequestURI(), parameters, null); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class, "MY-RESOLVER-1"); + doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } - private CacheRequest configureRequest(Mock pMockRequest, String pRequestURI) { - return configureRequest(pMockRequest, "GET", pRequestURI, null, null); - } - - private CacheRequest configureRequest(Mock pMockRequest, String pMethod, String pRequestURI, Map> pParameters, final Map> pHeaders) { - pMockRequest.reset(); - pMockRequest.stubs().method("getRequestURI").will(returnValue(URI.create(pRequestURI))); - pMockRequest.stubs().method("getParameters").will(returnValue(pParameters == null ? Collections.emptyMap() : pParameters)); - pMockRequest.stubs().method("getHeaders").will(returnValue(pHeaders == null ? Collections.emptyMap() : pHeaders)); - pMockRequest.stubs().method("getMethod").will(returnValue(pMethod)); - return (CacheRequest) pMockRequest.proxy(); - } - + @Test public void testCacheablePersistentRepeatedRequest() throws IOException, CacheException { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class, "MY-RESOLVER-2"); + doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockResolver.verify(); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); // Reset result.reset(); - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); + reset(response); + when(response.getOutputStream()).thenReturn(result); // Test request again, make sure resolve is executed exactly once - HTTPCache cache2 = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache2 = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); cache2.doCached(request, response, resolver); // Test that second response is equal to first assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } + @Test public void testCacheableRepeatedRequest() throws IOException, CacheException { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class, "MY-RESOLVER-3"); + doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); @@ -341,18 +295,17 @@ public class HTTPCacheTestCase extends MockObjectTestCase { assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockResolver.verify(); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); // Reset result.reset(); - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); + reset(response); + + // Reconfigure + when(response.getOutputStream()).thenReturn(result); // Test request again, make sure resolve is executed exactly once cache.doCached(request, response, resolver); @@ -361,252 +314,171 @@ public class HTTPCacheTestCase extends MockObjectTestCase { assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } + @Test public void testNonCacheableRequestHeader() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, "GET", createRequestURI(), null, Collections.singletonMap("Cache-Control", Collections.singletonList("no-store"))); + CacheRequest request = configureRequest(mock(CacheRequest.class), "GET", createRequestURI(), null, Collections.singletonMap("Cache-Control", Collections.singletonList("no-store"))); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); // TODO: How do we know that the response was NOT cached? - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } + @Test public void testNonCacheableRequestHeaderRepeated() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); String requestURI = createRequestURI(); - ByteArrayOutputStream result = new ByteArrayOutputStream(); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, requestURI); + CacheRequest request = configureRequest(mock(CacheRequest.class), requestURI); + + ByteArrayOutputStream result = new ByteArrayOutputStream(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); - Mock mockResponse = mock(CacheResponse.class); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockResolver.verify(); + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Reset result.reset(); + reset(response, resolver); - mockRequest.reset(); - mockRequest.stubs().method("getRequestURI").will(returnValue(URI.create(requestURI))); - mockRequest.stubs().method("getParameters").will(returnValue(Collections.emptyMap())); - mockRequest.stubs().method("getHeaders").will(returnValue(Collections.singletonMap("Cache-Control", Collections.singletonList("no-cache")))); // Force non-cached version of cached content - mockRequest.stubs().method("getMethod").will(returnValue("GET")); + // Reconfigure + request = configureRequest(request, "GET", requestURI, null, Collections.singletonMap("Cache-Control", Collections.singletonList("no-cache"))); + when(response.getOutputStream()).thenReturn(result); + doAnswer(new ResolveAnswer(value)).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); + value[3] = 'B'; // Make sure we have a different value second time - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - - mockResolver.reset(); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub2") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - value[3] = 'B'; - - // This cache should not be cached + // This request should not be cached cache.doCached(request, response, resolver); - // Verify that second reponse is ok + // Verify that second response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } + @Test public void testNonCacheableResponseHeader() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Cache-Control"), eq("no-cache")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Cache-Control", "no-cache"); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, Collections.singletonMap("Cache-Control", Collections.singletonList("no-cache")))) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader(eq("Cache-Control"), eq("no-cache")); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } + @Test public void testNonCacheableResponseHeaderRepeated() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Cache-Control"), eq("no-store")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Cache-Control", "no-store"); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, Collections.singletonMap("Cache-Control", Collections.singletonList("no-store")))) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockRequest.verify(); + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader(eq("Cache-Control"), eq("no-store")); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Reset - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Cache-Control"), eq("no-store")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - - mockResolver.reset(); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Cache-Control", "no-store"); - res.getOutputStream().write(value); - - return null; - } - }); result.reset(); + reset(response, resolver); + + // Reconfigure + when(response.getOutputStream()).thenReturn(result); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, Collections.singletonMap("Cache-Control", Collections.singletonList("no-store")))) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); + value[3] = 'B'; // Repeat invocation @@ -616,84 +488,63 @@ public class HTTPCacheTestCase extends MockObjectTestCase { assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader(eq("Cache-Control"), eq("no-store")); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } // Test non-cacheable response + @Test public void testNonCacheableResponse() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); ByteArrayOutputStream result = new ByteArrayOutputStream(); - Mock mockResponse = mock(CacheResponse.class); - mockResponse.expects(once()).method("setStatus").with(eq(500)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(500); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, value, null)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } // Test non-cacheable response + @Test public void testNonCacheableResponseRepeated() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); ByteArrayOutputStream result = new ByteArrayOutputStream(); - Mock mockResponse = mock(CacheResponse.class); - mockResponse.expects(once()).method("setStatus").with(eq(500)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(500); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, value, null)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); @@ -703,64 +554,53 @@ public class HTTPCacheTestCase extends MockObjectTestCase { assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockResolver.verify(); + verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); - // Test request again, should do new resolve... + // Reset result.reset(); + reset(response, resolver); + + // Reconfigure + when(response.getOutputStream()).thenReturn(result); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, value, null)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); value[3] = 'B'; - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(500)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - - mockResolver.reset(); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(500); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.getOutputStream().write(value); - - return null; - } - }); - // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + // Verify new resolve + verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } - // Test that request headers are forwarded to resolver... + @Test public void testRequestHeadersForwarded() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); final Map> headers = new LinkedHashMap>(); headers.put("Cache-Control", Arrays.asList("no-cache")); headers.put("X-Custom", Arrays.asList("FOO", "BAR")); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, "HEAD", createRequestURI(), null, headers); + CacheRequest request = configureRequest(mock(CacheRequest.class), "HEAD", createRequestURI(), null, headers); + CacheResponse response = mock(CacheResponse.class); - Mock mockResponse = mock(CacheResponse.class); - CacheResponse response = (CacheResponse) mockResponse.proxy(); - - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new Answer() { + public Void answer(InvocationOnMock invocation) throws Throwable { + CacheRequest req = (CacheRequest) invocation.getArguments()[0]; Map> reqHeaders = req.getHeaders(); assertEquals(headers, reqHeaders); @@ -768,48 +608,42 @@ public class HTTPCacheTestCase extends MockObjectTestCase { // Make sure that we preserve insertion order Set>> expected = headers.entrySet(); Iterator>> actual = reqHeaders.entrySet().iterator(); + for (Map.Entry> entry : expected) { assertEquals(entry, actual.next()); } return null; } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + }).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); + + // Verify that custom resolve was invoked + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } // Test that response headers are preserved + @Test public void testCacheablePreserveResponseHeaders() throws IOException, CacheException { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); - + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); + ByteArrayOutputStream result = new ByteArrayOutputStream(); - Mock mockResponse = mock(CacheResponse.class); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method(or(eq("setHeader"), eq("addHeader"))).with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method(or(eq("setHeader"), eq("addHeader"))).with(eq("Cache-Control"), eq("public")); - mockResponse.expects(atLeastOnce()).method(or(eq("setHeader"), eq("addHeader"))).with(eq("X-Custom"), eq("FOO")).id("firstCustom"); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("addHeader").with(eq("X-Custom"), eq("BAR")).after("firstCustom"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); final byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.stubs().method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new Answer() { + public Void answer(InvocationOnMock invocation) throws Throwable { + CacheResponse res = (CacheResponse) invocation.getArguments()[1]; - res.setStatus(HTTPCache.STATUS_OK); + res.setStatus(HttpServletResponse.SC_OK); res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); res.setHeader("Cache-Control", "public"); res.addHeader("X-Custom", "FOO"); @@ -818,215 +652,184 @@ public class HTTPCacheTestCase extends MockObjectTestCase { return null; } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + }).when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response).setHeader(eq("Cache-Control"), eq("public")); + + InOrder ordered = inOrder(response); + // TODO: This test is to fragile, as it relies on internal knowledge of the code tested + // (it doesn't really matter if first invocation is setHeader or addHeader) + // See if we can create a custom VerificationMode for "either/or" + ordered.verify(response).setHeader(eq("X-Custom"), eq("FOO")); + ordered.verify(response).addHeader(eq("X-Custom"), eq("BAR")); + + verify(response, atLeastOnce()).getOutputStream(); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } // Test Vary + @Test public void testVaryMissingRequestHeader() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("X-Foo")); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("X-Foo"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); - final byte[] value = "foobar".getBytes("UTF-8"); + byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); + HashMap> headers = new HashMap>(); + headers.put(HTTPCache.HEADER_CONTENT_TYPE, Arrays.asList("x-foo/bar")); + headers.put("Vary", Arrays.asList("X-Foo")); + headers.put("X-Foo", Arrays.asList("foobar")); + headers.put("X-Other", Arrays.asList("don't care")); - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader(HTTPCache.HEADER_CONTENT_TYPE, "x-foo/bar"); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Vary", "X-Foo"); - res.setHeader("X-Foo", "foobar header"); - res.setHeader("X-Other", "don't care"); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockRequest.verify(); + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "X-Foo"); + + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Reset - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("X-Foo")); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("X-Foo"), ANYTHING); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - result.reset(); + reset(response, resolver); + + // Reconfigure + when(response.getOutputStream()).thenReturn(result); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Repeat invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "X-Foo"); + + verifyNoMoreInteractions(resolver); } + @Test public void testVaryMissingRequestHeaderRepeated() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); - String requestURI = createRequestURI(); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, requestURI); + String requestURI = createRequestURI(); + CacheRequest request = configureRequest(mock(CacheRequest.class), requestURI); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("X-Foo")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); - final byte[] value = "foobar".getBytes("UTF-8"); + byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader(HTTPCache.HEADER_CONTENT_TYPE, "x-foo/bar"); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Vary", "X-Foo"); - res.setHeader("X-Other", "don't care"); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + HashMap> headers = new HashMap>(); + headers.put(HTTPCache.HEADER_CONTENT_TYPE, Arrays.asList("x-foo/bar")); + headers.put("Vary", Arrays.asList("X-Foo")); + headers.put("X-Other", Arrays.asList("don't care")); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockRequest.verify(); + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "X-Foo"); + + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Reset - request = configureRequest(mockRequest, "GET", requestURI, null, Collections.singletonMap("X-Foo", Collections.singletonList("foobar"))); - - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("X-Foo")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - - mockResolver.reset(); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Vary", "X-Foo"); - res.setHeader("X-Other", "don't care"); - res.getOutputStream().write(value); - - return null; - } - }); result.reset(); + request = configureRequest(request, "GET", requestURI, null, Collections.singletonMap("X-Foo", Collections.singletonList("foobar"))); + reset(response, resolver); + + // Reconfigure + when(response.getOutputStream()).thenReturn(result); + + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); value[3] = 'B'; // Repeat invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - } + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "X-Foo"); + + // Different X-Foo header, must re-validate + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); + } + + @Test public void testVarySameResourceIsCached() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, "GET", createRequestURI(), null, Collections.singletonMap("X-Foo", Collections.singletonList("foobar value"))); + CacheRequest request = configureRequest(mock(CacheRequest.class), "GET", createRequestURI(), null, Collections.singletonMap("X-Foo", Collections.singletonList("foobar value"))); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("X-Foo")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); - final byte[] value = "foobar".getBytes("UTF-8"); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); + byte[] value = "foobar".getBytes("UTF-8"); - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Vary", "X-Foo"); - res.setHeader("X-Other", "don't care"); - res.getOutputStream().write(value); + HashMap> headers = new HashMap>(); + headers.put(HTTPCache.HEADER_CONTENT_TYPE, Arrays.asList("x-foo/bar")); + headers.put("Vary", Arrays.asList("X-Foo")); + headers.put("X-Other", Arrays.asList("don't care")); - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); @@ -1036,106 +839,84 @@ public class HTTPCacheTestCase extends MockObjectTestCase { assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockRequest.verify(); + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "X-Foo"); + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Reset - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("X-Foo")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - + reset(response); result.reset(); + // Reconfigure + when(response.getOutputStream()).thenReturn(result); + // Repeat invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "X-Foo"); + + verifyNoMoreInteractions(resolver); } + @Test public void testVaryDifferentResources() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); - String requestURI = createRequestURI(); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, "GET", requestURI, null, Collections.singletonMap("X-Foo", Collections.singletonList("foo"))); + String requestURI = createRequestURI(); + CacheRequest request = configureRequest(mock(CacheRequest.class), requestURI); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("X-Foo")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); - final byte[] value = "foo".getBytes("UTF-8"); + byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); + HashMap> headers = new HashMap>(); + headers.put(HTTPCache.HEADER_CONTENT_TYPE, Arrays.asList("x-foo/bar")); + headers.put("Vary", Arrays.asList("X-Foo")); + headers.put("X-Other", Arrays.asList("don't care")); - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Vary", "X-Foo"); - res.setHeader("X-Other", "don't care"); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockRequest.verify(); + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "X-Foo"); + + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Reset - request = configureRequest(mockRequest, "GET", requestURI, null, Collections.singletonMap("X-Foo", Collections.singletonList("bar"))); - - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("X-Foo")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - - mockResolver.reset(); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Vary", "X-Foo"); - res.setHeader("Cache-Control", "no-store"); - res.getOutputStream().write(value); - - return null; - } - }); result.reset(); + request = configureRequest(request, "GET", requestURI, null, Collections.singletonMap("X-Foo", Collections.singletonList("bar"))); + reset(response, resolver); + + // Reconfigure + when(response.getOutputStream()).thenReturn(result); + headers.put("Cache-Control", Arrays.asList("no-store")); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); + value[0] = 'b'; value[1] = 'a'; value[2] = 'r'; @@ -1143,46 +924,40 @@ public class HTTPCacheTestCase extends MockObjectTestCase { // Repeat invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "X-Foo"); + verify(response, atLeastOnce()).setHeader("Cache-Control", "no-store"); + + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } + @Test public void testVaryStarNonCached() throws Exception { - HTTPCache cache = new HTTPCache(TEMP_ROOT, 60000, 1024 * 1024, 10, true); + HTTPCache cache = new HTTPCache(getTempRoot(), 60000, 1024 * 1024, 10, true); // Custom setup - Mock mockRequest = mock(CacheRequest.class); - CacheRequest request = configureRequest(mockRequest, createRequestURI()); + CacheRequest request = configureRequest(mock(CacheRequest.class), createRequestURI()); - Mock mockResponse = mock(CacheResponse.class); ByteArrayOutputStream result = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("*")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - CacheResponse response = (CacheResponse) mockResponse.proxy(); + CacheResponse response = mock(CacheResponse.class); + when(response.getOutputStream()).thenReturn(result); - final byte[] value = "foobar".getBytes("UTF-8"); + byte[] value = "foobar".getBytes("UTF-8"); - Mock mockResolver = mock(ResponseResolver.class); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); + HashMap> headers = new HashMap>(); + headers.put(HTTPCache.HEADER_CONTENT_TYPE, Arrays.asList("x-foo/bar")); + headers.put("Vary", Arrays.asList("*")); - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Vary", "*"); - res.getOutputStream().write(value); - - return null; - } - }); - ResponseResolver resolver = (ResponseResolver) mockResolver.proxy(); + ResponseResolver resolver = mock(ResponseResolver.class); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Do the invocation cache.doCached(request, response, resolver); @@ -1192,117 +967,176 @@ public class HTTPCacheTestCase extends MockObjectTestCase { assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); - mockRequest.verify(); - mockResponse.verify(); - mockRequest.verify(); + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "*"); + + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); // Reset - mockResponse.reset(); - mockResponse.expects(once()).method("setStatus").with(eq(HTTPCache.STATUS_OK)); - mockResponse.stubs().method("setHeader"); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Date"), ANYTHING); - mockResponse.expects(atLeastOnce()).method("setHeader").with(eq("Vary"), eq("*")); - mockResponse.stubs().method("addHeader"); - mockResponse.expects(atLeastOnce()).method("getOutputStream").will(returnValue(result)); - - mockResolver.reset(); - mockResolver.expects(once()).method("resolve").will(new CustomStub("request resolver stub") { - public Void invoke(Invocation invocation) throws Throwable { - CacheRequest req = (CacheRequest) invocation.parameterValues.get(0); - CacheResponse res = (CacheResponse) invocation.parameterValues.get(1); - - res.setStatus(HTTPCache.STATUS_OK); - res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); - res.setHeader("Vary", "*"); - res.getOutputStream().write(value); - - return null; - } - }); result.reset(); + reset(response, resolver); + + // Reconfigure + when(response.getOutputStream()).thenReturn(result); + headers.put("Cache-Control", Arrays.asList("no-store")); + doAnswer(new ResolveAnswer(HttpServletResponse.SC_OK, value, headers)) + .when(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); + value[3] = 'B'; // Repeat invocation cache.doCached(request, response, resolver); - // Verify that reponse is ok + // Verify that response is ok assertEquals(value.length, result.size()); assertEquals(new String(value, "UTF-8"), new String(result.toByteArray(), "UTF-8")); assertTrue(Arrays.equals(value, result.toByteArray())); + + verify(response).setStatus(HttpServletResponse.SC_OK); + verify(response, atLeastOnce()).getOutputStream(); + verify(response, atLeastOnce()).setHeader(eq("Date"), anyString()); + verify(response, atLeastOnce()).setHeader("Vary", "*"); + + verify(resolver).resolve(any(CacheRequest.class), any(CacheResponse.class)); } - /* + @Ignore("TODO") + @Test public void testVaryVariations() { fail("TODO"); } - public void testVarationsWithSameContentType() { + @Ignore("TODO") + @Test + public void testVariationsWithSameContentType() { // I believe there is a bug if two variations has same content type... fail("TODO"); } + @Ignore("TODO") + @Test // Test failing request (IOException) public void testIOException() { fail("TODO"); } + @Ignore("TODO") + @Test public void testCacheException() { fail("TODO"); } + @Ignore("TODO") + @Test public void testRuntimeException() { fail("TODO"); } + @Ignore("TODO") + @Test // Test failing (negative) HTTP response (401, 404, 410, 500, etc) public void testNegativeCache() { fail("TODO"); } + @Ignore("TODO") + @Test public void testNegativeCacheExpires() { fail("TODO"); } + @Ignore("TODO") + @Test // Test If-None-Match/ETag support public void testIfNoneMatch() { fail("TODO"); } + @Ignore("TODO") + @Test // Test If-Modified-Since support public void testIfModifiedSince() { fail("TODO"); } + @Ignore("TODO") + @Test // Test that data really expires when TTL is over public void testTimeToLive() { fail("TODO"); } + @Ignore("TODO") + @Test public void testMaxAgeRequest() { fail("TODO"); } - // Test that for requests with authorization, responses are not shared between different authorized users, unless response is marked as Cache-Control: public + @Ignore("TODO") + @Test + // Test that for requests with authorization, responses are not shared between different authorized users, unless response is marked as Cache-Control: public public void testAuthorizedRequestPublic() { fail("TODO"); } + @Ignore("TODO") + @Test public void testAuthorizedRequestPrivate() { fail("TODO"); } + @Ignore("TODO") + @Test public void testPutPostDeleteInvalidatesCache() { fail("TODO"); } + @Ignore("TODO") + @Test // TODO: Move out to separate package/test, just keep it here for PoC public void testClientRequest() { fail("Not implemented"); } + @Ignore("TODO") + @Test // TODO: Move out to separate package/test, just keep it here for PoC public void testServletRequest() { fail("Not implemented"); } - */ + + private static class ResolveAnswer implements Answer { + private final int status; + private final byte[] value; + private final Map> headers; + + public ResolveAnswer(byte[] value) { + this(HttpServletResponse.SC_OK, value, null); + } + + public ResolveAnswer(final int status, byte[] value, Map> headers) { + this.status = status; + this.value = value; + this.headers = headers != null ? headers : Collections.>emptyMap(); + } + + public Void answer(InvocationOnMock invocation) throws Throwable { + CacheResponse res = (CacheResponse) invocation.getArguments()[1]; + + res.setStatus(status); + res.setHeader("Date", NetUtil.formatHTTPDate(System.currentTimeMillis())); + + for (Map.Entry> header : headers.entrySet()) { + for (String value : header.getValue()) { + res.addHeader(header.getKey(), value); + } + } + + res.getOutputStream().write(value); + + return null; + } + } } diff --git a/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTestCase.java b/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTestCase.java index ec769165..cada4ba5 100755 --- a/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTestCase.java +++ b/servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTestCase.java @@ -1,10 +1,11 @@ package com.twelvemonkeys.servlet.image; +import com.twelvemonkeys.image.BufferedImageIcon; import com.twelvemonkeys.image.ImageUtil; import com.twelvemonkeys.io.FileUtil; import com.twelvemonkeys.servlet.OutputStreamAdapter; -import org.jmock.Mock; -import org.jmock.cglib.MockObjectTestCase; +import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import javax.imageio.ImageIO; @@ -12,11 +13,19 @@ import javax.servlet.ServletContext; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; import java.util.Arrays; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + /** * ImageServletResponseImplTestCase * @@ -24,7 +33,7 @@ import java.util.Arrays; * @author last modified by $Author: haku $ * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/image/ImageServletResponseImplTestCase.java#6 $ */ -public class ImageServletResponseImplTestCase extends MockObjectTestCase { +public class ImageServletResponseImplTestCase { private static final String CONTENT_TYPE_BMP = "image/bmp"; private static final String CONTENT_TYPE_FOO = "foo/bar"; private static final String CONTENT_TYPE_GIF = "image/gif"; @@ -38,31 +47,43 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { private static final Dimension IMAGE_DIMENSION_PNG = new Dimension(300, 410); private static final Dimension IMAGE_DIMENSION_GIF = new Dimension(250, 250); - private HttpServletRequest mRequest; - private ServletContext mContext; + private HttpServletRequest request; + private ServletContext context; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void init() throws Exception { + request = mock(HttpServletRequest.class); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").will(returnValue(null)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - mRequest = (HttpServletRequest) mockRequest.proxy(); +// mockRequest.stubs().method("getAttribute").will(returnValue(null)); +// mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); +// mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); +// mockRequest.stubs().method("getParameter").will(returnValue(null)); +// request = (HttpServletRequest) mockRequest.proxy(); - Mock mockContext = mock(ServletContext.class); - mockContext.stubs().method("getResource").with(eq("/" + IMAGE_NAME_PNG)).will(returnValue(getClass().getResource(IMAGE_NAME_PNG))); - mockContext.stubs().method("getResource").with(eq("/" + IMAGE_NAME_GIF)).will(returnValue(getClass().getResource(IMAGE_NAME_GIF))); - mockContext.stubs().method("log").withAnyArguments(); // Just suppress the logging - mockContext.stubs().method("getMimeType").with(eq("file.bmp")).will(returnValue(CONTENT_TYPE_BMP)); - mockContext.stubs().method("getMimeType").with(eq("file.foo")).will(returnValue(CONTENT_TYPE_FOO)); - mockContext.stubs().method("getMimeType").with(eq("file.gif")).will(returnValue(CONTENT_TYPE_GIF)); - mockContext.stubs().method("getMimeType").with(eq("file.jpeg")).will(returnValue(CONTENT_TYPE_JPEG)); - mockContext.stubs().method("getMimeType").with(eq("file.png")).will(returnValue(CONTENT_TYPE_PNG)); - mockContext.stubs().method("getMimeType").with(eq("file.txt")).will(returnValue(CONTENT_TYPE_TEXT)); - mContext = (ServletContext) mockContext.proxy(); + context = mock(ServletContext.class); + when(context.getResource("/" + IMAGE_NAME_PNG)).thenReturn(getClass().getResource(IMAGE_NAME_PNG)); + when(context.getResource("/" + IMAGE_NAME_GIF)).thenReturn(getClass().getResource(IMAGE_NAME_GIF)); + when(context.getMimeType("file.bmp")).thenReturn(CONTENT_TYPE_BMP); + when(context.getMimeType("file.foo")).thenReturn(CONTENT_TYPE_FOO); + when(context.getMimeType("file.gif")).thenReturn(CONTENT_TYPE_GIF); + when(context.getMimeType("file.jpeg")).thenReturn(CONTENT_TYPE_JPEG); + when(context.getMimeType("file.png")).thenReturn(CONTENT_TYPE_PNG); + when(context.getMimeType("file.txt")).thenReturn(CONTENT_TYPE_TEXT); + + +// Mock mockContext = mock(ServletContext.class); +// mockContext.stubs().method("getResource").with(eq("/" + IMAGE_NAME_PNG)).will(returnValue(getClass().getResource(IMAGE_NAME_PNG))); +// mockContext.stubs().method("getResource").with(eq("/" + IMAGE_NAME_GIF)).will(returnValue(getClass().getResource(IMAGE_NAME_GIF))); +// mockContext.stubs().method("log").withAnyArguments(); // Just suppress the logging +// mockContext.stubs().method("getMimeType").with(eq("file.bmp")).will(returnValue(CONTENT_TYPE_BMP)); +// mockContext.stubs().method("getMimeType").with(eq("file.foo")).will(returnValue(CONTENT_TYPE_FOO)); +// mockContext.stubs().method("getMimeType").with(eq("file.gif")).will(returnValue(CONTENT_TYPE_GIF)); +// mockContext.stubs().method("getMimeType").with(eq("file.jpeg")).will(returnValue(CONTENT_TYPE_JPEG)); +// mockContext.stubs().method("getMimeType").with(eq("file.png")).will(returnValue(CONTENT_TYPE_PNG)); +// mockContext.stubs().method("getMimeType").with(eq("file.txt")).will(returnValue(CONTENT_TYPE_TEXT)); +// context = (ServletContext) mockContext.proxy(); } private void fakeResponse(HttpServletRequest pRequest, ImageServletResponseImpl pImageResponse) throws IOException { @@ -78,7 +99,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { } else { String ext = name.substring(name.lastIndexOf(".")); - pImageResponse.setContentType(mContext.getMimeType("file" + ext)); + pImageResponse.setContentType(context.getMimeType("file" + ext)); pImageResponse.setContentLength(234); try { ServletOutputStream out = pImageResponse.getOutputStream(); @@ -95,15 +116,19 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { } } + @Test public void testBasicResponse() throws IOException { - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + +// Mock mockResponse = mock(HttpServletResponse.class); +// mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); +// mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(mRequest, response, mContext); - fakeResponse(mRequest, imageResponse); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); + fakeResponse(request, imageResponse); // Make sure image is correctly loaded BufferedImage image = imageResponse.getImage(); @@ -121,21 +146,27 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).setContentType(CONTENT_TYPE_PNG); + verify(response).getOutputStream(); } // Test that wrapper works as a no-op, in case the image does not need to be decoded // This is not a very common use case, as filters should avoid wrapping the response // for performance reasons, but we still want that to work + @Test public void testNoOpResponse() throws IOException { - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); +// mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); +// mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(mRequest, response, mContext); - fakeResponse(mRequest, imageResponse); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); + fakeResponse(request, imageResponse); // TODO: Is there a way we can avoid calling flush? // Flush image to wrapped response @@ -145,19 +176,26 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { // Test that image data is untouched assertTrue("Data differs", Arrays.equals(FileUtil.read(getClass().getResourceAsStream(IMAGE_NAME_PNG)), out.toByteArray())); + + verify(response).setContentType(CONTENT_TYPE_PNG); + verify(response).getOutputStream(); } // Transcode original PNG to JPEG with no other changes - public void testTranscodeResponse() throws IOException { - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_JPEG)); + @Test + public void testTranscodeResponsePNGToJPEG() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(mRequest, response, mContext); - fakeResponse(mRequest, imageResponse); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); +// Mock mockResponse = mock(HttpServletResponse.class); +// mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_JPEG)); +// mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); + fakeResponse(request, imageResponse); // Force transcode to JPEG imageResponse.setOutputContentType("image/jpeg"); @@ -181,7 +219,7 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth()); assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight()); - BufferedImage image = flatten(ImageIO.read(mContext.getResource("/" + IMAGE_NAME_PNG)), Color.BLACK); + BufferedImage image = flatten(ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG)), Color.BLACK); /* tempFile = File.createTempFile("imageservlet-test-", ".png"); @@ -193,25 +231,159 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { // JPEG compression trashes the image completely... assertSimilarImage(image, outImage, 144f); + + verify(response).setContentType(CONTENT_TYPE_JPEG); + verify(response).getOutputStream(); + } + + @Ignore + @Test + public void testTranscodeResponsePNGToGIFWithQuality() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); + +// Mock mockResponse = mock(HttpServletResponse.class); +// mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_GIF)); +// mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); + fakeResponse(request, imageResponse); + + // Force transcode to GIF + imageResponse.setOutputContentType("image/gif"); + // TODO: Set quality...! + + // Flush image to wrapped response + imageResponse.flush(); + + assertTrue("Content has no data", out.size() > 0); + + // Test that image data is still readable + BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray())); + assertNotNull(outImage); + assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth()); + assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight()); + + BufferedImage image = ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG)); + + /* + showIt(outImage, image); + */ + + // Should keep transparency, but is now binary + assertSimilarImageTransparent(image, outImage, 5f); + + verify(response).setContentType(CONTENT_TYPE_GIF); + verify(response).getOutputStream(); + } + + @Ignore + @Test + public void testTranscodeResponsePNGToGIF() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); + +// Mock mockResponse = mock(HttpServletResponse.class); +// mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_GIF)); +// mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); + fakeResponse(request, imageResponse); + + // Force transcode to GIF + imageResponse.setOutputContentType("image/gif"); + + // Flush image to wrapped response + imageResponse.flush(); + + assertTrue("Content has no data", out.size() > 0); + + // Test that image data is still readable + BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray())); + assertNotNull(outImage); + assertEquals(IMAGE_DIMENSION_PNG.width, outImage.getWidth()); + assertEquals(IMAGE_DIMENSION_PNG.height, outImage.getHeight()); + + BufferedImage image = ImageIO.read(context.getResource("/" + IMAGE_NAME_PNG)); + + BufferedImage diff = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY); + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + int rgbIn = image.getRGB(x, y); + int rgbOut = outImage.getRGB(x, y); + + int aDiff = (rgbIn >> 24) & 0xff - (rgbOut >> 24) & 0xff; + int rDiff = (rgbIn >> 16) & 0xff - (rgbOut >> 16) & 0xff; + int gDiff = (rgbIn >> 8) & 0xff - (rgbOut >> 8) & 0xff; + int bDiff = rgbIn & 0xff - rgbOut & 0xff; + + int gray = Math.min((int) Math.round((Math.abs(rDiff) + Math.abs(gDiff) + Math.abs(bDiff)) / 3d), 255); + + diff.setRGB(x, y, gray << 16 | gray << 8 | gray); + } + } + + + /**/ + showIt(image, outImage, diff); + //*/ + + // Should keep transparency, but is now binary + assertSimilarImageTransparent(image, outImage, 5f); + + verify(response).setContentType(CONTENT_TYPE_GIF); + verify(response).getOutputStream(); + } + + private static void showIt(final BufferedImage expected, final BufferedImage actual, final BufferedImage diff) { + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0)); + panel.add(new BlackLabel("expected", expected)); + panel.add(new BlackLabel("actual", actual)); + if (diff != null) { + panel.add(new BlackLabel("diff", diff)); + } + JScrollPane scroll = new JScrollPane(panel); + scroll.setBorder(BorderFactory.createEmptyBorder()); + JOptionPane.showMessageDialog(null, scroll); + } + }); + } + catch (InterruptedException ignore) { + } + catch (InvocationTargetException ignore) { + } } @Test public void testTranscodeResponseIndexedCM() throws IOException { // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").will(returnValue(null)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_GIF)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_GIF); +// Mock mockRequest = mock(HttpServletRequest.class); +// mockRequest.stubs().method("getAttribute").will(returnValue(null)); +// mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); +// mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_GIF)); +// mockRequest.stubs().method("getParameter").will(returnValue(null)); +// HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_JPEG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); +// Mock mockResponse = mock(HttpServletResponse.class); +// mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_JPEG)); +// mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Force transcode to JPEG @@ -223,28 +395,12 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertTrue("Content has no data", out.size() > 0); // Test that image data is still readable - /* - File tempFile = File.createTempFile("imageservlet-test-", ".jpeg"); - FileOutputStream stream = new FileOutputStream(tempFile); - out.writeTo(stream); - stream.close(); - System.err.println("open " + tempFile); - */ - BufferedImage outImage = ImageIO.read(new ByteArrayInputStream(out.toByteArray())); assertNotNull(outImage); assertEquals(IMAGE_DIMENSION_GIF.width, outImage.getWidth()); assertEquals(IMAGE_DIMENSION_GIF.height, outImage.getHeight()); - BufferedImage image = flatten(ImageIO.read(mContext.getResource("/" + IMAGE_NAME_GIF)), Color.WHITE); - - /* - tempFile = File.createTempFile("imageservlet-test-", ".png"); - stream = new FileOutputStream(tempFile); - ImageIO.write(image, "PNG", stream); - stream.close(); - System.err.println("open " + tempFile); - */ + BufferedImage image = flatten(ImageIO.read(context.getResource("/" + IMAGE_NAME_GIF)), Color.WHITE); assertSimilarImage(image, outImage, 96f); } @@ -275,28 +431,51 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { private void assertSimilarImage(final BufferedImage pExpected, final BufferedImage pActual, final float pArtifactThreshold) { for (int y = 0; y < pExpected.getHeight(); y++) { for (int x = 0; x < pExpected.getWidth(); x++) { - int original = pExpected.getRGB(x, y); + int expected = pExpected.getRGB(x, y); int actual = pActual.getRGB(x, y); // Multiply in the alpha component - float alpha = ((original >> 24) & 0xff) / 255f; + float alpha = ((expected >> 24) & 0xff) / 255f; - assertEquals(alpha * ((original >> 16) & 0xff), (actual >> 16) & 0xff, pArtifactThreshold); - assertEquals(alpha * ((original >> 8) & 0xff), (actual >> 8) & 0xff, pArtifactThreshold); - assertEquals(alpha * ((original) & 0xff), actual & 0xff, pArtifactThreshold); + assertEquals(alpha * ((expected >> 16) & 0xff), (actual >> 16) & 0xff, pArtifactThreshold); + assertEquals(alpha * ((expected >> 8) & 0xff), (actual >> 8) & 0xff, pArtifactThreshold); + assertEquals(alpha * ((expected) & 0xff), actual & 0xff, pArtifactThreshold); } } } - public void testReplaceResponse() throws IOException { - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_BMP)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + private void assertSimilarImageTransparent(final BufferedImage pExpected, final BufferedImage pActual, final float pArtifactThreshold) { + for (int y = 0; y < pExpected.getHeight(); y++) { + for (int x = 0; x < pExpected.getWidth(); x++) { + int expected = pExpected.getRGB(x, y); + int actual = pActual.getRGB(x, y); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(mRequest, response, mContext); - fakeResponse(mRequest, imageResponse); + int alpha = (expected >> 24) & 0xff; + boolean transparent = alpha < 40; + if (transparent) { + assertEquals(0, (actual >> 24) & 0xff); + } + else { + assertEquals((expected >> 16) & 0xff, (actual >> 16) & 0xff, pArtifactThreshold); + assertEquals((expected >> 8) & 0xff, (actual >> 8) & 0xff, pArtifactThreshold); + assertEquals( expected & 0xff, actual & 0xff, pArtifactThreshold); + } + } + } + } + + @Test + public void testReplaceResponse() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); +// Mock mockResponse = mock(HttpServletResponse.class); +// mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_BMP)); +// mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); + fakeResponse(request, imageResponse); // Make sure image is correctly loaded BufferedImage image = imageResponse.getImage(); @@ -320,6 +499,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); assertSimilarImage(image, outImage, 0); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_BMP); } // TODO: Test with AOI attributes (rename thes to source-region?) @@ -328,42 +510,54 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { // Make sure we don't change semantics here... + @Test public void testNotFoundInput() throws IOException { - // Need speical setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").will(returnValue(null)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/monkey-business.gif")); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - mRequest = (HttpServletRequest) mockRequest.proxy(); + // Need special setup + request = mock(HttpServletRequest.class); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/monkey-business.gif"); +// Mock mockRequest = mock(HttpServletRequest.class); +// mockRequest.stubs().method("getAttribute").will(returnValue(null)); +// mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); +// mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/monkey-business.gif")); +// mockRequest.stubs().method("getParameter").will(returnValue(null)); +// request = (HttpServletRequest) mockRequest.proxy(); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("sendError").with(eq(404), ANYTHING); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); +// Mock mockResponse = mock(HttpServletResponse.class); +// mockResponse.expects(once()).method("sendError").with(eq(404), ANYTHING); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(mRequest, response, mContext); - fakeResponse(mRequest, imageResponse); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); + fakeResponse(request, imageResponse); + + verify(response).sendError(eq(HttpServletResponse.SC_NOT_FOUND), anyString()); } // NOTE: This means it's up to some Filter to decide wether we should filter the given request + @Test public void testUnsupportedInput() throws IOException { assertFalse("Test is invalid, rewrite test", ImageIO.getImageReadersByFormatName("txt").hasNext()); - // Need speical setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").will(returnValue(null)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/foo.txt")); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - mRequest = (HttpServletRequest) mockRequest.proxy(); + // Need special setup + request = mock(HttpServletRequest.class); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/foo.txt"); +// Mock mockRequest = mock(HttpServletRequest.class); +// mockRequest.stubs().method("getAttribute").will(returnValue(null)); +// mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); +// mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/foo.txt")); +// mockRequest.stubs().method("getParameter").will(returnValue(null)); +// request = (HttpServletRequest) mockRequest.proxy(); - Mock mockResponse = mock(HttpServletResponse.class); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); +// Mock mockResponse = mock(HttpServletResponse.class); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(mRequest, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); - fakeResponse(mRequest, imageResponse); + fakeResponse(request, imageResponse); try { // Force transcode imageResponse.setOutputContentType("image/png"); @@ -375,22 +569,25 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { } catch (IOException e) { String message = e.getMessage().toLowerCase(); - assertTrue("Wrong message: " + e.getMessage(), message.indexOf("transcode") >= 0); - assertTrue("Wrong message: " + e.getMessage(), message.indexOf("reader") >= 0); - assertTrue("Wrong message: " + e.getMessage(), message.indexOf("text") >= 0); - // Failure here suggests a different failurfe condition than the one we expected + assertTrue("Wrong message: " + e.getMessage(), message.contains("transcode")); + assertTrue("Wrong message: " + e.getMessage(), message.contains("reader")); + assertTrue("Wrong message: " + e.getMessage(), message.contains("text")); + + // Failure here suggests a different error condition than the one we expected } } + @Test public void testUnsupportedOutput() throws IOException { assertFalse("Test is invalid, rewrite test", ImageIO.getImageWritersByFormatName("foo").hasNext()); - Mock mockResponse = mock(HttpServletResponse.class); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); +// Mock mockResponse = mock(HttpServletResponse.class); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(mRequest, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); - fakeResponse(mRequest, imageResponse); + fakeResponse(request, imageResponse); try { // Force transcode to unsupported format imageResponse.setOutputContentType("application/xml+foo"); @@ -402,10 +599,11 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { } catch (IOException e) { String message = e.getMessage().toLowerCase(); - assertTrue("Wrong message: " + e.getMessage(), message.indexOf("transcode") >= 0); - assertTrue("Wrong message: " + e.getMessage(), message.indexOf("writer") >= 0); - assertTrue("Wrong message: " + e.getMessage(), message.indexOf("foo") >= 0); - // Failure here suggests a different failurfe condition than the one we expected + assertTrue("Wrong message: " + e.getMessage(), message.contains("transcode")); + assertTrue("Wrong message: " + e.getMessage(), message.contains("writer")); + assertTrue("Wrong message: " + e.getMessage(), message.contains("foo")); + + // Failure here suggests a different error condition than the one we expected } } @@ -419,21 +617,28 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { public void testReadWithSourceRegion() throws IOException { Rectangle sourceRegion = new Rectangle(100, 100, 100, 100); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); + +// Mock mockRequest = mock(HttpServletRequest.class); +// mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); +// mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); +// mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); +// mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); +// mockRequest.stubs().method("getParameter").will(returnValue(null)); +// HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); +// Mock mockResponse = mock(HttpServletResponse.class); +// mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); +// mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); +// HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -452,27 +657,26 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test public void testReadWithNonSquareSourceRegion() throws IOException { Rectangle sourceRegion = new Rectangle(100, 100, 100, 80); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); + + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -491,6 +695,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test @@ -499,22 +706,17 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { Rectangle sourceRegion = new Rectangle(-1, -1, 300, 300); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI_UNIFORM)).will(returnValue(true)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -554,6 +756,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test @@ -562,22 +767,17 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { Rectangle sourceRegion = new Rectangle(-1, -1, 410, 300); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI_UNIFORM)).will(returnValue(true)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -640,6 +840,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test @@ -647,21 +850,16 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { Dimension size = new Dimension(100, 120); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE)).will(returnValue(size)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -690,28 +888,26 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test public void testReadWithNonUniformResize() throws IOException { Dimension size = new Dimension(150, 150); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE)).will(returnValue(size)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE_UNIFORM)).will(returnValue(false)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE_UNIFORM)).thenReturn(false); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -730,6 +926,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test @@ -738,22 +937,17 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { Dimension size = new Dimension(100, 120); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE)).will(returnValue(size)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -782,6 +976,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test @@ -789,23 +986,18 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { Rectangle sourceRegion = new Rectangle(100, 100, 200, 200); Dimension size = new Dimension(150, 150); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE)).will(returnValue(size)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE_UNIFORM)).will(returnValue(false)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE_UNIFORM)).thenReturn(false); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -824,6 +1016,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test @@ -832,23 +1027,18 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { Dimension size = new Dimension(100, 120); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI_UNIFORM)).will(returnValue(true)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE)).will(returnValue(size)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -885,6 +1075,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test @@ -893,23 +1086,18 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { Dimension size = new Dimension(150, 120); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI_UNIFORM)).will(returnValue(true)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE)).will(returnValue(size)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -950,6 +1138,9 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } @Test @@ -958,23 +1149,18 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { Dimension size = new Dimension(100, 120); // Custom setup - Mock mockRequest = mock(HttpServletRequest.class); - mockRequest.stubs().method("getAttribute").withAnyArguments().will(returnValue(null)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI_UNIFORM)).will(returnValue(true)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_AOI)).will(returnValue(sourceRegion)); - mockRequest.stubs().method("getAttribute").with(eq(ImageServletResponse.ATTRIB_SIZE)).will(returnValue(size)); - mockRequest.stubs().method("getContextPath").will(returnValue("/ape")); - mockRequest.stubs().method("getRequestURI").will(returnValue("/ape/" + IMAGE_NAME_PNG)); - mockRequest.stubs().method("getParameter").will(returnValue(null)); - HttpServletRequest request = (HttpServletRequest) mockRequest.proxy(); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI_UNIFORM)).thenReturn(true); + when(request.getAttribute(ImageServletResponse.ATTRIB_AOI)).thenReturn(sourceRegion); + when(request.getAttribute(ImageServletResponse.ATTRIB_SIZE)).thenReturn(size); + when(request.getContextPath()).thenReturn("/ape"); + when(request.getRequestURI()).thenReturn("/ape/" + IMAGE_NAME_PNG); - Mock mockResponse = mock(HttpServletResponse.class); - mockResponse.expects(once()).method("setContentType").with(eq(CONTENT_TYPE_PNG)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - mockResponse.expects(once()).method("getOutputStream").will(returnValue(new OutputStreamAdapter(out))); - HttpServletResponse response = (HttpServletResponse) mockResponse.proxy(); + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getOutputStream()).thenReturn(new OutputStreamAdapter(out)); - ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, mContext); + ImageServletResponseImpl imageResponse = new ImageServletResponseImpl(request, response, context); fakeResponse(request, imageResponse); // Make sure image is correctly loaded @@ -995,28 +1181,36 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { assertNotNull(outImage); assertEquals(image.getWidth(), outImage.getWidth()); assertEquals(image.getHeight(), outImage.getHeight()); + + verify(response).getOutputStream(); + verify(response).setContentType(CONTENT_TYPE_PNG); } // ----------------------------------------------------------------------------------------------------------------- // Absolute AOI // ----------------------------------------------------------------------------------------------------------------- + @Test public void testGetAOIAbsolute() { assertEquals(new Rectangle(10, 10, 100, 100), ImageServletResponseImpl.getAOI(200, 200, 10, 10, 100, 100, false, false)); } + @Test public void testGetAOIAbsoluteOverflowX() { assertEquals(new Rectangle(10, 10, 90, 100), ImageServletResponseImpl.getAOI(100, 200, 10, 10, 100, 100, false, false)); } + @Test public void testGetAOIAbsoluteOverflowW() { assertEquals(new Rectangle(0, 10, 100, 100), ImageServletResponseImpl.getAOI(100, 200, 0, 10, 110, 100, false, false)); } + @Test public void testGetAOIAbsoluteOverflowY() { assertEquals(new Rectangle(10, 10, 100, 90), ImageServletResponseImpl.getAOI(200, 100, 10, 10, 100, 100, false, false)); } + @Test public void testGetAOIAbsoluteOverflowH() { assertEquals(new Rectangle(10, 0, 100, 100), ImageServletResponseImpl.getAOI(200, 100, 10, 0, 100, 110, false, false)); } @@ -1312,4 +1506,16 @@ public class ImageServletResponseImplTestCase extends MockObjectTestCase { // TODO: Test percent // TODO: Test getSize()... + + private static class BlackLabel extends JLabel { + public BlackLabel(final String text, final BufferedImage outImage) { + super(text, new BufferedImageIcon(outImage), JLabel.CENTER); + setOpaque(true); + setBackground(Color.BLACK); + setForeground(Color.WHITE); + setVerticalAlignment(JLabel.CENTER); + setVerticalTextPosition(JLabel.BOTTOM); + setHorizontalTextPosition(JLabel.CENTER); + } + } }