From 4c7870a675b18f939c07fe203141f5a344f26b2d Mon Sep 17 00:00:00 2001 From: Lukas Krecan Date: Tue, 18 May 2021 19:45:55 +0200 Subject: [PATCH 1/6] #361 Fix containsEntry --- .../jsonunit/assertj/JsonMapAssert.java | 11 ++++++++++- .../test/base/AbstractAssertJTest.java | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java index bffead963..e143589b5 100644 --- a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java +++ b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java @@ -25,6 +25,7 @@ import java.util.Map; +import static net.javacrumbs.jsonunit.core.internal.JsonUtils.convertToJson; import static org.assertj.core.error.ShouldContainValue.shouldContainValue; import static org.assertj.core.error.ShouldNotContainValue.shouldNotContainValue; @@ -106,6 +107,14 @@ public MapAssert isEqualToComparingFieldByFieldRecursively(@Null throw unsupportedOperation(); } + @Override + public MapAssert containsEntry(String key, Object value) { + if (value instanceof Node) { + return super.containsEntry(key, ((Node) value).getValue()); + } else { + return super.containsEntry(key, convertToJson(value, "expected", true).getValue()); + } + } /** * Does not work. Use {@link #containsKey(Object)} instead. @@ -153,7 +162,7 @@ public MapAssert hasAllNullFieldsOrPropertiesExcept(String... pr public MapAssert hasNoNullFieldsOrProperties() { return super.hasNoNullFieldsOrProperties(); } - + /** * Does not work. https://github.com/lukas-krecan/JsonUnit/issues/324 */ diff --git a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java index 3b9a35ff2..a4e974c80 100644 --- a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java +++ b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java @@ -113,6 +113,24 @@ void shouldFailCorrectlyOnNull() { ).hasMessage("JSON documents are different:\nDifferent value found in node \"\", expected: <1> but was: .\n"); } + @Test + void containsEntryShouldWork() { + String entryValue = "{\n" + + " \"approvable\" : true," + + " \"rejectable\" : false" + + "}"; + + String input = "[{\"allowedActions\":" + entryValue + "}]"; + + assertThatJson(input, + body -> body.isArray().hasSize(1), + body -> body.inPath("[0]").isObject().containsEntry("allowedActions", json(entryValue)), + body -> body.inPath("[0]").isObject().containsEntry("allowedActions", entryValue), + //body -> body.inPath("[0]").isObject().contains(entry("allowedActions", entryValue)), + body -> body.inPath("[0].allowedActions").isObject().isEqualTo(json(entryValue)) + ); + } + @Test void absentOnArray() { String json = "[{\"a\":1},{\"b\":1}]"; From 6606a9f0adcaaefcf7ca11ff44839fd5753f571a Mon Sep 17 00:00:00 2001 From: Lukas Krecan Date: Tue, 18 May 2021 20:12:11 +0200 Subject: [PATCH 2/6] #361 Fix other entry methods --- .../jsonunit/assertj/JsonAssert.java | 3 +- .../jsonunit/assertj/JsonMapAssert.java | 87 ++++++++++++++----- .../test/base/AbstractAssertJTest.java | 9 +- 3 files changed, 75 insertions(+), 24 deletions(-) diff --git a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonAssert.java b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonAssert.java index 339ebc08d..d9c142169 100644 --- a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonAssert.java +++ b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonAssert.java @@ -33,7 +33,6 @@ import org.assertj.core.api.BigIntegerAssert; import org.assertj.core.api.BooleanAssert; import org.assertj.core.api.ListAssert; -import org.assertj.core.api.MapAssert; import org.assertj.core.api.StringAssert; import org.assertj.core.api.UriAssert; import org.assertj.core.description.Description; @@ -127,7 +126,7 @@ public JsonAssert isEqualTo(@Nullable Object expected) { */ @NotNull @SuppressWarnings("unchecked") - public MapAssert isObject() { + public JsonMapAssert isObject() { Node node = assertType(OBJECT); return new JsonMapAssert((Map) node.getValue(), path.asPrefix(), configuration) .as("Different value found in node \"%s\"", path); diff --git a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java index e143589b5..03c4b5366 100644 --- a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java +++ b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java @@ -19,22 +19,24 @@ import net.javacrumbs.jsonunit.core.internal.Diff; import net.javacrumbs.jsonunit.core.internal.Node; import net.javacrumbs.jsonunit.core.internal.Path; -import org.assertj.core.api.MapAssert; +import org.assertj.core.api.AbstractMapAssert; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Map; -import static net.javacrumbs.jsonunit.core.internal.JsonUtils.convertToJson; +import static java.util.Arrays.stream; +import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.error.ShouldContainValue.shouldContainValue; import static org.assertj.core.error.ShouldNotContainValue.shouldNotContainValue; +import static org.assertj.core.util.Arrays.array; -class JsonMapAssert extends MapAssert { +public class JsonMapAssert extends AbstractMapAssert, String, Object> { private final Configuration configuration; private final Path path; JsonMapAssert(Map actual, Path path, Configuration configuration) { - super(actual); + super(actual, JsonMapAssert.class); this.path = path; this.configuration = configuration; usingComparator(new JsonComparator(configuration, path.asPrefix(), true)); @@ -48,7 +50,7 @@ public JsonMapAssert isEqualTo(@Nullable Object expected) { @Override @NotNull - public MapAssert containsValue(@Nullable Object expected) { + public JsonMapAssert containsValue(@Nullable Object expected) { if (expected instanceof Node) { if (!contains(expected)) { throwAssertionError(shouldContainValue(actual, expected)); @@ -61,7 +63,7 @@ public MapAssert containsValue(@Nullable Object expected) { @Override @NotNull - public MapAssert doesNotContainValue(@Nullable Object expected) { + public JsonMapAssert doesNotContainValue(@Nullable Object expected) { if (expected instanceof Node) { if (contains(expected)) { throwAssertionError(shouldNotContainValue(actual, expected)); @@ -82,37 +84,82 @@ public JsonMapAssert isEqualToIgnoringGivenFields(@Nullable Object other, @NotNu @Override @NotNull @Deprecated - public MapAssert isEqualToComparingOnlyGivenFields(@Nullable Object other, @NotNull String... propertiesOrFieldsUsedInComparison) { + public JsonMapAssert isEqualToComparingOnlyGivenFields(@Nullable Object other, @NotNull String... propertiesOrFieldsUsedInComparison) { throw unsupportedOperation(); } @Override @NotNull @Deprecated - public MapAssert isEqualToIgnoringNullFields(@Nullable Object other) { + public JsonMapAssert isEqualToIgnoringNullFields(@Nullable Object other) { throw unsupportedOperation(); } @Override @NotNull @Deprecated - public MapAssert isEqualToComparingFieldByField(@Nullable Object other) { + public JsonMapAssert isEqualToComparingFieldByField(@Nullable Object other) { throw unsupportedOperation(); } @Override @NotNull @Deprecated - public MapAssert isEqualToComparingFieldByFieldRecursively(@Nullable Object other) { + public JsonMapAssert isEqualToComparingFieldByFieldRecursively(@Nullable Object other) { throw unsupportedOperation(); } @Override - public MapAssert containsEntry(String key, Object value) { - if (value instanceof Node) { - return super.containsEntry(key, ((Node) value).getValue()); + public JsonMapAssert containsEntry(String key, Object value) { + return contains(array(entry(key, value))); + } + + @SafeVarargs + @Override + public final JsonMapAssert containsAnyOf(Map.Entry... entries) { + return super.containsAnyOf(wrap(entries)); + } + + @Override + public JsonMapAssert containsAllEntriesOf(Map other) { + return contains(toEntries(other)); + } + + @SafeVarargs + @Override + public final JsonMapAssert containsExactly(Map.Entry... entries) { + return super.containsExactly(wrap(entries)); + } + + @SafeVarargs + @Override + public final JsonMapAssert containsOnly(Map.Entry... entries) { + return super.containsOnly(wrap(entries)); + } + + @Override + @SafeVarargs + public final JsonMapAssert contains(Map.Entry... entries) { + return super.contains(wrap(entries)); + } + + @NotNull + @SuppressWarnings("unchecked") + private Map.Entry[] wrap(Map.Entry[] entries) { + return stream(entries).map(this::wrapEntry).toArray(Map.Entry[]::new); + } + + @SuppressWarnings("unchecked") + private Map.Entry[] toEntries(Map map) { + return map.entrySet().toArray(new Map.Entry[0]); + } + + private Map.Entry wrapEntry(Map.Entry entry) { + if (entry.getValue() instanceof Node) { + return entry(entry.getKey(), ((Node) entry.getValue()).getValue()); } else { - return super.containsEntry(key, convertToJson(value, "expected", true).getValue()); + // if it's not a node, we do not touch it + return entry; } } @@ -122,7 +169,7 @@ public MapAssert containsEntry(String key, Object value) { */ @Override @Deprecated - public MapAssert hasFieldOrProperty(String name) { + public JsonMapAssert hasFieldOrProperty(String name) { return super.hasFieldOrProperty(name); } @@ -132,7 +179,7 @@ public MapAssert hasFieldOrProperty(String name) { */ @Override @Deprecated - public MapAssert hasFieldOrPropertyWithValue(String name, Object value) { + public JsonMapAssert hasFieldOrPropertyWithValue(String name, Object value) { return super.hasFieldOrPropertyWithValue(name, value); } @@ -141,7 +188,7 @@ public MapAssert hasFieldOrPropertyWithValue(String name, Object */ @Override @Deprecated - public MapAssert hasAllNullFieldsOrProperties() { + public JsonMapAssert hasAllNullFieldsOrProperties() { return super.hasAllNullFieldsOrProperties(); } @@ -150,7 +197,7 @@ public MapAssert hasAllNullFieldsOrProperties() { */ @Override @Deprecated - public MapAssert hasAllNullFieldsOrPropertiesExcept(String... propertiesOrFieldsToIgnore) { + public JsonMapAssert hasAllNullFieldsOrPropertiesExcept(String... propertiesOrFieldsToIgnore) { return super.hasAllNullFieldsOrPropertiesExcept(propertiesOrFieldsToIgnore); } @@ -159,7 +206,7 @@ public MapAssert hasAllNullFieldsOrPropertiesExcept(String... pr */ @Deprecated @Override - public MapAssert hasNoNullFieldsOrProperties() { + public JsonMapAssert hasNoNullFieldsOrProperties() { return super.hasNoNullFieldsOrProperties(); } @@ -168,7 +215,7 @@ public MapAssert hasNoNullFieldsOrProperties() { */ @Override @Deprecated - public MapAssert hasNoNullFieldsOrPropertiesExcept(String... propertiesOrFieldsToIgnore) { + public JsonMapAssert hasNoNullFieldsOrPropertiesExcept(String... propertiesOrFieldsToIgnore) { return super.hasNoNullFieldsOrPropertiesExcept(propertiesOrFieldsToIgnore); } diff --git a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java index a4e974c80..52b661964 100644 --- a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java +++ b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java @@ -125,8 +125,13 @@ void containsEntryShouldWork() { assertThatJson(input, body -> body.isArray().hasSize(1), body -> body.inPath("[0]").isObject().containsEntry("allowedActions", json(entryValue)), - body -> body.inPath("[0]").isObject().containsEntry("allowedActions", entryValue), - //body -> body.inPath("[0]").isObject().contains(entry("allowedActions", entryValue)), + body -> body.inPath("[0]").isObject().contains(entry("allowedActions", json(entryValue))), + body -> body.inPath("[0]").isObject().containsAllEntriesOf(singletonMap("allowedActions", json(entryValue))), + body -> body.inPath("[0]").isObject().containsAnyOf(entry("allowedActions", json(entryValue)), entry("test", 1)), + body -> body.inPath("[0]").isObject().containsExactlyEntriesOf(singletonMap("allowedActions", json(entryValue))), + body -> body.inPath("[0]").isObject().containsExactly(entry("allowedActions", json(entryValue))), + body -> body.inPath("[0]").isObject().containsExactlyInAnyOrderEntriesOf(singletonMap("allowedActions", json(entryValue))), + body -> body.inPath("[0]").isObject().containsOnly(entry("allowedActions", json(entryValue))), body -> body.inPath("[0].allowedActions").isObject().isEqualTo(json(entryValue)) ); } From 8c4d46ee4f946b8421622ff4ad82ca88aa8a199c Mon Sep 17 00:00:00 2001 From: Lukas Krecan Date: Tue, 18 May 2021 20:59:13 +0200 Subject: [PATCH 3/6] Fix values check --- .../jsonunit/assertj/JsonMapAssert.java | 19 +++++++++++++++++++ .../test/base/AbstractAssertJTest.java | 2 ++ 2 files changed, 21 insertions(+) diff --git a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java index 03c4b5366..088ca0687 100644 --- a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java +++ b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java @@ -143,12 +143,22 @@ public final JsonMapAssert contains(Map.Entry... entries) { return super.contains(wrap(entries)); } + @Override + public JsonMapAssert containsValues(Object... values) { + return super.containsValues(wrapValues(values)); + } + + private Object[] wrapValues(Object[] values) { + return stream(values).map(this::wrapValue).toArray(); + } + @NotNull @SuppressWarnings("unchecked") private Map.Entry[] wrap(Map.Entry[] entries) { return stream(entries).map(this::wrapEntry).toArray(Map.Entry[]::new); } + @SuppressWarnings("unchecked") private Map.Entry[] toEntries(Map map) { return map.entrySet().toArray(new Map.Entry[0]); @@ -163,6 +173,15 @@ public final JsonMapAssert contains(Map.Entry... entries) { } } + private Object wrapValue(Object value) { + if (value instanceof Node) { + return ((Node) value).getValue(); + } else { + // if it's not a node, we do not touch it + return value; + } + } + /** * Does not work. Use {@link #containsKey(Object)} instead. * https://github.com/lukas-krecan/JsonUnit/issues/324 diff --git a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java index 52b661964..793b433ed 100644 --- a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java +++ b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java @@ -132,6 +132,8 @@ void containsEntryShouldWork() { body -> body.inPath("[0]").isObject().containsExactly(entry("allowedActions", json(entryValue))), body -> body.inPath("[0]").isObject().containsExactlyInAnyOrderEntriesOf(singletonMap("allowedActions", json(entryValue))), body -> body.inPath("[0]").isObject().containsOnly(entry("allowedActions", json(entryValue))), + body -> body.inPath("[0]").isObject().containsValues(json(entryValue)), + body -> body.inPath("[0]").isObject().containsValue(json(entryValue)), body -> body.inPath("[0].allowedActions").isObject().isEqualTo(json(entryValue)) ); } From def84ed9d99addf914ee6e9c201aa31073e6be8b Mon Sep 17 00:00:00 2001 From: Lukas Krecan Date: Wed, 19 May 2021 19:43:00 +0200 Subject: [PATCH 4/6] Fix containValues --- .../jsonunit/assertj/JsonMapAssert.java | 16 ++-------------- .../test/base/AbstractAssertJTest.java | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java index 088ca0687..2430ce392 100644 --- a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java +++ b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java @@ -145,11 +145,8 @@ public final JsonMapAssert contains(Map.Entry... entries) { @Override public JsonMapAssert containsValues(Object... values) { - return super.containsValues(wrapValues(values)); - } - - private Object[] wrapValues(Object[] values) { - return stream(values).map(this::wrapValue).toArray(); + stream(values).forEach(this::containsValue); + return this; } @NotNull @@ -173,15 +170,6 @@ private Object[] wrapValues(Object[] values) { } } - private Object wrapValue(Object value) { - if (value instanceof Node) { - return ((Node) value).getValue(); - } else { - // if it's not a node, we do not touch it - return value; - } - } - /** * Does not work. Use {@link #containsKey(Object)} instead. * https://github.com/lukas-krecan/JsonUnit/issues/324 diff --git a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java index 793b433ed..6238e85d1 100644 --- a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java +++ b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java @@ -138,6 +138,24 @@ void containsEntryShouldWork() { ); } + @Test + void containsValuesShouldPass() { + String json = "{\"a\": 1, \"b\": 2}"; + assertThatJson(json).isObject().containsValues(valueOf(1), valueOf(2), json("\"${json-unit.any-number}\"")); + } + + @Test + void containsValuesShouldFail() { + String json = "{\"a\": 1, \"b\": 2}"; + assertThatThrownBy(() -> + assertThatJson(json).isObject().containsValues(valueOf(1), valueOf(2), json("\"${json-unit.any-string}\"")) + ).hasMessage("[Different value found in node \"\"] \n" + + "Expecting:\n" + + " {\"a\":1,\"b\":2}\n" + + "to contain value:\n" + + " \"${json-unit.any-string}\""); + } + @Test void absentOnArray() { String json = "[{\"a\":1},{\"b\":1}]"; From b3bbe7c2cdffdc528e670abc5582f5dc6d80be94 Mon Sep 17 00:00:00 2001 From: Lukas Krecan Date: Wed, 19 May 2021 20:00:36 +0200 Subject: [PATCH 5/6] Fix containsEntry --- .../jsonunit/assertj/JsonMapAssert.java | 51 ++++++++++++++----- .../test/base/AbstractAssertJTest.java | 26 ++++++++++ 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java index 2430ce392..24701cbb6 100644 --- a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java +++ b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java @@ -23,10 +23,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; import static java.util.Arrays.stream; +import static java.util.Objects.deepEquals; +import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.entry; +import static org.assertj.core.error.ShouldContain.shouldContain; import static org.assertj.core.error.ShouldContainValue.shouldContainValue; import static org.assertj.core.error.ShouldNotContainValue.shouldNotContainValue; import static org.assertj.core.util.Arrays.array; @@ -116,7 +121,7 @@ public JsonMapAssert containsEntry(String key, Object value) { @SafeVarargs @Override - public final JsonMapAssert containsAnyOf(Map.Entry... entries) { + public final JsonMapAssert containsAnyOf(Entry... entries) { return super.containsAnyOf(wrap(entries)); } @@ -127,20 +132,38 @@ public JsonMapAssert containsAllEntriesOf(Map other) { @SafeVarargs @Override - public final JsonMapAssert containsExactly(Map.Entry... entries) { + public final JsonMapAssert containsExactly(Entry... entries) { return super.containsExactly(wrap(entries)); } @SafeVarargs @Override - public final JsonMapAssert containsOnly(Map.Entry... entries) { + public final JsonMapAssert containsOnly(Entry... entries) { return super.containsOnly(wrap(entries)); } @Override @SafeVarargs - public final JsonMapAssert contains(Map.Entry... entries) { - return super.contains(wrap(entries)); + public final JsonMapAssert contains(Entry... expected) { + List> notFound = stream(expected).filter(entry -> !doesContainEntry(entry)).collect(toList()); + if (!notFound.isEmpty()) { + throwAssertionError(shouldContain(actual, expected, notFound)); + } + return this; + } + + private boolean doesContainEntry(Entry entry) { + String key = entry.getKey(); + if (!actual.containsKey(key)) { + return false; + } + Object actualValue = actual.get(key); + if (entry.getValue() instanceof Node) { + Node value = (Node) entry.getValue(); + return isSimilar(actualValue, value); + } else { + return deepEquals(actualValue, entry.getValue()); + } } @Override @@ -151,17 +174,17 @@ public JsonMapAssert containsValues(Object... values) { @NotNull @SuppressWarnings("unchecked") - private Map.Entry[] wrap(Map.Entry[] entries) { - return stream(entries).map(this::wrapEntry).toArray(Map.Entry[]::new); + private Entry[] wrap(Entry[] entries) { + return stream(entries).map(this::wrapEntry).toArray(Entry[]::new); } @SuppressWarnings("unchecked") - private Map.Entry[] toEntries(Map map) { - return map.entrySet().toArray(new Map.Entry[0]); + private Entry[] toEntries(Map map) { + return map.entrySet().toArray(new Entry[0]); } - private Map.Entry wrapEntry(Map.Entry entry) { + private Entry wrapEntry(Entry entry) { if (entry.getValue() instanceof Node) { return entry(entry.getKey(), ((Node) entry.getValue()).getValue()); } else { @@ -181,7 +204,7 @@ public JsonMapAssert hasFieldOrProperty(String name) { } /** - * Does not work. Use {@link #contains(Map.Entry[])} instead. + * Does not work. Use {@link #contains(Entry[])} instead. * https://github.com/lukas-krecan/JsonUnit/issues/324 */ @Override @@ -240,6 +263,10 @@ private JsonMapAssert compare(@Nullable Object other, @NotNull Configuration con } private boolean contains(Object expected) { - return actual.entrySet().stream().anyMatch(kv -> Diff.create(expected, kv.getValue(), "fullJson", path.asPrefix(), configuration).similar()); + return actual.entrySet().stream().anyMatch(entry -> isSimilar(entry.getValue(), expected)); + } + + private boolean isSimilar(Object actual, Object expected) { + return Diff.create(expected, actual, "fullJson", path.asPrefix(), configuration).similar(); } } diff --git a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java index 6238e85d1..2e061bd40 100644 --- a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java +++ b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java @@ -138,6 +138,32 @@ void containsEntryShouldWork() { ); } + @Test + void containsEntryShouldWorkWithMatcher() { + String json = "{\"a\": 1, \"b\": 2}"; + assertThatJson(json).isObject().containsEntry("a", json("\"${json-unit.any-number}\"")); + assertThatJson(json).isObject().contains(entry("a", json("\"${json-unit.any-number}\""))); + } + + @Test + void containsEntryShouldFailWithMatcher() { + String json = "{\"a\": 1, \"b\": 2}"; + + assertThatThrownBy(() -> + assertThatJson(json).isObject().contains( + entry("a", json("\"${json-unit.any-string}\"")), + entry("b", json("\"${json-unit.any-number}\"")) + ) + ).hasMessage("[Different value found in node \"\"] \n" + + "Expecting map:\n" + + " {\"a\":1,\"b\":2}\n" + + "to contain:\n" + + " [MapEntry[key=\"a\", value=\"${json-unit.any-string}\"],\n" + + " MapEntry[key=\"b\", value=\"${json-unit.any-number}\"]]\n" + + "but could not find the following map entries:\n" + + " [MapEntry[key=\"a\", value=\"${json-unit.any-string}\"]]\n"); + } + @Test void containsValuesShouldPass() { String json = "{\"a\": 1, \"b\": 2}"; From f5686e575cb591fd850bab64b55a0ec5a1f0f30a Mon Sep 17 00:00:00 2001 From: Lukas Krecan Date: Sat, 22 May 2021 20:57:05 +0200 Subject: [PATCH 6/6] Fix contains entry --- .../jsonunit/assertj/JsonMapAssert.java | 52 +++++++++++-------- .../test/base/AbstractAssertJTest.java | 38 +++++++++++++- 2 files changed, 67 insertions(+), 23 deletions(-) diff --git a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java index 24701cbb6..db3630cde 100644 --- a/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java +++ b/json-unit-assertj/src/main/java/net/javacrumbs/jsonunit/assertj/JsonMapAssert.java @@ -26,12 +26,15 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.stream.Collectors; import static java.util.Arrays.stream; import static java.util.Objects.deepEquals; import static java.util.stream.Collectors.toList; +import static net.javacrumbs.jsonunit.core.internal.JsonUtils.wrapDeserializedObject; import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.error.ShouldContain.shouldContain; +import static org.assertj.core.error.ShouldContainAnyOf.shouldContainAnyOf; import static org.assertj.core.error.ShouldContainValue.shouldContainValue; import static org.assertj.core.error.ShouldNotContainValue.shouldNotContainValue; import static org.assertj.core.util.Arrays.array; @@ -122,7 +125,11 @@ public JsonMapAssert containsEntry(String key, Object value) { @SafeVarargs @Override public final JsonMapAssert containsAnyOf(Entry... entries) { - return super.containsAnyOf(wrap(entries)); + boolean anyMatch = stream(entries).anyMatch(this::doesContainEntry); + if (!anyMatch) { + throwAssertionError(shouldContainAnyOf(actual, entries)); + } + return this; } @Override @@ -130,22 +137,41 @@ public JsonMapAssert containsAllEntriesOf(Map other) { return contains(toEntries(other)); } + /** + * This method does not support JsonUnit features. Prefer {@link #containsOnly(Entry[])} + */ @SafeVarargs @Override + @Deprecated public final JsonMapAssert containsExactly(Entry... entries) { - return super.containsExactly(wrap(entries)); + return super.containsExactly(entries); + } + + /** + * This method does not support JsonUnit features. Prefer {@link #containsOnly(Entry[])} + */ + @Override + @Deprecated + public JsonMapAssert containsExactlyEntriesOf(Map map) { + return super.containsExactlyEntriesOf(map); } @SafeVarargs @Override - public final JsonMapAssert containsOnly(Entry... entries) { - return super.containsOnly(wrap(entries)); + public final JsonMapAssert containsOnly(Entry... expected) { + Map expectedAsMap = stream(expected).collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + return isEqualTo(wrapDeserializedObject(expectedAsMap)); + } + + @NotNull + private List> entriesNotFoundInMap(Entry[] expected) { + return stream(expected).filter(entry -> !doesContainEntry(entry)).collect(toList()); } @Override @SafeVarargs public final JsonMapAssert contains(Entry... expected) { - List> notFound = stream(expected).filter(entry -> !doesContainEntry(entry)).collect(toList()); + List> notFound = entriesNotFoundInMap(expected); if (!notFound.isEmpty()) { throwAssertionError(shouldContain(actual, expected, notFound)); } @@ -172,27 +198,11 @@ public JsonMapAssert containsValues(Object... values) { return this; } - @NotNull - @SuppressWarnings("unchecked") - private Entry[] wrap(Entry[] entries) { - return stream(entries).map(this::wrapEntry).toArray(Entry[]::new); - } - - @SuppressWarnings("unchecked") private Entry[] toEntries(Map map) { return map.entrySet().toArray(new Entry[0]); } - private Entry wrapEntry(Entry entry) { - if (entry.getValue() instanceof Node) { - return entry(entry.getKey(), ((Node) entry.getValue()).getValue()); - } else { - // if it's not a node, we do not touch it - return entry; - } - } - /** * Does not work. Use {@link #containsKey(Object)} instead. * https://github.com/lukas-krecan/JsonUnit/issues/324 diff --git a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java index 2e061bd40..7fa608997 100644 --- a/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java +++ b/tests/test-base/src/main/java/net/javacrumbs/jsonunit/test/base/AbstractAssertJTest.java @@ -128,8 +128,6 @@ void containsEntryShouldWork() { body -> body.inPath("[0]").isObject().contains(entry("allowedActions", json(entryValue))), body -> body.inPath("[0]").isObject().containsAllEntriesOf(singletonMap("allowedActions", json(entryValue))), body -> body.inPath("[0]").isObject().containsAnyOf(entry("allowedActions", json(entryValue)), entry("test", 1)), - body -> body.inPath("[0]").isObject().containsExactlyEntriesOf(singletonMap("allowedActions", json(entryValue))), - body -> body.inPath("[0]").isObject().containsExactly(entry("allowedActions", json(entryValue))), body -> body.inPath("[0]").isObject().containsExactlyInAnyOrderEntriesOf(singletonMap("allowedActions", json(entryValue))), body -> body.inPath("[0]").isObject().containsOnly(entry("allowedActions", json(entryValue))), body -> body.inPath("[0]").isObject().containsValues(json(entryValue)), @@ -145,6 +143,15 @@ void containsEntryShouldWorkWithMatcher() { assertThatJson(json).isObject().contains(entry("a", json("\"${json-unit.any-number}\""))); } + @Test + void containsOnlyShouldWorkWithMatcher() { + String json = "{\"a\": 1, \"b\": 2}"; + assertThatJson(json).isObject().containsOnly( + entry("a", json("\"${json-unit.any-number}\"")), + entry("b", json("\"${json-unit.any-number}\"")) + ); + } + @Test void containsEntryShouldFailWithMatcher() { String json = "{\"a\": 1, \"b\": 2}"; @@ -164,6 +171,33 @@ void containsEntryShouldFailWithMatcher() { " [MapEntry[key=\"a\", value=\"${json-unit.any-string}\"]]\n"); } + @Test + void containsAnyOfShouldWorkWithMatcher() { + String json = "{\"a\": 1, \"b\": 2}"; + assertThatJson(json).isObject().containsAnyOf( + entry("a", json("\"${json-unit.any-string}\"")), + entry("a", json("\"${json-unit.any-number}\"")) + ); + } + + @Test + void containsAnyOfShouldFailWithMatcher() { + String json = "{\"a\": 1, \"b\": 2}"; + + assertThatThrownBy(() -> + assertThatJson(json).isObject().containsAnyOf( + entry("a", json("\"${json-unit.any-string}\"")), + entry("b", json("\"${json-unit.any-string}\"")) + ) + ).hasMessage("[Different value found in node \"\"] \n" + + "Expecting:\n" + + " {\"a\":1,\"b\":2}\n" + + "to contain at least one of the following elements:\n" + + " [MapEntry[key=\"a\", value=\"${json-unit.any-string}\"],\n" + + " MapEntry[key=\"b\", value=\"${json-unit.any-string}\"]]\n" + + "but none were found "); + } + @Test void containsValuesShouldPass() { String json = "{\"a\": 1, \"b\": 2}";