Skip to content

Commit

Permalink
Merge 0f99825 into 24fdd7d
Browse files Browse the repository at this point in the history
  • Loading branch information
fslev committed Oct 29, 2022
2 parents 24fdd7d + 0f99825 commit 6ae11c8
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 24 deletions.
5 changes: 5 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog

## 5.2-SNAPSHOT
- #### Changed
- refactor AssertionError messages
- #### Fixed
- MATCH_ANY and DO_NOT_MATCH_ANY use cases didn't work while using custom comparator


## 5.1 (2022-10-05)
- #### Changed
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ JSONCompare.assertMatches(expected, actual); //assertion fails
org.opentest4j.AssertionFailedError: FOUND 1 DIFFERENCE(S):

_________________________DIFF__________________________
Field '!.*' was FOUND
Actual JSON OBJECT has unmatched fields
```
```javascript
// actual JSON array should NOT contain any extra elements
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/io/json/compare/JSONCompare.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ public static void assertMatches(Object expected, Object actual, JsonComparator
if (!diffs.isEmpty()) {
String defaultMessage = String.format("FOUND %s DIFFERENCE(S):" + System.lineSeparator() + "%s" + System.lineSeparator(),
diffs.size(), diffs.stream().map(diff ->
System.lineSeparator() + System.lineSeparator() + "_________________________DIFF__________________________" +
System.lineSeparator() + System.lineSeparator() + "_________________________DIFF__________________________" +
System.lineSeparator() + diff).reduce(String::concat).get());
if (comparator == null || comparator.getClass().equals(DefaultJsonComparator.class)) {
defaultMessage += System.lineSeparator() + System.lineSeparator() + ASSERTION_ERROR_HINT_MESSAGE + System.lineSeparator();
defaultMessage += System.lineSeparator() + System.lineSeparator() + ASSERTION_ERROR_HINT_MESSAGE + System.lineSeparator();
}
AssertionFailureBuilder.assertionFailure().message(message == null ? defaultMessage : defaultMessage + System.lineSeparator() + message)
.expected(prettyPrint(expectedJson)).actual(prettyPrint(actualJson)).buildAndThrow();
Expand All @@ -85,7 +85,7 @@ public static void assertNotMatches(Object expected, Object actual, JsonComparat
if (!diffs.isEmpty()) {
return;
}
String defaultMessage = System.lineSeparator() + "JSONs are equal";
String defaultMessage = System.lineSeparator() + "JSONs are equal";
AssertionFailureBuilder.assertionFailure().message(message == null ? defaultMessage : defaultMessage + System.lineSeparator() + message)
.expected(prettyPrint(expectedJson)).actual(prettyPrint(actualJson))
.includeValuesInMessage(false).buildAndThrow();
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/json/compare/matcher/JsonArrayMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private List<String> matchWithJsonArray(int expPosition, JsonNode expElement, Us
break;
case DO_NOT_MATCH_ANY:
diffs.add(String.format("Expected condition %s from position %s was not met." +
" Actual JSON array has extra elements.",
" Actual JSON array has extra elements",
expElement, expPosition + 1));
return diffs;
}
Expand All @@ -93,7 +93,7 @@ private List<String> matchWithJsonArray(int expPosition, JsonNode expElement, Us
+ MessageUtil.cropL(JSONCompare.prettyPrint(expElement)));
} else if (useCase == UseCase.MATCH_ANY) {
diffs.add(String.format("Expected condition %s from position %s was not met." +
" Actual Json Array has no extra elements.", expElement, expPosition + 1));
" Actual Json Array has no extra elements", expElement, expPosition + 1));
}
return diffs;
}
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/io/json/compare/matcher/JsonObjectMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ public List<String> match() {
Map.Entry<String, JsonNode> entry = it.next();
String expectedField = entry.getKey();
JsonNode expectedValue = entry.getValue();
UseCase useCase = getUseCase(expectedField);
UseCase fieldUseCase = getUseCase(expectedField);
String expectedSanitizedField = sanitize(expectedField);
Optional<String> jsonPathExpression = extractJsonPathExp(expectedSanitizedField);
List<Map.Entry<String, JsonNode>> candidateEntries = null;
if (!jsonPathExpression.isPresent()) {
candidateEntries = searchCandidatesByField(expectedSanitizedField, actual);
candidateEntries = searchCandidatesByField(fieldUseCase, expectedSanitizedField, actual);
}
switch (useCase) {
switch (fieldUseCase) {
case MATCH_ANY:
case MATCH:
if (!jsonPathExpression.isPresent()) {
Expand All @@ -49,6 +49,10 @@ public List<String> match() {
}
break;
case DO_NOT_MATCH_ANY:
if (!candidateEntries.isEmpty()) {
diffs.add(String.format("Expected condition '%s' was not met. Actual JSON OBJECT has unmatched fields", expectedField));
}
break;
case DO_NOT_MATCH:
if (!jsonPathExpression.isPresent()) {
if (!candidateEntries.isEmpty()) {
Expand All @@ -66,7 +70,7 @@ public List<String> match() {
}
}
if (compareModes.contains(CompareMode.JSON_OBJECT_NON_EXTENSIBLE) && expected.size() < actual.size()) {
diffs.add("Actual JSON OBJECT has extra fields");
diffs.add("Actual JSON OBJECT has unmatched fields");
}
return diffs;
}
Expand Down Expand Up @@ -96,7 +100,7 @@ private List<String> matchWithCandidates(String expectedField, JsonNode expected
return diffs;
}

private List<Map.Entry<String, JsonNode>> searchCandidatesByField(String fieldName, JsonNode target) {
private List<Map.Entry<String, JsonNode>> searchCandidatesByField(UseCase fieldUseCase, String fieldName, JsonNode target) {
List<Map.Entry<String, JsonNode>> candidates = new ArrayList<>();
Iterator<Map.Entry<String, JsonNode>> it = target.fields();
while (it.hasNext()) {
Expand All @@ -105,7 +109,8 @@ private List<Map.Entry<String, JsonNode>> searchCandidatesByField(String fieldNa
if (matchedFieldNames.contains(key)) {
continue;
}
if (comparator.compareFields(fieldName, key)) {
if (fieldUseCase.equals(UseCase.MATCH_ANY) || fieldUseCase.equals(UseCase.DO_NOT_MATCH_ANY)
|| comparator.compareFields(fieldName, key)) {
candidates.add(entry);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class JsonValueMatcher extends AbstractJsonMatcher {
@Override
public List<String> match() {
List<String> diffs = new ArrayList<>();
String diff = System.lineSeparator() + "Expected %s: %s But got: %s";
String diff = System.lineSeparator() + "Expected %s: %s But got: %s";

if (expected.isNull() && !actual.isNull()) {
diffs.add(String.format(diff, "null", "", actual));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package io.json.compare.matcher.diffs;

import io.json.compare.CompareMode;
import io.json.compare.JSONCompare;
import io.json.compare.JsonComparator;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.HashSet;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class JsonCustomComparatorDiffTests {

@Test
public void compareJsons() {
String expected = "{\"name\":\"test\",\"records\":[3]}";
String actual = "{\"name\":\"test\",\"records\":[1,2,3], \"otherRecords\":[4]}";
JSONCompare.assertMatches(expected, actual, new CustomComparator());

String expected1 = "{\"name\":\"test1\",\"records\":[3,4]}";
String actual1 = "{\"name\":\"test\",\"records\":[1,2,3], \"otherRecords\":[4]}";
AssertionError error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected1, actual1, new CustomComparator()));
assertTrue(error.getMessage().matches("(?s).*FOUND 2 DIFFERENCE.*" +
"name ->.*Expected value: \"test1\" But got: \"test\".*" +
"records ->.*Expected element from position 2 was NOT FOUND.*4.*"));
}

@Test
public void compareJsonsWithCompareModes() {
String expected = "{\"name\":\"test\",\"records\":[1,2,3], \"otherRecords\":[4]}";
String actual = "{\"name\":\"test\",\"records\":[1,2,3], \"otherRecords\":[4]}";
JSONCompare.assertMatches(expected, actual, new CustomComparator(),
new HashSet<>(Arrays.asList(CompareMode.JSON_OBJECT_NON_EXTENSIBLE, CompareMode.JSON_ARRAY_NON_EXTENSIBLE,
CompareMode.JSON_ARRAY_STRICT_ORDER)));

String expected1 = "{\"name\":\"test\",\"records\":[2,1]}";
String actual1 = "{\"name\":\"test\",\"records\":[1,2,3], \"otherRecords\":[4]}";
AssertionError error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected1, actual1, new CustomComparator(),
new HashSet<>(Arrays.asList(CompareMode.JSON_OBJECT_NON_EXTENSIBLE, CompareMode.JSON_ARRAY_NON_EXTENSIBLE,
CompareMode.JSON_ARRAY_STRICT_ORDER))));
assertTrue(error.getMessage().matches("(?s).*FOUND 4 DIFFERENCE.*" +
"records -> JSON ARRAY elements differ at position 1.*2.*Expected value: 2 But got: 1.*" +
"records -> JSON ARRAY elements differ at position 2.*1.*Expected value: 1 But got: 2.*" +
"records -> Actual JSON ARRAY has extra elements.*" +
"Actual JSON OBJECT has unmatched fields.*"));
}

@Test
public void compareJsonsWithUseCases() {
String expected = "{\"!name\":\"test\",\"records\":[1,2,3, \"!.*\"], \"otherRecords\":[4, \"!.*\"]}";
String actual = "{\"names\":\"test\",\"records\":[1,2,3], \"otherRecords\":[4]}";
JSONCompare.assertMatches(expected, actual, new CustomComparator());

expected = "{\"!name\":\"test\", \"records\":[1,2,3, \"!.*\"], \"otherRecords\":[4, \"!.*\"], \"!.*\":\".*\"}";
actual = "{\"records\":[1,2,3], \"otherRecords\":[4]}";
JSONCompare.assertMatches(expected, actual, new CustomComparator());

expected = "{\".*\":\"test\",\"records\":[1, \".*\", 3, \"!.*\"], \"otherRecords\":[4, \"!.*\"], \"!.*\":\".*\"}";
actual = "{\"names\":\"test\",\"records\":[1,2,3], \"otherRecords\":[4]}";
JSONCompare.assertMatches(expected, actual, new CustomComparator());

String expected1 = "{\".*\":\"test\", \"records\":[1, \".*\", 3, \"!.*\"], \"otherRecords\":[4, \"!.*\"], \"!.*\":\".*\"}";
String actual1 = "{\"names\":\"test1\", \"records\":[2,1,4,3], \"otherRecords\":[1,2], \"another\":\"record\"}";
AssertionError error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected1, actual1, new CustomComparator()));
assertTrue(error.getMessage().matches("(?s).*FOUND 7 DIFFERENCE.*" +
"\\Q.*\\E ->.*Expected value: \"test\" But got: \"test1\".*" +
"\\Q.*\\E ->.*Different JSON types: expected TextNode but got ArrayNode.*" +
"\\Q.*\\E ->.*Different JSON types: expected TextNode but got ArrayNode.*" +
"\\Q.*\\E ->.*Expected value: \"test\" But got: \"record\".*" +
"records ->.*Expected condition \"\\Q!.*\\E\" from position 4 was not met. Actual JSON array has extra elements.*" +
"otherRecords ->.*Expected element from position 1 was NOT FOUND.*4.*" +
"Expected condition '\\Q!.*\\E' was not met. Actual JSON OBJECT has unmatched fields.*"));

String expected2 = "{\"name\":\"test\", \"records\":[1, \".*\", 3, 4, \".*\"], \"otherRecords\":[4, \"!.*\"], \".*\":\".*\"}";
String actual2 = "{\"names\":\"test1\", \"records\":[2,1,4,3], \"otherRecords\":[1,2, 4], \"another\":\"record\"}";
error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected2, actual2, new CustomComparator()));
assertTrue(error.getMessage().matches("(?s).*FOUND 3 DIFFERENCE.*" +
"Field 'name' was NOT FOUND.*" +
"records ->.*Expected condition \"\\Q.*\\E\" from position 5 was not met. Actual Json Array has no extra elements.*" +
"otherRecords ->.*Expected condition \"\\Q!.*\\E\" from position 2 was not met. Actual JSON array has extra elements.*"));

String expected3 = "{\"name\":\"test\", \"records\":[1, \".*\", 3, 4, \".*\"], \"otherRecords\":[4, 2, \"!.*\"], \".*\":\".*\"}";
String actual3 = "{\"name\":\"test\", \"records\":[2,1,5,4,3], \"otherRecords\":[2, 4]}";
error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected3, actual3, new CustomComparator()));
assertTrue(error.getMessage().matches("(?s).*FOUND 1 DIFFERENCE.*" +
"Field '\\Q.*\\E' was NOT FOUND.*"));

}

@Test
public void compareJsonsWithRegexes() {
String expected = "{\"na.*\":\"test\",\"records\":[1,\"\\\\d+\",3], \"otherRecords\":[4]}";
String actual = "{\"na.*\":\"test\",\"records\":[\"\\\\d+\",3,1], \"otherRecords\":[4]}";
JSONCompare.assertMatches(expected, actual, new CustomComparator());

String expected1 = "{\"na.*\":\"test\",\"records\":[2,\"\\\\d+\"]}";
String actual1 = "{\"name\":\"test\",\"records\":[1,2,3], \"otherRecords\":[4]}";
AssertionError error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected1, actual1, new CustomComparator()));
assertTrue(error.getMessage().matches("(?s).*FOUND 2 DIFFERENCE.*" +
"Field '\\Qna.*\\E' was NOT FOUND.*" +
"records ->.*Expected element from position 2 was NOT FOUND.*\"\\Q\\\\d+\\E\".*"));
}

private static class CustomComparator implements JsonComparator {
@Override
public boolean compareValues(Object expected, Object actual) {
return expected.equals(actual);
}

@Override
public boolean compareFields(String expected, String actual) {
return expected.equals(actual);
}
}
}
Loading

0 comments on commit 6ae11c8

Please sign in to comment.