Skip to content

Commit af826e8

Browse files
committed
feat: allow to have equality between null and empty array
1 parent ef013c9 commit af826e8

11 files changed

Lines changed: 83 additions & 27 deletions

src/main/java/com/deblock/jsondiff/matcher/CompositeJsonMatcher.java

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,24 @@
66
import tools.jackson.databind.node.ObjectNode;
77
import tools.jackson.databind.node.ValueNode;
88

9+
import java.util.ArrayList;
10+
import java.util.Arrays;
11+
import java.util.List;
12+
913
public class CompositeJsonMatcher implements JsonMatcher {
10-
private final PartialJsonMatcher<ArrayNode> jsonArrayPartialMatcher;
11-
private final PartialJsonMatcher<ObjectNode> jsonObjectPartialMatcher;
12-
private final PartialJsonMatcher<ValueNode> primitivePartialMatcher;
14+
private final List<PartialJsonMatcher<JsonNode>> matchers;
1315

14-
public CompositeJsonMatcher(
15-
PartialJsonMatcher<ArrayNode> jsonArrayPartialMatcher,
16-
PartialJsonMatcher<ObjectNode> jsonObjectPartialMatcher,
17-
PartialJsonMatcher<ValueNode> primitivePartialMatcher
18-
) {
19-
this.jsonArrayPartialMatcher = jsonArrayPartialMatcher;
20-
this.jsonObjectPartialMatcher = jsonObjectPartialMatcher;
21-
this.primitivePartialMatcher = primitivePartialMatcher;
16+
public CompositeJsonMatcher(PartialJsonMatcher<?> ...jsonArrayPartialMatcher) {
17+
this.matchers = new ArrayList<>();
18+
Arrays.stream(jsonArrayPartialMatcher).forEach(it -> this.matchers.add((PartialJsonMatcher<JsonNode>) it));
2219
}
2320

2421
@Override
2522
public JsonDiff diff(Path path, JsonNode expected, JsonNode received) {
26-
if (expected instanceof ObjectNode expectedObjectNode && received instanceof ObjectNode receivedObjectNode) {
27-
return this.jsonObjectPartialMatcher.jsonDiff(path, expectedObjectNode, receivedObjectNode, this);
28-
} else if (expected instanceof ArrayNode expectedArrayNode && received instanceof ArrayNode receivedArrayNode) {
29-
return this.jsonArrayPartialMatcher.jsonDiff(path, expectedArrayNode, receivedArrayNode, this);
30-
} else if (expected instanceof ValueNode expectedValueNode && received instanceof ValueNode receivedValueNode){
31-
return this.primitivePartialMatcher.jsonDiff(path, expectedValueNode, receivedValueNode, this);
32-
} else {
33-
return new UnMatchedPrimaryDiff(path, expected, received);
34-
}
23+
return this.matchers.stream()
24+
.filter(matcher -> matcher.manage(expected, received))
25+
.findFirst()
26+
.map(matcher -> matcher.jsonDiff(path, expected, received, this))
27+
.orElseGet(() -> new UnMatchedPrimaryDiff(path, expected, received));
3528
}
36-
37-
}
29+
}

src/main/java/com/deblock/jsondiff/matcher/JsonMatcher.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,4 @@
66
public interface JsonMatcher {
77

88
JsonDiff diff(Path path, JsonNode expected, JsonNode received);
9-
109
}

src/main/java/com/deblock/jsondiff/matcher/LenientJsonArrayPartialMatcher.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public JsonDiff jsonDiff(Path path, ArrayNode expectedArrayNode, ArrayNode recie
5757
return diff;
5858
}
5959

60+
@Override
61+
public boolean manage(JsonNode expected, JsonNode received) {
62+
return expected.isArray() && received.isArray();
63+
}
64+
6065
private double maxSimilarityRate(Map.Entry<Integer, Map<Integer, JsonDiff>> entry) {
6166
return entry.getValue().values().stream().mapToDouble(JsonDiff::similarityRate).max().orElse(0);
6267
}
@@ -137,4 +142,4 @@ public boolean containsNode(JsonNode node) {
137142
return nodeCounter.containsKey(node);
138143
}
139144
}
140-
}
145+
}

src/main/java/com/deblock/jsondiff/matcher/LenientJsonObjectPartialMatcher.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.deblock.jsondiff.diff.JsonDiff;
44
import com.deblock.jsondiff.diff.JsonObjectDiff;
5+
import tools.jackson.databind.JsonNode;
56
import tools.jackson.databind.node.ObjectNode;
67

78
public class LenientJsonObjectPartialMatcher implements PartialJsonMatcher<ObjectNode> {
@@ -26,4 +27,9 @@ public JsonDiff jsonDiff(Path path, ObjectNode expectedJson, ObjectNode received
2627

2728
return jsonDiff;
2829
}
29-
}
30+
31+
@Override
32+
public boolean manage(JsonNode expected, JsonNode received) {
33+
return expected.isObject() && received.isObject();
34+
}
35+
}

src/main/java/com/deblock/jsondiff/matcher/LenientNumberPrimitivePartialMatcher.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.deblock.jsondiff.diff.JsonDiff;
44
import com.deblock.jsondiff.diff.MatchedPrimaryDiff;
55
import com.deblock.jsondiff.diff.UnMatchedPrimaryDiff;
6+
import tools.jackson.databind.JsonNode;
67
import tools.jackson.databind.node.NumericNode;
78
import tools.jackson.databind.node.ValueNode;
89

@@ -25,4 +26,9 @@ public JsonDiff jsonDiff(Path path, ValueNode expectedValue, ValueNode receivedV
2526

2627
return delegated.jsonDiff(path, expectedValue, receivedValue, jsonMatcher);
2728
}
29+
30+
@Override
31+
public boolean manage(JsonNode expected, JsonNode received) {
32+
return expected.isValueNode() && received.isValueNode();
33+
}
2834
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.deblock.jsondiff.matcher;
2+
3+
import com.deblock.jsondiff.diff.JsonDiff;
4+
import com.deblock.jsondiff.diff.MatchedPrimaryDiff;
5+
import com.deblock.jsondiff.diff.UnMatchedPrimaryDiff;
6+
import tools.jackson.databind.JsonNode;
7+
8+
public class NullEqualsEmptyArrayMatcher implements PartialJsonMatcher<JsonNode> {
9+
10+
@Override
11+
public JsonDiff jsonDiff(Path path, JsonNode expectedJson, JsonNode receivedJson, JsonMatcher jsonMatcher) {
12+
if (
13+
(expectedJson.isNull() && receivedJson.isEmpty())
14+
|| (receivedJson.isNull() && expectedJson.isEmpty())
15+
) {
16+
return new MatchedPrimaryDiff(path, expectedJson);
17+
}
18+
return new UnMatchedPrimaryDiff(path, expectedJson, receivedJson);
19+
}
20+
21+
@Override
22+
public boolean manage(JsonNode expected, JsonNode received) {
23+
return (expected.isNull() && received.isArray())
24+
|| (received.isNull() && expected.isArray());
25+
}
26+
}

src/main/java/com/deblock/jsondiff/matcher/PartialJsonMatcher.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@
55

66
public interface PartialJsonMatcher<T extends JsonNode> {
77
JsonDiff jsonDiff(Path path, T expectedJson, T receivedJson, JsonMatcher jsonMatcher);
8+
9+
boolean manage(JsonNode expected, JsonNode received);
10+
811
}

src/main/java/com/deblock/jsondiff/matcher/StrictJsonArrayPartialMatcher.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.deblock.jsondiff.diff.JsonArrayDiff;
44
import com.deblock.jsondiff.diff.JsonDiff;
5+
import tools.jackson.databind.JsonNode;
56
import tools.jackson.databind.node.ArrayNode;
67

78
import java.util.Comparator;
@@ -35,4 +36,9 @@ public JsonDiff jsonDiff(Path path, ArrayNode expectedValues, ArrayNode received
3536
}
3637
return diff;
3738
}
39+
40+
@Override
41+
public boolean manage(JsonNode expected, JsonNode received) {
42+
return expected.isArray() && received.isArray();
43+
}
3844
}

src/main/java/com/deblock/jsondiff/matcher/StrictJsonObjectPartialMatcher.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.deblock.jsondiff.diff.JsonDiff;
44
import com.deblock.jsondiff.diff.JsonObjectDiff;
5+
import tools.jackson.databind.JsonNode;
56
import tools.jackson.databind.node.ObjectNode;
67

78
public class StrictJsonObjectPartialMatcher implements PartialJsonMatcher<ObjectNode> {
@@ -37,4 +38,9 @@ public JsonDiff jsonDiff(Path path, ObjectNode expectedJson, ObjectNode received
3738

3839
return jsonDiff;
3940
}
41+
42+
@Override
43+
public boolean manage(JsonNode expected, JsonNode received) {
44+
return expected.isObject() && received.isObject();
45+
}
4046
}

src/main/java/com/deblock/jsondiff/matcher/StrictPrimitivePartialMatcher.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.deblock.jsondiff.diff.JsonDiff;
44
import com.deblock.jsondiff.diff.MatchedPrimaryDiff;
55
import com.deblock.jsondiff.diff.UnMatchedPrimaryDiff;
6+
import tools.jackson.databind.JsonNode;
67
import tools.jackson.databind.node.ValueNode;
78

89
import java.util.Objects;
@@ -17,4 +18,9 @@ public JsonDiff jsonDiff(Path path, ValueNode expectedValue, ValueNode receivedV
1718
return new UnMatchedPrimaryDiff(path, expectedValue, receivedValue);
1819
}
1920
}
21+
22+
@Override
23+
public boolean manage(JsonNode expected, JsonNode received) {
24+
return expected.isValueNode() && received.isValueNode();
25+
}
2026
}

0 commit comments

Comments
 (0)