diff --git a/src/main/java/uk/org/webcompere/modelassert/json/condition/tree/TreeComparisonCondition.java b/src/main/java/uk/org/webcompere/modelassert/json/condition/tree/TreeComparisonCondition.java index 58f962c..78c4d4a 100644 --- a/src/main/java/uk/org/webcompere/modelassert/json/condition/tree/TreeComparisonCondition.java +++ b/src/main/java/uk/org/webcompere/modelassert/json/condition/tree/TreeComparisonCondition.java @@ -91,6 +91,12 @@ void compareTrees(JsonNode actual, JsonNode expected, Location pathToHere, List< return; } + boolean usingNullMatchedEmpty = findRule(pathToHere, TreeRule.NULL_MATCHES_EMPTY_ARRAY).isPresent(); + if (usingNullMatchedEmpty && ( + actual.isNull() && expected.isEmpty() || actual.isEmpty() && expected.isNull())) { + return; + } + // early exit if types don't match if (actual.getNodeType() != expected.getNodeType()) { failures.add(pathToHere.toString() + " different types: expected " + expected.getNodeType() + diff --git a/src/main/java/uk/org/webcompere/modelassert/json/condition/tree/TreeRule.java b/src/main/java/uk/org/webcompere/modelassert/json/condition/tree/TreeRule.java index a721862..60b8952 100644 --- a/src/main/java/uk/org/webcompere/modelassert/json/condition/tree/TreeRule.java +++ b/src/main/java/uk/org/webcompere/modelassert/json/condition/tree/TreeRule.java @@ -27,6 +27,11 @@ public enum TreeRule { */ ARRAY_CONTAINS, + /** + * Allow an empty array to match null and vice-versa + */ + NULL_MATCHES_EMPTY_ARRAY, + /** * Skip over fields that are missing in the other object - implies keys in any order */ diff --git a/src/main/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/tree/PathDsl.java b/src/main/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/tree/PathDsl.java index 85cf432..4487b8a 100644 --- a/src/main/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/tree/PathDsl.java +++ b/src/main/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/tree/PathDsl.java @@ -86,6 +86,15 @@ public WhereDsl arrayContains() { return whereDsl.pathRule(new PathRule(pathMatch, TreeRule.ARRAY_CONTAINS)); } + /** + * Allow empty array to match null and vice-versa + * + * @return this for fluent calling + */ + public WhereDsl nullMatchesEmptyArray() { + return whereDsl.pathRule(new PathRule(pathMatch, TreeRule.NULL_MATCHES_EMPTY_ARRAY)); + } + /** * Ignore everything at this path * @return the {@link WhereDsl} for fluent calling, with this path ignored diff --git a/src/main/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/tree/WhereDsl.java b/src/main/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/tree/WhereDsl.java index c4a7c36..07cb8c0 100644 --- a/src/main/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/tree/WhereDsl.java +++ b/src/main/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/tree/WhereDsl.java @@ -61,6 +61,15 @@ public WhereDsl arrayContains() { return pathRule(new PathRule(TreeRule.ARRAY_CONTAINS)); } + /** + * Allow empty array to match null and vice-versa + * + * @return this for fluent calling + */ + public WhereDsl nullMatchesEmptyArray() { + return pathRule(new PathRule(TreeRule.NULL_MATCHES_EMPTY_ARRAY)); + } + /** * Add common configuration to the where dsl * @param configurer the configurer to use diff --git a/src/test/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/ArrayNodeDslTest.java b/src/test/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/ArrayNodeDslTest.java index 8e69319..9a0a098 100644 --- a/src/test/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/ArrayNodeDslTest.java +++ b/src/test/java/uk/org/webcompere/modelassert/json/dsl/nodespecific/ArrayNodeDslTest.java @@ -114,4 +114,11 @@ void whenUsingArrayNodeWithArrayThenIsNotEmptyWorks() { assertJson("{foo:[\"bar\"]}") .at("/foo").array().isNotEmpty(); } + + @Test + void emptyArrayCanBeConfiguredToMatchNull() { + assertJson("{foo: null}") + .where().nullMatchesEmptyArray() + .isEqualTo("{foo: []}"); + } }