diff --git a/src/main/java/io/json/compare/JSONCompare.java b/src/main/java/io/json/compare/JSONCompare.java index c27e784..af6b7b9 100644 --- a/src/main/java/io/json/compare/JSONCompare.java +++ b/src/main/java/io/json/compare/JSONCompare.java @@ -2,11 +2,11 @@ import com.fasterxml.jackson.databind.JsonNode; import io.json.compare.matcher.JsonMatcher; -import io.json.compare.matcher.MatcherException; import io.json.compare.util.JsonUtils; import org.junit.jupiter.api.AssertionFailureBuilder; import java.io.IOException; +import java.util.List; import java.util.Set; @@ -62,11 +62,12 @@ public static void assertNotMatches(Object expected, Object actual, Set compareModes, String message) { JsonNode expectedJson = toJson(expected); JsonNode actualJson = toJson(actual); - try { - new JsonMatcher(expectedJson, actualJson, - comparator == null ? new DefaultJsonComparator() : comparator, compareModes).match(); - } catch (MatcherException e) { - String defaultMessage = String.format("%s\n", e.getMessage()); + List diffs = new JsonMatcher(expectedJson, actualJson, + comparator == null ? new DefaultJsonComparator() : comparator, compareModes).match(); + if (!diffs.isEmpty()) { + String defaultMessage = String.format("FOUND %s DIFFERENCE(S):\n%s\n", + diffs.size(), diffs.stream().map(diff -> + "\n_________________________DIFF__________________________\n" + diff).reduce(String::concat).get()); if (comparator == null || comparator.getClass().equals(DefaultJsonComparator.class)) { defaultMessage += "\n\n" + ASSERTION_ERROR_HINT_MESSAGE + "\n"; } @@ -78,13 +79,12 @@ public static void assertMatches(Object expected, Object actual, JsonComparator public static void assertNotMatches(Object expected, Object actual, JsonComparator comparator, Set compareModes, String message) { JsonNode expectedJson = toJson(expected); JsonNode actualJson = toJson(actual); - try { - new JsonMatcher(expectedJson, actualJson, - comparator == null ? new DefaultJsonComparator() : comparator, compareModes).match(); - } catch (MatcherException e) { + List diffs = new JsonMatcher(expectedJson, actualJson, + comparator == null ? new DefaultJsonComparator() : comparator, compareModes).match(); + if (!diffs.isEmpty()) { return; } - String defaultMessage = "JSONs are equal"; + String defaultMessage = "\nJSONs are equal"; AssertionFailureBuilder.assertionFailure().message(message == null ? defaultMessage : defaultMessage + "\n" + message) .expected(prettyPrint(expectedJson)).actual(prettyPrint(actualJson)) .includeValuesInMessage(false).buildAndThrow(); diff --git a/src/main/java/io/json/compare/matcher/AbstractJsonMatcher.java b/src/main/java/io/json/compare/matcher/AbstractJsonMatcher.java index d4c2b7b..31ca2b8 100644 --- a/src/main/java/io/json/compare/matcher/AbstractJsonMatcher.java +++ b/src/main/java/io/json/compare/matcher/AbstractJsonMatcher.java @@ -5,10 +5,7 @@ import io.json.compare.DefaultJsonComparator; import io.json.compare.JsonComparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Optional; -import java.util.Set; +import java.util.*; abstract class AbstractJsonMatcher { @@ -27,7 +24,7 @@ abstract class AbstractJsonMatcher { this.compareModes = compareModes == null ? new HashSet<>() : compareModes; } - protected abstract void match() throws MatcherException; + protected abstract List match(); protected static UseCase getUseCase(JsonNode node) { if (node.isValueNode()) { diff --git a/src/main/java/io/json/compare/matcher/JsonArrayMatcher.java b/src/main/java/io/json/compare/matcher/JsonArrayMatcher.java index 0b0c49f..ae8b9b1 100644 --- a/src/main/java/io/json/compare/matcher/JsonArrayMatcher.java +++ b/src/main/java/io/json/compare/matcher/JsonArrayMatcher.java @@ -6,8 +6,7 @@ import io.json.compare.JsonComparator; import io.json.compare.util.MessageUtil; -import java.util.HashSet; -import java.util.Set; +import java.util.*; class JsonArrayMatcher extends AbstractJsonMatcher { @@ -18,79 +17,78 @@ class JsonArrayMatcher extends AbstractJsonMatcher { } @Override - public void match() throws MatcherException { + public List match() { + List diffs = new ArrayList<>(); + for (int i = 0; i < expected.size(); i++) { JsonNode expElement = expected.get(i); if (isJsonPathNode(expElement)) { - new JsonMatcher(expElement, actual, comparator, compareModes).match(); + diffs.addAll(new JsonMatcher(expElement, actual, comparator, compareModes).match()); } else { - matchWithActualJsonArray(i, expElement, actual); + diffs.addAll(matchWithJsonArray(i, expElement, actual)); } } if (compareModes.contains(CompareMode.JSON_ARRAY_NON_EXTENSIBLE) && expected.size() < actual.size()) { - throw new MatcherException("Actual JSON ARRAY has extra elements"); + diffs.add("Actual JSON ARRAY has extra elements"); } + return diffs; } - private void matchWithActualJsonArray(int expPosition, JsonNode expElement, JsonNode actual) throws MatcherException { + private List matchWithJsonArray(int expPosition, JsonNode expElement, JsonNode actualArray) { + List diffs = new ArrayList<>(); UseCase useCase = getUseCase(expElement); - boolean found = false; - actualElementsLoop: - for (int j = 0; j < actual.size(); j++) { + + for (int j = 0; j < actualArray.size(); j++) { if (matchedPositions.contains(j)) { continue; } if (compareModes.contains(CompareMode.JSON_ARRAY_STRICT_ORDER) && j != expPosition) { continue; } + List elementDiffs; switch (useCase) { case MATCH: - JsonNode actElement = actual.get(j); - try { - new JsonMatcher(expElement, actElement, comparator, compareModes).match(); - } catch (MatcherException e) { + JsonNode actElement = actualArray.get(j); + elementDiffs = new JsonMatcher(expElement, actElement, comparator, compareModes).match(); + if (elementDiffs.isEmpty()) { + matchedPositions.add(j); + return Collections.emptyList(); + } else { if (compareModes.contains(CompareMode.JSON_ARRAY_STRICT_ORDER)) { - throw new MatcherException(String - .format("JSON ARRAY elements differ at position %s:\n%s", expPosition + 1, - MessageUtil.cropL(JSONCompare.prettyPrint(expElement)))); + diffs.add(String.format("\nJSON ARRAY elements differ at position %s:\n%s\nDifferences:\n%s", expPosition + 1, + MessageUtil.cropL(JSONCompare.prettyPrint(expElement)), String.join("\n", elementDiffs))); + return diffs; } - continue actualElementsLoop; } - found = true; - matchedPositions.add(j); - break actualElementsLoop; + break; case MATCH_ANY: matchedPositions.add(j); - return; + return Collections.emptyList(); case DO_NOT_MATCH: - actElement = actual.get(j); - if (!areOfSameType(expElement, actElement)) { - continue actualElementsLoop; - } - try { - new JsonMatcher(expElement, actElement, comparator, compareModes).match(); - } catch (MatcherException e) { - found = true; - break actualElementsLoop; + actElement = actualArray.get(j); + if (areOfSameType(expElement, actElement)) { + elementDiffs = new JsonMatcher(expElement, actElement, comparator, compareModes).match(); + if (!elementDiffs.isEmpty()) { + diffs.add("\nExpected element from position " + (expPosition + 1) + + " was FOUND:\n" + MessageUtil.cropL(JSONCompare.prettyPrint(expElement))); + return diffs; + } } break; case DO_NOT_MATCH_ANY: - throw new MatcherException("Expected element from position " + (expPosition + 1) - + " was FOUND:\n" + MessageUtil.cropL(JSONCompare.prettyPrint(expElement))); + diffs.add(String.format("\nExpected condition %s from position %s was not met." + + " Actual JSON array has extra elements.", + expElement, expPosition + 1)); + return diffs; } } - if (!found && useCase == UseCase.MATCH) { - throw new MatcherException("Expected element from position " + (expPosition + 1) + " was NOT FOUND:\n" - + MessageUtil.cropL(JSONCompare.prettyPrint(expElement))); - } - if (found && useCase == UseCase.DO_NOT_MATCH) { - throw new MatcherException("Expected element from position " + (expPosition + 1) - + " was FOUND:\n" + MessageUtil.cropL(JSONCompare.prettyPrint(expElement))); - } - if (useCase == UseCase.MATCH_ANY) { - throw new MatcherException("Expected condition of type MATCH_ANY from position " + (expPosition + 1) - + " was NOT MET. Actual Json Array has no extra elements:\n" + if (useCase == UseCase.MATCH) { + diffs.add("\nExpected element from position " + (expPosition + 1) + " was NOT FOUND:\n" + MessageUtil.cropL(JSONCompare.prettyPrint(expElement))); + } else if (useCase == UseCase.MATCH_ANY) { + diffs.add(String.format("\nExpected condition %s from position %s was not met." + + " Actual Json Array has no extra elements.", expElement, expPosition + 1)); } + return diffs; } } diff --git a/src/main/java/io/json/compare/matcher/JsonMatcher.java b/src/main/java/io/json/compare/matcher/JsonMatcher.java index 1b9639c..0b62eba 100644 --- a/src/main/java/io/json/compare/matcher/JsonMatcher.java +++ b/src/main/java/io/json/compare/matcher/JsonMatcher.java @@ -4,6 +4,9 @@ import io.json.compare.CompareMode; import io.json.compare.JsonComparator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Set; public class JsonMatcher extends AbstractJsonMatcher { @@ -13,20 +16,21 @@ public JsonMatcher(JsonNode expected, JsonNode actual, JsonComparator comparator } @Override - public void match() throws MatcherException { + public List match() { if (isJsonObject(expected) && isJsonObject(actual)) { - new JsonObjectMatcher(expected, actual, comparator, compareModes).match(); + return new JsonObjectMatcher(expected, actual, comparator, compareModes).match(); } else if (isJsonArray(expected) && isJsonArray(actual)) { - new JsonArrayMatcher(expected, actual, comparator, compareModes).match(); + return new JsonArrayMatcher(expected, actual, comparator, compareModes).match(); } else if (isValueNode(expected) && isValueNode(actual)) { - new JsonValueMatcher(expected, actual, comparator, compareModes).match(); + return new JsonValueMatcher(expected, actual, comparator, compareModes).match(); } else if (isJsonPathNode(expected)) { - new JsonObjectMatcher(expected, actual, comparator, compareModes).match(); + return new JsonObjectMatcher(expected, actual, comparator, compareModes).match(); } else if (isMissingNode(expected) && isMissingNode(actual)) { - //do nothing + return Collections.emptyList(); } else { - throw new MatcherException("Different JSON types: " - + expected.getClass().getSimpleName() + " vs " + actual.getClass().getSimpleName()); + List diffs = new ArrayList<>(); + diffs.add("Different JSON types: expected" + expected.getClass().getSimpleName() + " but got " + actual.getClass().getSimpleName()); + return diffs; } } } diff --git a/src/main/java/io/json/compare/matcher/JsonObjectMatcher.java b/src/main/java/io/json/compare/matcher/JsonObjectMatcher.java index b1cee9a..58174c3 100644 --- a/src/main/java/io/json/compare/matcher/JsonObjectMatcher.java +++ b/src/main/java/io/json/compare/matcher/JsonObjectMatcher.java @@ -16,7 +16,9 @@ class JsonObjectMatcher extends AbstractJsonMatcher { } @Override - public void match() throws MatcherException { + public List match() { + List diffs = new ArrayList<>(); + Iterator> it = expected.fields(); while (it.hasNext()) { Map.Entry entry = it.next(); @@ -27,21 +29,22 @@ public void match() throws MatcherException { Optional jsonPathExpression = extractJsonPathExp(expectedSanitizedField); List> candidateEntries = null; if (!jsonPathExpression.isPresent()) { - candidateEntries = searchCandidateEntriesByField(expectedSanitizedField, actual); + candidateEntries = searchCandidatesByField(expectedSanitizedField, actual); } switch (useCase) { case MATCH_ANY: case MATCH: if (!jsonPathExpression.isPresent()) { if (candidateEntries.isEmpty()) { - throw new MatcherException(String.format("Field '%s' was not found or cannot be matched", expectedField)); + diffs.add(String.format("Field '%s' was not found", expectedField)); + } else { + diffs.addAll(matchWithCandidates(expectedSanitizedField, expectedValue, candidateEntries)); } - matchWithCandidateEntries(expectedSanitizedField, expectedValue, candidateEntries); } else { try { - new JsonPathMatcher(jsonPathExpression.get(), expectedValue, actual, comparator, compareModes).match(); + diffs.addAll(new JsonPathMatcher(jsonPathExpression.get(), expectedValue, actual, comparator, compareModes).match()); } catch (PathNotFoundException e) { - throw new MatcherException(String.format("%s <- json path ('%s')", e.getMessage(), jsonPathExpression.get())); + diffs.add(String.format("json path ('%s') -> %s", jsonPathExpression.get(), e.getMessage())); } } break; @@ -49,7 +52,7 @@ public void match() throws MatcherException { case DO_NOT_MATCH: if (!jsonPathExpression.isPresent()) { if (!candidateEntries.isEmpty()) { - throw new MatcherException(String.format("Field '%s' was found", expectedField)); + diffs.add(String.format("Field '%s' was found", expectedField)); } } else { try { @@ -57,42 +60,44 @@ public void match() throws MatcherException { } catch (PathNotFoundException e) { break; } - throw new MatcherException(String.format("Json path '%s' was found", expectedField)); + diffs.add(String.format("Json path '%s' was found", expectedField)); } break; } } if (compareModes.contains(CompareMode.JSON_OBJECT_NON_EXTENSIBLE) && expected.size() < actual.size()) { - throw new MatcherException("Actual JSON OBJECT has extra fields"); + diffs.add("Actual JSON OBJECT has extra fields"); } + return diffs; } - private void matchWithCandidateEntries(String expectedKey, JsonNode expectedValue, List> candidates) throws MatcherException { + private List matchWithCandidates(String expectedField, JsonNode expectedValue, List> candidates) { + List diffs = new ArrayList<>(); + UseCase expectedValueUseCase = getUseCase(expectedValue); - for (ListIterator> it = candidates.listIterator(); it.hasNext(); ) { - Map.Entry candidateEntry = it.next(); + + for (Map.Entry candidateEntry : candidates) { String candidateField = candidateEntry.getKey(); + if (expectedValueUseCase == UseCase.MATCH_ANY) { matchedFieldNames.add(candidateField); - break; + return Collections.emptyList(); } + JsonNode candidateValue = candidateEntry.getValue(); - try { - new JsonMatcher(expectedValue, candidateValue, comparator, compareModes).match(); - } catch (MatcherException e) { - if (it.hasNext()) { - continue; - } else { - throw new MatcherException(String.format("%s <- %s", e.getMessage(), expectedKey)); - } + List candidateDiffs = new JsonMatcher(expectedValue, candidateValue, comparator, compareModes).match(); + if (candidateDiffs.isEmpty()) { + matchedFieldNames.add(candidateField); + return Collections.emptyList(); + } else { + candidateDiffs.forEach(diff -> diffs.add(String.format("%s -> %s", expectedField, diff))); } - matchedFieldNames.add(candidateField); - break; } + return diffs; } - private List> searchCandidateEntriesByField(String fieldName, JsonNode target) { - List> candidatesList = new ArrayList<>(); + private List> searchCandidatesByField(String fieldName, JsonNode target) { + List> candidates = new ArrayList<>(); Iterator> it = target.fields(); while (it.hasNext()) { Map.Entry entry = it.next(); @@ -101,9 +106,9 @@ private List> searchCandidateEntriesByField(String f continue; } if (comparator.compareFields(fieldName, key)) { - candidatesList.add(entry); + candidates.add(entry); } } - return candidatesList; + return candidates; } } \ No newline at end of file diff --git a/src/main/java/io/json/compare/matcher/JsonPathMatcher.java b/src/main/java/io/json/compare/matcher/JsonPathMatcher.java index 506c3c1..b0a9a91 100644 --- a/src/main/java/io/json/compare/matcher/JsonPathMatcher.java +++ b/src/main/java/io/json/compare/matcher/JsonPathMatcher.java @@ -10,6 +10,8 @@ import io.json.compare.CompareMode; import io.json.compare.JsonComparator; +import java.util.ArrayList; +import java.util.List; import java.util.Set; class JsonPathMatcher extends AbstractJsonMatcher { @@ -26,14 +28,12 @@ class JsonPathMatcher extends AbstractJsonMatcher { } @Override - public void match() throws MatcherException { - JsonNode result = null; - try { - result = MAPPER.convertValue(PARSE_CONTEXT.parse(actual).read(jsonPath), JsonNode.class); - new JsonMatcher(expected, result, comparator, compareModes).match(); - } catch (MatcherException e) { - throw new MatcherException(String.format("Expected json path result:\n%s\nBut got:\n%s\n\n%s <- json path ('%s')", - expected, result, e.getMessage(), jsonPath)); - } + public List match() { + List diffs = new ArrayList<>(); + JsonNode result = MAPPER.convertValue(PARSE_CONTEXT.parse(actual).read(jsonPath), JsonNode.class); + List jsonPathDiffs = new JsonMatcher(expected, result, comparator, compareModes).match(); + jsonPathDiffs.forEach(diff -> diffs.add(String.format("Json path ('%s') -> Expected json path result:\n%s\nBut got:\n%s\n\n%s", + jsonPath, expected, result, diff))); + return diffs; } } \ No newline at end of file diff --git a/src/main/java/io/json/compare/matcher/JsonValueMatcher.java b/src/main/java/io/json/compare/matcher/JsonValueMatcher.java index 8ac6e5f..f0c37cd 100644 --- a/src/main/java/io/json/compare/matcher/JsonValueMatcher.java +++ b/src/main/java/io/json/compare/matcher/JsonValueMatcher.java @@ -4,6 +4,8 @@ import io.json.compare.CompareMode; import io.json.compare.JsonComparator; +import java.util.ArrayList; +import java.util.List; import java.util.Set; class JsonValueMatcher extends AbstractJsonMatcher { @@ -13,41 +15,31 @@ class JsonValueMatcher extends AbstractJsonMatcher { } @Override - public void match() throws MatcherException { - UseCase useCase = getUseCase(expected.asText()); - matchTextTypes(); - matchNumberTypes(); - matchBooleanTypes(); - matchNullTypes(); - String expectedText = sanitize(expected.asText()); - String actualText = actual.asText(); + public List match() { + List diffs = new ArrayList<>(); + String diff = "\nExpected %s: %s But got: %s"; - if (!useCase.equals(UseCase.MATCH_ANY) && comparator.compareValues(expectedText, actualText) != useCase.equals(UseCase.MATCH)) { - throw new MatcherException(String.format("Expected value: %s But found: %s ", expected, actual)); - } - } - - private void matchNullTypes() throws MatcherException { if (expected.isNull() && !actual.isNull()) { - throw new MatcherException(String.format("Expected value: %s But found: %s ", expected, actual)); - } - } - - private void matchNumberTypes() throws MatcherException { - if (expected.isNumber() && !actual.isNumber()) { - throw new MatcherException(String.format("Expected value: %s But found: %s ", expected, actual)); - } - } - - private void matchBooleanTypes() throws MatcherException { - if (expected.isBoolean() && !actual.isBoolean()) { - throw new MatcherException(String.format("Expected value: %s But found: %s ", expected, actual)); - } - } - - private void matchTextTypes() throws MatcherException { - if (actual.isTextual() && !expected.isTextual()) { - throw new MatcherException(String.format("Expected value: %s But found: %s ", expected, actual)); + diffs.add(String.format(diff, "null", "", actual)); + return diffs; + } else if (expected.isNumber() && !actual.isNumber()) { + diffs.add(String.format(diff, "number", expected, actual)); + return diffs; + } else if (expected.isBoolean() && !actual.isBoolean()) { + diffs.add(String.format(diff, "boolean", expected, actual)); + return diffs; + } else if (actual.isTextual() && !expected.isTextual()) { + diffs.add(String.format(diff, "text", expected, actual)); + return diffs; + } else { + UseCase useCase = getUseCase(expected.asText()); + String expectedText = sanitize(expected.asText()); + String actualText = actual.asText(); + + if (!useCase.equals(UseCase.MATCH_ANY) && comparator.compareValues(expectedText, actualText) != useCase.equals(UseCase.MATCH)) { + diffs.add(String.format(diff, "value", expected, actual)); + } + return diffs; } } } \ No newline at end of file diff --git a/src/main/java/io/json/compare/matcher/MatcherException.java b/src/main/java/io/json/compare/matcher/MatcherException.java deleted file mode 100644 index e96074c..0000000 --- a/src/main/java/io/json/compare/matcher/MatcherException.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.json.compare.matcher; - -public class MatcherException extends Exception { - - public MatcherException(String msg) { - super(msg); - } -} diff --git a/src/test/java/io/json/compare/matcher/JSONPathCompareTests.java b/src/test/java/io/json/compare/matcher/JSONPathCompareTests.java index 6250ddc..390504a 100644 --- a/src/test/java/io/json/compare/matcher/JSONPathCompareTests.java +++ b/src/test/java/io/json/compare/matcher/JSONPathCompareTests.java @@ -196,7 +196,10 @@ public void checkInvalidOrNotFoundJsonPathErrorMessage() { try { JSONCompare.assertMatches(expected, actual); } catch (AssertionError e) { - assertTrue(e.getMessage().contains("No results for path: $['idontexist'] <- json path ('$.idontexist') <- a11 <- a1 <- a")); + assertTrue(e.getMessage().contains("FOUND 1 DIFFERENCE(S):\n" + + "\n" + + "_________________________DIFF__________________________\n" + + "a -> a1 -> a11 -> json path ('$.idontexist') -> No results for path: $['idontexist']")); return; } fail("No error thrown"); @@ -216,7 +219,10 @@ public void checkJsonPathAssertionErrorMessage() { try { JSONCompare.assertMatches(expected, actual); } catch (AssertionError e) { - assertTrue(e.getMessage().contains("But found: \"lorem\" <- json path ('$.a') <- a11 <- a1 <- a")); + assertTrue(e.getMessage().contains("a -> a1 -> a11 -> Json path ('$.a') -> Expected json path result:\n" + + "\"lorem1\"\n" + + "But got:\n" + + "\"lorem\"")); return; } fail("No error thrown"); diff --git a/src/test/java/io/json/compare/matcher/diffs/JsonObjectDiffTests.java b/src/test/java/io/json/compare/matcher/diffs/JsonObjectDiffTests.java new file mode 100644 index 0000000..1f52498 --- /dev/null +++ b/src/test/java/io/json/compare/matcher/diffs/JsonObjectDiffTests.java @@ -0,0 +1,14 @@ +package io.json.compare.matcher.diffs; + +import io.json.compare.JSONCompare; +import org.junit.jupiter.api.Test; + +public class JsonObjectDiffTests { + + @Test + public void compareWithNumbers() { + String expected = "{\"b\":1,\"a\":2}"; + String actual = "{\"a\":2,\"b\":1}"; + JSONCompare.assertMatches(expected, actual); + } +} diff --git a/src/test/java/io/json/compare/matcher/diffs/JsonValueDiffTests.java b/src/test/java/io/json/compare/matcher/diffs/JsonValueDiffTests.java new file mode 100644 index 0000000..c358ee5 --- /dev/null +++ b/src/test/java/io/json/compare/matcher/diffs/JsonValueDiffTests.java @@ -0,0 +1,50 @@ +package io.json.compare.matcher.diffs; + +import io.json.compare.JSONCompare; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JsonValueDiffTests { + + @Test + public void compareNulls() { + String expected = "{\"a\":null}"; + String actual = "{\"a\":\"null\"}"; + AssertionError error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected, actual)); + assertTrue(error.getMessage().matches("(?s).*FOUND 1 DIFFERENCE.*a ->.*Expected null: But got: \"null\".*")); + JSONCompare.assertNotMatches(expected, actual); + } + + @Test + public void compareBooleans() { + String expected = "{\"a\":false}"; + String actual = "{\"a\":\"false\"}"; + AssertionError error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected, actual)); + assertTrue(error.getMessage().matches("(?s).*FOUND 1 DIFFERENCE.*a ->.*Expected boolean: false But got: \"false\".*")); + JSONCompare.assertNotMatches(expected, actual); + } + + @Test + public void compareNumbers() { + String expected = "{\"a\":2}"; + String actual = "{\"a\":\"2\"}"; + AssertionError error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected, actual)); + assertTrue(error.getMessage().matches("(?s).*FOUND 1 DIFFERENCE.*a ->.*Expected number: 2 But got: \"2\".*")); + JSONCompare.assertNotMatches(expected, actual); + } + + @Test + public void compareAll() { + String expected = "{\"a\":null,\"b\":1,\"c\":false,\"d\":\"false\",\"e\":\"text\"}"; + String actual = "{\"a\":\"null\",\"b\":\"1\",\"c\":\"false\",\"d\":false,\"e\":false}"; + AssertionError error = assertThrows(AssertionError.class, () -> JSONCompare.assertMatches(expected, actual)); + assertTrue(error.getMessage().matches("(?s).*FOUND 4 DIFFERENCE.*" + + "a ->.*Expected null: But got: \"null\".*" + + "b ->.*Expected number: 1 But got: \"1\".*" + + "c ->.*Expected boolean: false But got: \"false\".*" + + "e ->.*Expected value: \"text\" But got: false.*")); + JSONCompare.assertNotMatches(expected, actual); + } +} diff --git a/src/test/java/io/json/compare/matcher/issues/Issue11Test.java b/src/test/java/io/json/compare/matcher/issues/Issue11Test.java index 6a3201c..7af9907 100644 --- a/src/test/java/io/json/compare/matcher/issues/Issue11Test.java +++ b/src/test/java/io/json/compare/matcher/issues/Issue11Test.java @@ -232,7 +232,7 @@ public void testJsonArrayStrictOrderWithRegexFieldsThrowsCorrectMessage() { try { JSONCompare.assertMatches(expected, actual, new HashSet<>(Arrays.asList(CompareMode.JSON_ARRAY_STRICT_ORDER))); } catch (AssertionError e) { - assertTrue(e.getMessage().contains("was not found or cannot be matched")); + assertTrue(e.getMessage().contains("was not found")); } }