Skip to content

Commit cacc78d

Browse files
deblocktclaude
andcommitted
fix: update tests for new CompositeJsonMatcher API
- Fix CompositeJsonMatcherTest to configure manage() method on mocks - Add comprehensive tests for NullEqualsEmptyArrayMatcher 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent af826e8 commit cacc78d

2 files changed

Lines changed: 206 additions & 9 deletions

File tree

src/test/java/com/deblock/jsondiff/matcher/CompositeJsonMatcherTest.java

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.deblock.jsondiff.matcher;
22

33
import com.deblock.jsondiff.diff.JsonDiff;
4+
import tools.jackson.databind.JsonNode;
45
import tools.jackson.databind.node.*;
56
import org.junit.jupiter.api.Test;
67
import org.mockito.Mockito;
78

89
import static org.junit.jupiter.api.Assertions.*;
10+
import static org.mockito.ArgumentMatchers.any;
911

1012
public class CompositeJsonMatcherTest {
1113
private final static Path path = Path.ROOT.add(Path.PathItem.of("property"));
@@ -16,10 +18,20 @@ public void shouldCallTheArrayMatcherIfTheTwoObjectAreArray() {
1618
final var array2 = new ArrayNode(null);
1719

1820
final var arrayMatcher = (PartialJsonMatcher<ArrayNode>) Mockito.mock(PartialJsonMatcher.class);
21+
final var objectMatcher = (PartialJsonMatcher<ObjectNode>) Mockito.mock(PartialJsonMatcher.class);
22+
final var primitiveMatcher = (PartialJsonMatcher<ValueNode>) Mockito.mock(PartialJsonMatcher.class);
23+
24+
Mockito.when(arrayMatcher.manage(any(), any())).thenAnswer(inv ->
25+
((JsonNode)inv.getArgument(0)).isArray() && ((JsonNode)inv.getArgument(1)).isArray());
26+
Mockito.when(objectMatcher.manage(any(), any())).thenAnswer(inv ->
27+
((JsonNode)inv.getArgument(0)).isObject() && ((JsonNode)inv.getArgument(1)).isObject());
28+
Mockito.when(primitiveMatcher.manage(any(), any())).thenAnswer(inv ->
29+
((JsonNode)inv.getArgument(0)).isValueNode() && ((JsonNode)inv.getArgument(1)).isValueNode());
30+
1931
final var compositeMatcher = new CompositeJsonMatcher(
2032
arrayMatcher,
21-
(PartialJsonMatcher<ObjectNode>) Mockito.mock(PartialJsonMatcher.class),
22-
(PartialJsonMatcher<ValueNode>) Mockito.mock(PartialJsonMatcher.class)
33+
objectMatcher,
34+
primitiveMatcher
2335
);
2436
final var expectedJsonDiff = Mockito.mock(JsonDiff.class);
2537
Mockito.when(arrayMatcher.jsonDiff(path, array1, array2, compositeMatcher)).thenReturn(expectedJsonDiff);
@@ -34,11 +46,21 @@ public void shouldCallTheObjectMatcherIfTheTwoObjectAreObject() {
3446
final var object1 = new ObjectNode(null);
3547
final var object2 = new ObjectNode(null);
3648

49+
final var arrayMatcher = (PartialJsonMatcher<ArrayNode>) Mockito.mock(PartialJsonMatcher.class);
3750
final var objectMatcher = (PartialJsonMatcher<ObjectNode>) Mockito.mock(PartialJsonMatcher.class);
51+
final var primitiveMatcher = (PartialJsonMatcher<ValueNode>) Mockito.mock(PartialJsonMatcher.class);
52+
53+
Mockito.when(arrayMatcher.manage(any(), any())).thenAnswer(inv ->
54+
((JsonNode)inv.getArgument(0)).isArray() && ((JsonNode)inv.getArgument(1)).isArray());
55+
Mockito.when(objectMatcher.manage(any(), any())).thenAnswer(inv ->
56+
((JsonNode)inv.getArgument(0)).isObject() && ((JsonNode)inv.getArgument(1)).isObject());
57+
Mockito.when(primitiveMatcher.manage(any(), any())).thenAnswer(inv ->
58+
((JsonNode)inv.getArgument(0)).isValueNode() && ((JsonNode)inv.getArgument(1)).isValueNode());
59+
3860
final var compositeMatcher = new CompositeJsonMatcher(
39-
(PartialJsonMatcher<ArrayNode>) Mockito.mock(PartialJsonMatcher.class),
61+
arrayMatcher,
4062
objectMatcher,
41-
(PartialJsonMatcher<ValueNode>) Mockito.mock(PartialJsonMatcher.class)
63+
primitiveMatcher
4264
);
4365
final var expectedJsonDiff = Mockito.mock(JsonDiff.class);
4466
Mockito.when(objectMatcher.jsonDiff(path, object1, object2, compositeMatcher)).thenReturn(expectedJsonDiff);
@@ -53,10 +75,20 @@ public void shouldCallThePrimitiveMatcherIfTheTwoObjectAreValue() {
5375
final var value1 = StringNode.valueOf("");
5476
final var value2 = IntNode.valueOf(10);
5577

78+
final var arrayMatcher = (PartialJsonMatcher<ArrayNode>) Mockito.mock(PartialJsonMatcher.class);
79+
final var objectMatcher = (PartialJsonMatcher<ObjectNode>) Mockito.mock(PartialJsonMatcher.class);
5680
final var primitiveMatcher = (PartialJsonMatcher<ValueNode>) Mockito.mock(PartialJsonMatcher.class);
81+
82+
Mockito.when(arrayMatcher.manage(any(), any())).thenAnswer(inv ->
83+
((JsonNode)inv.getArgument(0)).isArray() && ((JsonNode)inv.getArgument(1)).isArray());
84+
Mockito.when(objectMatcher.manage(any(), any())).thenAnswer(inv ->
85+
((JsonNode)inv.getArgument(0)).isObject() && ((JsonNode)inv.getArgument(1)).isObject());
86+
Mockito.when(primitiveMatcher.manage(any(), any())).thenAnswer(inv ->
87+
((JsonNode)inv.getArgument(0)).isValueNode() && ((JsonNode)inv.getArgument(1)).isValueNode());
88+
5789
final var compositeMatcher = new CompositeJsonMatcher(
58-
(PartialJsonMatcher<ArrayNode>) Mockito.mock(PartialJsonMatcher.class),
59-
(PartialJsonMatcher<ObjectNode>) Mockito.mock(PartialJsonMatcher.class),
90+
arrayMatcher,
91+
objectMatcher,
6092
primitiveMatcher
6193
);
6294
final var expectedJsonDiff = Mockito.mock(JsonDiff.class);
@@ -72,10 +104,21 @@ public void shouldReturnANonMatchWhenTypesAreDifferent() {
72104
final var value1 = StringNode.valueOf("");
73105
final var value2 = new ObjectNode(null);
74106

107+
final var arrayMatcher = (PartialJsonMatcher<ArrayNode>) Mockito.mock(PartialJsonMatcher.class);
108+
final var objectMatcher = (PartialJsonMatcher<ObjectNode>) Mockito.mock(PartialJsonMatcher.class);
109+
final var primitiveMatcher = (PartialJsonMatcher<ValueNode>) Mockito.mock(PartialJsonMatcher.class);
110+
111+
Mockito.when(arrayMatcher.manage(any(), any())).thenAnswer(inv ->
112+
((JsonNode)inv.getArgument(0)).isArray() && ((JsonNode)inv.getArgument(1)).isArray());
113+
Mockito.when(objectMatcher.manage(any(), any())).thenAnswer(inv ->
114+
((JsonNode)inv.getArgument(0)).isObject() && ((JsonNode)inv.getArgument(1)).isObject());
115+
Mockito.when(primitiveMatcher.manage(any(), any())).thenAnswer(inv ->
116+
((JsonNode)inv.getArgument(0)).isValueNode() && ((JsonNode)inv.getArgument(1)).isValueNode());
117+
75118
final var compositeMatcher = new CompositeJsonMatcher(
76-
(PartialJsonMatcher<ArrayNode>) Mockito.mock(PartialJsonMatcher.class),
77-
(PartialJsonMatcher<ObjectNode>) Mockito.mock(PartialJsonMatcher.class),
78-
(PartialJsonMatcher<ValueNode>) Mockito.mock(PartialJsonMatcher.class)
119+
arrayMatcher,
120+
objectMatcher,
121+
primitiveMatcher
79122
);
80123

81124
final var result = compositeMatcher.diff(path, value1, value2);
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package com.deblock.jsondiff.matcher;
2+
3+
import com.deblock.jsondiff.diff.MatchedPrimaryDiff;
4+
import com.deblock.jsondiff.diff.UnMatchedPrimaryDiff;
5+
import org.junit.jupiter.api.Test;
6+
import tools.jackson.databind.ObjectMapper;
7+
import tools.jackson.databind.node.ArrayNode;
8+
import tools.jackson.databind.node.NullNode;
9+
import tools.jackson.databind.node.ObjectNode;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
13+
public class NullEqualsEmptyArrayMatcherTest {
14+
private static final ObjectMapper MAPPER = new ObjectMapper();
15+
private static final Path ROOT = Path.ROOT;
16+
private final NullEqualsEmptyArrayMatcher matcher = new NullEqualsEmptyArrayMatcher();
17+
18+
@Test
19+
public void manage_shouldReturnTrue_whenExpectedIsNullAndReceivedIsArray() {
20+
final var nullNode = NullNode.getInstance();
21+
final var arrayNode = MAPPER.createArrayNode();
22+
23+
assertTrue(matcher.manage(nullNode, arrayNode));
24+
}
25+
26+
@Test
27+
public void manage_shouldReturnTrue_whenExpectedIsArrayAndReceivedIsNull() {
28+
final var arrayNode = MAPPER.createArrayNode();
29+
final var nullNode = NullNode.getInstance();
30+
31+
assertTrue(matcher.manage(arrayNode, nullNode));
32+
}
33+
34+
@Test
35+
public void manage_shouldReturnFalse_whenBothAreNull() {
36+
final var nullNode1 = NullNode.getInstance();
37+
final var nullNode2 = NullNode.getInstance();
38+
39+
assertFalse(matcher.manage(nullNode1, nullNode2));
40+
}
41+
42+
@Test
43+
public void manage_shouldReturnFalse_whenBothAreArrays() {
44+
final var array1 = MAPPER.createArrayNode();
45+
final var array2 = MAPPER.createArrayNode();
46+
47+
assertFalse(matcher.manage(array1, array2));
48+
}
49+
50+
@Test
51+
public void manage_shouldReturnFalse_whenExpectedIsNullAndReceivedIsObject() {
52+
final var nullNode = NullNode.getInstance();
53+
final var objectNode = MAPPER.createObjectNode();
54+
55+
assertFalse(matcher.manage(nullNode, objectNode));
56+
}
57+
58+
@Test
59+
public void jsonDiff_shouldReturnMatch_whenNullVsEmptyArray() {
60+
final var nullNode = NullNode.getInstance();
61+
final var emptyArray = MAPPER.createArrayNode();
62+
63+
final var result = matcher.jsonDiff(ROOT, nullNode, emptyArray, null);
64+
65+
assertInstanceOf(MatchedPrimaryDiff.class, result);
66+
assertEquals(100.0, result.similarityRate());
67+
}
68+
69+
@Test
70+
public void jsonDiff_shouldReturnMatch_whenEmptyArrayVsNull() {
71+
final var emptyArray = MAPPER.createArrayNode();
72+
final var nullNode = NullNode.getInstance();
73+
74+
final var result = matcher.jsonDiff(ROOT, emptyArray, nullNode, null);
75+
76+
assertInstanceOf(MatchedPrimaryDiff.class, result);
77+
assertEquals(100.0, result.similarityRate());
78+
}
79+
80+
@Test
81+
public void jsonDiff_shouldReturnUnMatch_whenNullVsNonEmptyArray() {
82+
final var nullNode = NullNode.getInstance();
83+
final var nonEmptyArray = MAPPER.createArrayNode();
84+
nonEmptyArray.add(1);
85+
86+
final var result = matcher.jsonDiff(ROOT, nullNode, nonEmptyArray, null);
87+
88+
assertInstanceOf(UnMatchedPrimaryDiff.class, result);
89+
assertEquals(0.0, result.similarityRate());
90+
}
91+
92+
@Test
93+
public void jsonDiff_shouldReturnUnMatch_whenNonEmptyArrayVsNull() {
94+
final var nonEmptyArray = MAPPER.createArrayNode();
95+
nonEmptyArray.add("value");
96+
final var nullNode = NullNode.getInstance();
97+
98+
final var result = matcher.jsonDiff(ROOT, nonEmptyArray, nullNode, null);
99+
100+
assertInstanceOf(UnMatchedPrimaryDiff.class, result);
101+
assertEquals(0.0, result.similarityRate());
102+
}
103+
104+
@Test
105+
public void integrationTest_shouldMatchNullAndEmptyArrayInJson() {
106+
final var expected = "{\"items\": null}";
107+
final var received = "{\"items\": []}";
108+
109+
final var jsonMatcher = new CompositeJsonMatcher(
110+
new NullEqualsEmptyArrayMatcher(),
111+
new LenientJsonArrayPartialMatcher(),
112+
new LenientJsonObjectPartialMatcher(),
113+
new StrictPrimitivePartialMatcher()
114+
);
115+
116+
final var diff = com.deblock.jsondiff.DiffGenerator.diff(expected, received, jsonMatcher);
117+
118+
assertEquals(100.0, diff.similarityRate());
119+
}
120+
121+
@Test
122+
public void integrationTest_shouldMatchEmptyArrayAndNullInJson() {
123+
final var expected = "{\"items\": []}";
124+
final var received = "{\"items\": null}";
125+
126+
final var jsonMatcher = new CompositeJsonMatcher(
127+
new NullEqualsEmptyArrayMatcher(),
128+
new LenientJsonArrayPartialMatcher(),
129+
new LenientJsonObjectPartialMatcher(),
130+
new StrictPrimitivePartialMatcher()
131+
);
132+
133+
final var diff = com.deblock.jsondiff.DiffGenerator.diff(expected, received, jsonMatcher);
134+
135+
assertEquals(100.0, diff.similarityRate());
136+
}
137+
138+
@Test
139+
public void integrationTest_shouldNotMatchNullAndNonEmptyArray() {
140+
final var expected = "{\"items\": null}";
141+
final var received = "{\"items\": [1, 2, 3]}";
142+
143+
final var jsonMatcher = new CompositeJsonMatcher(
144+
new NullEqualsEmptyArrayMatcher(),
145+
new LenientJsonArrayPartialMatcher(),
146+
new LenientJsonObjectPartialMatcher(),
147+
new StrictPrimitivePartialMatcher()
148+
);
149+
150+
final var diff = com.deblock.jsondiff.DiffGenerator.diff(expected, received, jsonMatcher);
151+
152+
assertTrue(diff.similarityRate() < 100.0);
153+
}
154+
}

0 commit comments

Comments
 (0)