Skip to content

Commit f04b814

Browse files
committed
Merge pull request skyscreamer#35 from albx79/master
Custom comparator - in master
2 parents 1b4cdbb + 4921339 commit f04b814

5 files changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.skyscreamer.jsonassert;
2+
3+
/**
4+
* Associates a custom matcher to a specific jsonpath.
5+
*/
6+
public final class Customization {
7+
private final String path;
8+
private final ValueMatcher<Object> comparator;
9+
10+
public Customization(String path, ValueMatcher<Object> comparator) {
11+
assert path != null;
12+
assert comparator != null;
13+
this.path = path;
14+
this.comparator = comparator;
15+
}
16+
17+
public static Customization customization(String path, ValueMatcher<Object> comparator) {
18+
return new Customization(path, comparator);
19+
}
20+
21+
public boolean appliesToPath(String path) {
22+
return this.path.equals(path);
23+
}
24+
25+
public boolean matches(Object actual, Object expected) {
26+
return comparator.equal(actual, expected);
27+
}
28+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.skyscreamer.jsonassert;
2+
3+
public interface ValueMatcher<T> {
4+
5+
boolean equal(T o1, T o2);
6+
7+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.skyscreamer.jsonassert.comparator;
2+
3+
import org.json.JSONException;
4+
import org.skyscreamer.jsonassert.Customization;
5+
import org.skyscreamer.jsonassert.JSONCompareMode;
6+
import org.skyscreamer.jsonassert.JSONCompareResult;
7+
8+
import java.util.Arrays;
9+
import java.util.Collection;
10+
11+
public class CustomComparator extends DefaultComparator {
12+
13+
private final Collection<Customization> customizations;
14+
15+
public CustomComparator(JSONCompareMode mode, Customization... customizations) {
16+
super(mode);
17+
this.customizations = Arrays.asList(customizations);
18+
}
19+
20+
@Override
21+
public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException {
22+
Customization customization = getCustomization(prefix);
23+
if (customization != null) {
24+
if (!customization.matches(actualValue, expectedValue)) {
25+
result.fail(prefix, expectedValue, actualValue);
26+
}
27+
} else {
28+
super.compareValues(prefix, expectedValue, actualValue, result);
29+
}
30+
}
31+
32+
private Customization getCustomization(String path) {
33+
for (Customization c : customizations)
34+
if (c.appliesToPath(path))
35+
return c;
36+
return null;
37+
}
38+
}

src/main/java/org/skyscreamer/jsonassert/comparator/DefaultComparator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@
33
import org.json.JSONArray;
44
import org.json.JSONException;
55
import org.json.JSONObject;
6+
import org.skyscreamer.jsonassert.Customization;
67
import org.skyscreamer.jsonassert.JSONCompareMode;
78
import org.skyscreamer.jsonassert.JSONCompareResult;
89

10+
import java.util.Collection;
11+
import java.util.Collections;
12+
import java.util.HashSet;
13+
import java.util.Set;
14+
915
import static org.skyscreamer.jsonassert.comparator.JSONCompareUtil.allJSONObjects;
1016
import static org.skyscreamer.jsonassert.comparator.JSONCompareUtil.allSimpleValues;
1117

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.skyscreamer.jsonassert;
2+
3+
import org.json.JSONException;
4+
import org.junit.Test;
5+
import org.skyscreamer.jsonassert.comparator.CustomComparator;
6+
import org.skyscreamer.jsonassert.comparator.JSONComparator;
7+
8+
import static org.junit.Assert.assertEquals;
9+
import static org.junit.Assert.assertTrue;
10+
import static org.skyscreamer.jsonassert.JSONCompare.compareJSON;
11+
12+
public class JSONCustomComparatorTest {
13+
14+
String actual = "{\"first\":\"actual\", \"second\":1}";
15+
String expected = "{\"first\":\"expected\", \"second\":1}";
16+
17+
String deepActual = "{\n" +
18+
" \"outer\":\n" +
19+
" {\n" +
20+
" \"inner\":\n" +
21+
" {\n" +
22+
" \"value\": \"actual\",\n" +
23+
" \"otherValue\": \"foo\"\n" +
24+
" }\n" +
25+
" }\n" +
26+
"}";
27+
String deepExpected = "{\n" +
28+
" \"outer\":\n" +
29+
" {\n" +
30+
" \"inner\":\n" +
31+
" {\n" +
32+
" \"value\": \"expected\",\n" +
33+
" \"otherValue\": \"foo\"\n" +
34+
" }\n" +
35+
" }\n" +
36+
"}";
37+
38+
int comparatorCallCount = 0;
39+
ValueMatcher<Object> comparator = new ValueMatcher<Object>() {
40+
@Override
41+
public boolean equal(Object o1, Object o2) {
42+
comparatorCallCount++;
43+
return o1.toString().equals("actual") && o2.toString().equals("expected");
44+
}
45+
};
46+
47+
@Test
48+
public void whenPathMatchesInCustomizationThenCallCustomMatcher() throws JSONException {
49+
JSONComparator jsonCmp = new CustomComparator(JSONCompareMode.STRICT, new Customization("first", comparator));
50+
JSONCompareResult result = compareJSON(expected, actual, jsonCmp);
51+
assertTrue(result.getMessage(), result.passed());
52+
assertEquals(1, comparatorCallCount);
53+
}
54+
55+
@Test
56+
public void whenDeepPathMatchesCallCustomMatcher() throws JSONException {
57+
JSONComparator jsonCmp = new CustomComparator(JSONCompareMode.STRICT, new Customization("outer.inner.value", comparator));
58+
JSONCompareResult result = compareJSON(deepExpected, deepActual, jsonCmp);
59+
assertTrue(result.getMessage(), result.passed());
60+
assertEquals(1, comparatorCallCount);
61+
}
62+
63+
}

0 commit comments

Comments
 (0)