SLING-6429 Hamcrest Matchers: Arrays in ValueMap properties are not compared correctly
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1775840 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/hamcrest/matchers/ResourcePropertiesMatcher.java b/src/main/java/org/apache/sling/hamcrest/matchers/ResourcePropertiesMatcher.java
index 12a3888..e467be1 100644
--- a/src/main/java/org/apache/sling/hamcrest/matchers/ResourcePropertiesMatcher.java
+++ b/src/main/java/org/apache/sling/hamcrest/matchers/ResourcePropertiesMatcher.java
@@ -16,6 +16,7 @@
*/
package org.apache.sling.hamcrest.matchers;
+import java.lang.reflect.Array;
import java.util.Map;
import org.apache.sling.api.resource.Resource;
@@ -25,27 +26,62 @@
public class ResourcePropertiesMatcher extends TypeSafeMatcher<Resource> {
- private final Map<String, Object> properties;
+ private final Map<String, Object> expectedProps;
public ResourcePropertiesMatcher(Map<String, Object> properties) {
if (properties == null || properties.isEmpty()) {
throw new IllegalArgumentException("properties is null or empty");
}
- this.properties = properties;
+ this.expectedProps = properties;
}
@Override
public void describeTo(Description description) {
- description.appendText("Resource with properties ").appendValueList("[", ",", "]", properties.entrySet());
+ description.appendText("Resource with properties ").appendValueList("[", ",", "]", expectedProps.entrySet());
}
@Override
protected boolean matchesSafely(Resource item) {
-
- for (Map.Entry<String, Object> prop : properties.entrySet()) {
- Object value = item.adaptTo(ValueMap.class).get(prop.getKey());
- if ( value == null || !value.equals(prop.getValue())) {
+ ValueMap givenProps = item.adaptTo(ValueMap.class);
+ for (Map.Entry<String, Object> prop : expectedProps.entrySet()) {
+ Object givenValue = givenProps.get(prop.getKey());
+ Object expectedValue = prop.getValue();
+ if (givenValue != null && expectedValue != null
+ && givenValue.getClass().isArray() && expectedValue.getClass().isArray()) {
+ if (!arrayEquals(expectedValue, givenValue)) {
+ return false;
+ }
+ }
+ else {
+ if (!objectEquals(expectedValue, givenValue)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean objectEquals(Object value1, Object value2) {
+ if (value1 == null) {
+ return (value2 == null);
+ }
+ else if (value2 == null) {
+ return (value1 == null);
+ }
+ else {
+ return value1.equals(value2);
+ }
+ }
+
+ private boolean arrayEquals(Object array1, Object array2) {
+ int length1 = Array.getLength(array1);
+ int length2 = Array.getLength(array2);
+ if (length1 != length2) {
+ return false;
+ }
+ for (int i=0; i<length1; i++) {
+ if (!objectEquals(Array.get(array1, i), Array.get(array2, i))) {
return false;
}
}
diff --git a/src/test/java/org/apache/sling/hamcrest/ResourceMatchersTest.java b/src/test/java/org/apache/sling/hamcrest/ResourceMatchersTest.java
index 771d660..15f8ca3 100644
--- a/src/test/java/org/apache/sling/hamcrest/ResourceMatchersTest.java
+++ b/src/test/java/org/apache/sling/hamcrest/ResourceMatchersTest.java
@@ -66,12 +66,14 @@
public void testProps() {
context.build().resource("/resource",
"key1", "value1",
- "key2", "value2",
- "key3", "value3");
+ "key2", 123,
+ "key3", new String[] { "item1", "item2" },
+ "key4", "otherValue");
Map<String, Object> expectedProperties = ImmutableMap.<String, Object>builder()
.put("key1", "value1")
- .put("key2", "value2")
+ .put("key2", 123)
+ .put("key3", new String[] { "item1", "item2" })
.build();
Resource resource = context.resourceResolver().getResource("/resource");
@@ -80,13 +82,13 @@
// test existing key with not matching value
expectedProperties = ImmutableMap.<String, Object>builder()
.put("key1", "value1")
- .put("key2", "value3")
+ .put("key3", "value3")
.build();
Assert.assertThat(resource, Matchers.not(ResourceMatchers.props(expectedProperties)));
// test non-existing key
expectedProperties = ImmutableMap.<String, Object>builder()
- .put("key4", "value4")
+ .put("key5", "value5")
.build();
Assert.assertThat(resource, Matchers.not(ResourceMatchers.props(expectedProperties)));
}
@@ -95,12 +97,14 @@
public void testPropsVarargs() {
context.build().resource("/resource",
"key1", "value1",
- "key2", "value2",
- "key3", "value3");
+ "key2", true,
+ "key3", new int[] { 1, 2, 3 },
+ "key4", "otherValue");
Object[] expectedProperties = new Object[] {
"key1", "value1",
- "key2", "value2"
+ "key2", true,
+ "key3", new int[] { 1, 2, 3 }
};
Resource resource = context.resourceResolver().getResource("/resource");
@@ -109,13 +113,31 @@
// test existing key with not matching value
expectedProperties = new Object[] {
"key1", "value1",
- "key2", "value3"
+ "key3", new int[] { 1, 2, 5 }
+ };
+ Assert.assertThat(resource, Matchers.not(ResourceMatchers.props(expectedProperties)));
+
+ expectedProperties = new Object[] {
+ "key1", "value1",
+ "key3", new int[] { 1, 2 }
+ };
+ Assert.assertThat(resource, Matchers.not(ResourceMatchers.props(expectedProperties)));
+
+ expectedProperties = new Object[] {
+ "key1", "value1",
+ "key3", 1
+ };
+ Assert.assertThat(resource, Matchers.not(ResourceMatchers.props(expectedProperties)));
+
+ expectedProperties = new Object[] {
+ "key1", "value1",
+ "key3", null
};
Assert.assertThat(resource, Matchers.not(ResourceMatchers.props(expectedProperties)));
// test non-existing key
expectedProperties = new Object[] {
- "key4", "value4"
+ "key5", "value5"
};
Assert.assertThat(resource, Matchers.not(ResourceMatchers.props(expectedProperties)));
}
@@ -134,12 +156,12 @@
public void testNameAndProps() {
context.build().resource("/resource",
"key1", "value1",
- "key2", "value2",
+ "key2", new String[] { "item1" },
"key3", "value3");
Map<String, Object> expectedProperties = ImmutableMap.<String, Object>builder()
.put("key1", "value1")
- .put("key2", "value2")
+ .put("key2", new String[] { "item1" })
.build();
Resource resource = context.resourceResolver().getResource("/resource");