From 6f485c8df2d391058b57ff35209ea20d7037aeb5 Mon Sep 17 00:00:00 2001 From: Patrik Helsing Date: Sat, 28 May 2016 17:52:00 +0200 Subject: [PATCH 1/5] Empty json arrays and empty json objects are considered valid json. --- .../jsonpath/matchers/JsonPathMatchers.java | 4 ++- .../matchers/JsonPathMatchersTest.java | 29 +++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java index c89c42cc..562305a5 100644 --- a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java +++ b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java @@ -6,6 +6,8 @@ import com.jayway.jsonpath.ReadContext; import org.hamcrest.Matcher; import java.io.File; +import java.util.List; +import java.util.Map; import static org.hamcrest.Matchers.*; @@ -30,7 +32,7 @@ public class JsonPathMatchers { } public static Matcher isJson() { - return isJson(withJsonPath("$..*")); + return isJson(withJsonPath("$", anyOf(instanceOf(Map.class), instanceOf(List.class)))); } public static Matcher isJson(final Matcher matcher) { diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java index f52edafd..8b4d2b32 100644 --- a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java @@ -7,7 +7,6 @@ import org.junit.BeforeClass; import org.junit.Test; import java.io.File; -import java.nio.file.Paths; import java.util.Collection; import static com.jayway.jsonpath.matchers.JsonPathMatchers.*; @@ -34,6 +33,26 @@ public class JsonPathMatchersTest { Configuration.setDefaults(null); } + @Test + public void shouldMatchOnEmptyJsonObject() { + assertThat("{}", isJson()); + } + + @Test + public void shouldMatchOnJsonObject() { + assertThat("{ \"hi\" : \"there\" }", isJson()); + } + + @Test + public void shouldMatchOnEmptyJsonArray() { + assertThat("[]", isJson()); + } + + @Test + public void shouldMatchOnJsonArray() { + assertThat("[\"hi\", \"there\"]", isJson()); + } + @Test public void shouldMatchValidJson() { assertThat(VALID_JSON, isJson()); @@ -44,7 +63,11 @@ public class JsonPathMatchersTest { public void shouldNotMatchInvalidJson() { assertThat(INVALID_JSON, not(isJson())); assertThat(new Object(), not(isJson())); - assertThat("{}", not(isJson())); + assertThat(new Object[]{}, not(isJson())); + assertThat("hi there", not(isJson())); + assertThat(new Integer(42), not(isJson())); + assertThat(Boolean.TRUE, not(isJson())); + assertThat(false, not(isJson())); assertThat(null, not(isJson())); } @@ -122,7 +145,7 @@ public class JsonPathMatchersTest { @Test public void shouldNotMatchJsonPathOnNonExistingFile() { - File nonExistingFile = Paths.get("missing-file").toFile(); + File nonExistingFile = new File("missing-file"); assertThat(nonExistingFile, not(hasJsonPath("$..*", anything()))); } From 6823a7de1d584fe34d87b39e416c8ddfad90b4a2 Mon Sep 17 00:00:00 2001 From: Patrik Helsing Date: Sat, 28 May 2016 20:20:37 +0200 Subject: [PATCH 2/5] hasJsonPath("path.to.empty.array") will match, e.g return true --- json-path-assert/README.md | 21 +++++++++ .../jsonpath/matchers/JsonPathMatchers.java | 4 +- .../matchers/JsonPathMatchersTest.java | 47 +++++++++++++++---- .../jsonpath/matchers/WithJsonPathTest.java | 7 +-- .../src/test/resources/books.json | 3 ++ 5 files changed, 69 insertions(+), 13 deletions(-) diff --git a/json-path-assert/README.md b/json-path-assert/README.md index a6e94a2d..e2c604c1 100644 --- a/json-path-assert/README.md +++ b/json-path-assert/README.md @@ -80,3 +80,24 @@ Use typed matchers for specific JSON representations, if needed File json = ... assertThat(json, isJsonFile(withJsonPath("$..author"))); + +--- + +CAUTION: regarding the use of indefinite paths + +When using indefinite path expressions (e.g with wildcards '*'), the result will yield a list. Possibly an _empty_ list if no matching entries were found. If you want to assert that the list will actually contain something, make sure to express this explicitly, e.g checking for the size of the list. + + // Given a JSON like this: + { + "items": [] + } + + // Both of these statements will succeed(!) + assertThat(json, hasJsonPath("$.items[*]")); + assertThat(json, hasJsonPath("$.items[*].name")); + + // Make sure to explicitly check for size if you want to catch this scenario as a failure + assertThat(json, hasJsonPath("$.items[*]", hasSize(greaterThan(0)))); + + // However, checking for the existence of an array works fine, as is + assertThat(json, hasJsonPath("$.not_here[*]")); diff --git a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java index 562305a5..196a191a 100644 --- a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java +++ b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java @@ -19,7 +19,7 @@ public class JsonPathMatchers { public static Matcher hasJsonPath(String jsonPath) { return describedAs("has json path %0", - hasJsonPath(jsonPath, not(anyOf(nullValue(), empty()))), + hasJsonPath(jsonPath, not(nullValue())), jsonPath); } @@ -53,7 +53,7 @@ public class JsonPathMatchers { public static Matcher withJsonPath(JsonPath jsonPath) { return describedAs("with json path %0", - withJsonPath(jsonPath, not(anyOf(nullValue(), empty()))), + withJsonPath(jsonPath, not(nullValue())), jsonPath.getPath()); } diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java index 8b4d2b32..3be702c6 100644 --- a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java @@ -73,16 +73,45 @@ public class JsonPathMatchersTest { @Test public void shouldMatchExistingJsonPath() { - assertThat(BOOKS_JSON, hasJsonPath("$.store.name")); - assertThat(BOOKS_JSON, hasJsonPath("$.store.book[2].title")); - assertThat(BOOKS_JSON, hasJsonPath("$.store.book[*].author")); + assertThat(BOOKS_JSON, hasJsonPath("$.store.name")); // string + assertThat(BOOKS_JSON, hasJsonPath("$.store.switch")); // boolean + assertThat(BOOKS_JSON, hasJsonPath("$.expensive")); // number + assertThat(BOOKS_JSON, hasJsonPath("$.store.bicycle")); // object + assertThat(BOOKS_JSON, hasJsonPath("$.store.truck")); // empty object + assertThat(BOOKS_JSON, hasJsonPath("$.store.book")); // non-empty array + assertThat(BOOKS_JSON, hasJsonPath("$.store.book[*]")); // non-empty array + assertThat(BOOKS_JSON, hasJsonPath("$.store.magazine")); // empty array + assertThat(BOOKS_JSON, hasJsonPath("$.store.magazine[*]")); // empty array } @Test public void shouldMatchExistingJsonPathAlternative() { - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.name"))); - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.book[2].title"))); - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.book[*].author"))); + assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.name"))); // string + assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.switch"))); // boolean + assertThat(BOOKS_JSON, isJson(withJsonPath("$.expensive"))); // number + assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.bicycle"))); // object + assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.truck"))); // empty object + assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.book"))); // non-empty array + assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.book[*]"))); // non-empty array + assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.magazine"))); // empty array + assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.magazine[*]"))); // empty array + } + + @Test + public void shouldNotMatchNonExistentArrays() { + assertThat(BOOKS_JSON, not(hasJsonPath("$.store.not_here[*]"))); + } + + @Test + public void willMatchIndefiniteJsonPathsEvaluatedToEmptyLists() { + // This is just a test to demonstrate that wildcard paths + // will always match, regardless of result. This is because + // the evaluation of these expressions will at least return + // an empty list. + String json = "{\"items\": []}"; + assertThat(json, hasJsonPath("$.items[*]")); + assertThat(json, hasJsonPath("$.items[*].name")); + assertThat(json, hasJsonPath("$.items[*]", hasSize(0))); } @Test @@ -103,15 +132,17 @@ public class JsonPathMatchersTest { @Test public void shouldNotMatchNonExistingJsonPath() { assertThat(BOOKS_JSON, not(hasJsonPath("$.not_there"))); + assertThat(BOOKS_JSON, not(hasJsonPath("$.store.not_there"))); + assertThat(BOOKS_JSON, not(hasJsonPath("$.store.book[1].isbn"))); assertThat(BOOKS_JSON, not(hasJsonPath("$.store.book[5].title"))); - assertThat(BOOKS_JSON, not(hasJsonPath("$.store.book[*].not_there"))); } @Test public void shouldNotMatchNonExistingJsonPathAlternative() { assertThat(BOOKS_JSON, not(isJson(withJsonPath("$.not_there")))); + assertThat(BOOKS_JSON, not(isJson(withJsonPath(("$.store.not_there"))))); + assertThat(BOOKS_JSON, not(isJson(withJsonPath(("$.store.book[1].isbn"))))); assertThat(BOOKS_JSON, not(isJson(withJsonPath("$.store.book[5].title")))); - assertThat(BOOKS_JSON, not(isJson(withJsonPath("$.store.book[*].not_there")))); } @Test diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithJsonPathTest.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithJsonPathTest.java index 6b26cd0c..15f2b94d 100644 --- a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithJsonPathTest.java +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithJsonPathTest.java @@ -9,6 +9,7 @@ import org.hamcrest.StringDescription; import org.junit.Test; import java.util.Collection; +import java.util.List; import static com.jayway.jsonpath.JsonPath.compile; import static com.jayway.jsonpath.matchers.JsonPathMatchers.withJsonPath; @@ -40,14 +41,14 @@ public class WithJsonPathTest { public void shouldNotMatchNonExistingJsonPath() { assertThat(BOOKS_JSON, not(withJsonPath(compile("$.not_there")))); assertThat(BOOKS_JSON, not(withJsonPath(compile("$.store.book[5].title")))); - assertThat(BOOKS_JSON, not(withJsonPath(compile("$.store.book[*].not_there")))); + assertThat(BOOKS_JSON, not(withJsonPath(compile("$.store.book[1].not_there")))); } @Test public void shouldNotMatchNonExistingStringJsonPath() { assertThat(BOOKS_JSON, not(withJsonPath("$.not_there"))); assertThat(BOOKS_JSON, not(withJsonPath("$.store.book[5].title"))); - assertThat(BOOKS_JSON, not(withJsonPath("$.store.book[*].not_there"))); + assertThat(BOOKS_JSON, not(withJsonPath("$.store.book[1].not_there"))); } @Test @@ -92,7 +93,7 @@ public class WithJsonPathTest { @Test public void shouldMatchJsonPathEvaluatedToCollectionValue() { - assertThat(BOOKS_JSON, withJsonPath(compile("$.store.book[*].author"), instanceOf(Collection.class))); + assertThat(BOOKS_JSON, withJsonPath(compile("$.store.book[*].author"), instanceOf(List.class))); assertThat(BOOKS_JSON, withJsonPath(compile("$.store.book[*].author"), hasSize(4))); assertThat(BOOKS_JSON, withJsonPath(compile("$.store.book[*].author"), hasItem("Evelyn Waugh"))); assertThat(BOOKS_JSON, withJsonPath(compile("$..book[2].title"), hasItem("Moby Dick"))); diff --git a/json-path-assert/src/test/resources/books.json b/json-path-assert/src/test/resources/books.json index f009f4ba..78004291 100644 --- a/json-path-assert/src/test/resources/books.json +++ b/json-path-assert/src/test/resources/books.json @@ -1,6 +1,9 @@ { "store": { "name": "Little Shop", + "switch": true, + "magazine": [], + "truck": {}, "book": [ { "category": "reference", From 59a1c82b18f8471e7da1a1cfe99d7cd4bc1ef9cf Mon Sep 17 00:00:00 2001 From: Patrik Helsing Date: Sat, 28 May 2016 23:05:05 +0200 Subject: [PATCH 3/5] Make it possible to correctly assert on path to null value. --- json-path-assert/README.md | 24 +- .../jsonpath/matchers/JsonPathMatchers.java | 4 +- .../jsonpath/matchers/WithoutJsonPath.java | 4 +- .../jsonpath/matchers/HasNoJsonPathTest.java | 30 +++ .../jayway/jsonpath/matchers/IsJsonTest.java | 53 ++++- .../matchers/JsonPathMatchersTest.java | 216 ++++++++++-------- .../jsonpath/matchers/WithJsonPathTest.java | 21 -- .../matchers/WithoutJsonPathTest.java | 44 ++++ .../src/test/resources/books.json | 1 + 9 files changed, 265 insertions(+), 132 deletions(-) create mode 100644 json-path-assert/src/test/java/com/jayway/jsonpath/matchers/HasNoJsonPathTest.java create mode 100644 json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithoutJsonPathTest.java diff --git a/json-path-assert/README.md b/json-path-assert/README.md index e2c604c1..a56b9a51 100644 --- a/json-path-assert/README.md +++ b/json-path-assert/README.md @@ -83,7 +83,7 @@ Use typed matchers for specific JSON representations, if needed --- -CAUTION: regarding the use of indefinite paths +### Regarding the use of indefinite paths When using indefinite path expressions (e.g with wildcards '*'), the result will yield a list. Possibly an _empty_ list if no matching entries were found. If you want to assert that the list will actually contain something, make sure to express this explicitly, e.g checking for the size of the list. @@ -101,3 +101,25 @@ When using indefinite path expressions (e.g with wildcards '*'), the result will // However, checking for the existence of an array works fine, as is assertThat(json, hasJsonPath("$.not_here[*]")); + +--- + +### Regarding the use of null in JSON + +'null' is a valid JSON value. If such a value exist, the path is still considered to be a valid path. + + // Given a JSON like this: + { "none": null } + + // All of these will succeed, since '$.none' is a valid path + assertThat(json, hasJsonPath("$.none")); + assertThat(json, isJson(withJsonPath("$.none"))); + assertThat(json, hasJsonPath("$.none", nullValue())); + assertThat(json, isJson(withJsonPath("$.none", nullValue()))); + + // But all of these will fail, since '$.not_there' is not a valid path + assertThat(json, hasJsonPath("$.not_there")); + assertThat(json, isJson(withJsonPath("$.not_there"))); + assertThat(json, hasJsonPath("$.not_there", anything())); + assertThat(json, isJson(withJsonPath("$.not_there", anything()))); + diff --git a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java index 196a191a..7689a22b 100644 --- a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java +++ b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java @@ -19,7 +19,7 @@ public class JsonPathMatchers { public static Matcher hasJsonPath(String jsonPath) { return describedAs("has json path %0", - hasJsonPath(jsonPath, not(nullValue())), + isJson(withJsonPath(jsonPath)), jsonPath); } @@ -53,7 +53,7 @@ public class JsonPathMatchers { public static Matcher withJsonPath(JsonPath jsonPath) { return describedAs("with json path %0", - withJsonPath(jsonPath, not(nullValue())), + withJsonPath(jsonPath, anything()), jsonPath.getPath()); } diff --git a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/WithoutJsonPath.java b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/WithoutJsonPath.java index b339d5df..d14a12b0 100644 --- a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/WithoutJsonPath.java +++ b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/WithoutJsonPath.java @@ -6,8 +6,6 @@ import com.jayway.jsonpath.ReadContext; import org.hamcrest.Description; import org.hamcrest.TypeSafeDiagnosingMatcher; -import static org.hamcrest.Matchers.empty; - public class WithoutJsonPath extends TypeSafeDiagnosingMatcher { private final JsonPath jsonPath; @@ -23,7 +21,7 @@ public class WithoutJsonPath extends TypeSafeDiagnosingMatcher { .appendText(jsonPath.getPath()) .appendText(" was evaluated to ") .appendValue(value); - return value == null || empty().matches(value); + return false; } catch (JsonPathException e) { return true; } diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/HasNoJsonPathTest.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/HasNoJsonPathTest.java new file mode 100644 index 00000000..edd4ca9e --- /dev/null +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/HasNoJsonPathTest.java @@ -0,0 +1,30 @@ +package com.jayway.jsonpath.matchers; + +import org.junit.Test; + +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertThat; + +public class HasNoJsonPathTest { + private static final String JSON_STRING = "{" + + "\"name\": \"Jessie\"" + + "}"; + + @Test + public void shouldMatchMissingJsonPath() { + assertThat(JSON_STRING, hasNoJsonPath("$.not_there")); + } + + @Test + public void shouldNotMatchExistingJsonPath() { + assertThat(JSON_STRING, not(hasNoJsonPath("$.name"))); + } + + @Test + public void shouldBeDescriptive() { + assertThat(hasNoJsonPath("$.name"), + hasToString(equalTo("is json without json path \"$['name']\""))); + } + +} diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/IsJsonTest.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/IsJsonTest.java index 0d08aa02..dc4325ff 100644 --- a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/IsJsonTest.java +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/IsJsonTest.java @@ -20,8 +20,11 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; public class IsJsonTest { + private static final String VALID_JSON = resource("example.json"); + private static final String INVALID_JSON = "{ invalid-json }"; private static final String BOOKS_JSON_STRING = resource("books.json"); private static final File BOOKS_JSON_FILE = resourceAsFile("books.json"); + private static final Object BOOKS_JSON_PARSED = parseJson(BOOKS_JSON_STRING); @BeforeClass public static void setupStrictJsonParsing() { @@ -33,16 +36,52 @@ public class IsJsonTest { Configuration.setDefaults(null); } + @Test + public void shouldMatchOnEmptyJsonObject() { + assertThat("{}", isJson()); + } + + @Test + public void shouldMatchOnJsonObject() { + assertThat("{ \"hi\" : \"there\" }", isJson()); + } + + @Test + public void shouldMatchOnEmptyJsonArray() { + assertThat("[]", isJson()); + } + + @Test + public void shouldMatchOnJsonArray() { + assertThat("[\"hi\", \"there\"]", isJson()); + } + + @Test + public void shouldMatchValidJson() { + assertThat(VALID_JSON, isJson()); + assertThat(BOOKS_JSON_STRING, isJson()); + } + + @Test + public void shouldNotMatchInvalidJson() { + assertThat(INVALID_JSON, not(isJson())); + assertThat(new Object(), not(isJson())); + assertThat(new Object[]{}, not(isJson())); + assertThat("hi there", not(isJson())); + assertThat(new Integer(42), not(isJson())); + assertThat(Boolean.TRUE, not(isJson())); + assertThat(false, not(isJson())); + assertThat(null, not(isJson())); + } + @Test public void shouldMatchJsonObjectEvaluatedToTrue() { - Object parsedJson = parseJson(BOOKS_JSON_STRING); - assertThat(parsedJson, isJson(withPathEvaluatedTo(true))); + assertThat(BOOKS_JSON_PARSED, isJson(withPathEvaluatedTo(true))); } @Test public void shouldNotMatchJsonObjectEvaluatedToFalse() { - Object parsedJson = parseJson(BOOKS_JSON_STRING); - assertThat(parsedJson, not(isJson(withPathEvaluatedTo(false)))); + assertThat(BOOKS_JSON_PARSED, not(isJson(withPathEvaluatedTo(false)))); } @Test @@ -65,6 +104,12 @@ public class IsJsonTest { assertThat(BOOKS_JSON_FILE, not(isJson(withPathEvaluatedTo(false)))); } + @Test + public void shouldNotMatchNonExistingJsonFile() { + File nonExistingFile = new File("missing-file"); + assertThat(nonExistingFile, not(isJson())); + } + @Test public void shouldBeDescriptive() { Matcher matcher = isJson(withPathEvaluatedTo(true)); diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java index 3be702c6..bb287fc3 100644 --- a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/JsonPathMatchersTest.java @@ -7,7 +7,8 @@ import org.junit.BeforeClass; import org.junit.Test; import java.io.File; -import java.util.Collection; +import java.util.List; +import java.util.Map; import static com.jayway.jsonpath.matchers.JsonPathMatchers.*; import static com.jayway.jsonpath.matchers.helpers.ResourceHelpers.resource; @@ -16,8 +17,6 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; public class JsonPathMatchersTest { - - private static final String VALID_JSON = resource("example.json"); private static final String BOOKS_JSON = resource("books.json"); private static final String INVALID_JSON = "{ invalid-json }"; private static final File BOOKS_JSON_FILE = resourceAsFile("books.json"); @@ -34,139 +33,164 @@ public class JsonPathMatchersTest { } @Test - public void shouldMatchOnEmptyJsonObject() { - assertThat("{}", isJson()); - } + public void shouldMatchJsonPathToStringValue() { + final String json = "{\"name\": \"Jessie\"}"; - @Test - public void shouldMatchOnJsonObject() { - assertThat("{ \"hi\" : \"there\" }", isJson()); + assertThat(json, hasJsonPath("$.name")); + assertThat(json, isJson(withJsonPath("$.name"))); + assertThat(json, hasJsonPath("$.name", equalTo("Jessie"))); + assertThat(json, isJson(withJsonPath("$.name", equalTo("Jessie")))); + + assertThat(json, not(hasJsonPath("$.name", equalTo("John")))); + assertThat(json, not(isJson(withJsonPath("$.name", equalTo("John"))))); } @Test - public void shouldMatchOnEmptyJsonArray() { - assertThat("[]", isJson()); + public void shouldMatchJsonPathToIntegerValue() { + final String json = "{\"number\": 10}"; + + assertThat(json, hasJsonPath("$.number")); + assertThat(json, isJson(withJsonPath("$.number"))); + assertThat(json, hasJsonPath("$.number", equalTo(10))); + assertThat(json, isJson(withJsonPath("$.number", equalTo(10)))); + + assertThat(json, not(hasJsonPath("$.number", equalTo(3)))); + assertThat(json, not(isJson(withJsonPath("$.number", equalTo(3))))); } @Test - public void shouldMatchOnJsonArray() { - assertThat("[\"hi\", \"there\"]", isJson()); + public void shouldMatchJsonPathToDoubleValue() { + final String json = "{\"price\": 19.95}"; + + assertThat(json, hasJsonPath("$.price")); + assertThat(json, isJson(withJsonPath("$.price"))); + assertThat(json, hasJsonPath("$.price", equalTo(19.95))); + assertThat(json, isJson(withJsonPath("$.price", equalTo(19.95)))); + + assertThat(json, not(hasJsonPath("$.price", equalTo(3.3)))); + assertThat(json, not(isJson(withJsonPath("$.price", equalTo(42))))); } @Test - public void shouldMatchValidJson() { - assertThat(VALID_JSON, isJson()); - assertThat(BOOKS_JSON, isJson()); + public void shouldMatchJsonPathToBooleanValue() { + final String json = "{\"flag\": false}"; + + assertThat(json, hasJsonPath("$.flag")); + assertThat(json, isJson(withJsonPath("$.flag"))); + assertThat(json, hasJsonPath("$.flag", equalTo(false))); + assertThat(json, isJson(withJsonPath("$.flag", equalTo(false)))); + + assertThat(json, not(hasJsonPath("$.flag", equalTo(true)))); + assertThat(json, not(isJson(withJsonPath("$.flag", equalTo(true))))); } @Test - public void shouldNotMatchInvalidJson() { - assertThat(INVALID_JSON, not(isJson())); - assertThat(new Object(), not(isJson())); - assertThat(new Object[]{}, not(isJson())); - assertThat("hi there", not(isJson())); - assertThat(new Integer(42), not(isJson())); - assertThat(Boolean.TRUE, not(isJson())); - assertThat(false, not(isJson())); - assertThat(null, not(isJson())); + public void shouldMatchJsonPathToJsonObject() { + final String json = "{\"object\": { \"name\":\"Oscar\"}}"; + + assertThat(json, hasJsonPath("$.object")); + assertThat(json, isJson(withJsonPath("$.object"))); + assertThat(json, hasJsonPath("$.object", instanceOf(Map.class))); + assertThat(json, isJson(withJsonPath("$.object", instanceOf(Map.class)))); + + assertThat(json, not(hasJsonPath("$.object", instanceOf(List.class)))); + assertThat(json, not(isJson(withJsonPath("$.object", instanceOf(List.class))))); } @Test - public void shouldMatchExistingJsonPath() { - assertThat(BOOKS_JSON, hasJsonPath("$.store.name")); // string - assertThat(BOOKS_JSON, hasJsonPath("$.store.switch")); // boolean - assertThat(BOOKS_JSON, hasJsonPath("$.expensive")); // number - assertThat(BOOKS_JSON, hasJsonPath("$.store.bicycle")); // object - assertThat(BOOKS_JSON, hasJsonPath("$.store.truck")); // empty object - assertThat(BOOKS_JSON, hasJsonPath("$.store.book")); // non-empty array - assertThat(BOOKS_JSON, hasJsonPath("$.store.book[*]")); // non-empty array - assertThat(BOOKS_JSON, hasJsonPath("$.store.magazine")); // empty array - assertThat(BOOKS_JSON, hasJsonPath("$.store.magazine[*]")); // empty array + public void shouldMatchJsonPathToEmptyJsonObject() { + final String json = "{\"empty_object\": {}}"; + + assertThat(json, hasJsonPath("$.empty_object")); + assertThat(json, isJson(withJsonPath("$.empty_object"))); + assertThat(json, hasJsonPath("$.empty_object", instanceOf(Map.class))); + assertThat(json, isJson(withJsonPath("$.empty_object", instanceOf(Map.class)))); + + assertThat(json, not(hasJsonPath("$.empty_object", instanceOf(List.class)))); + assertThat(json, not(isJson(withJsonPath("$.empty_object", instanceOf(List.class))))); } @Test - public void shouldMatchExistingJsonPathAlternative() { - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.name"))); // string - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.switch"))); // boolean - assertThat(BOOKS_JSON, isJson(withJsonPath("$.expensive"))); // number - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.bicycle"))); // object - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.truck"))); // empty object - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.book"))); // non-empty array - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.book[*]"))); // non-empty array - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.magazine"))); // empty array - assertThat(BOOKS_JSON, isJson(withJsonPath("$.store.magazine[*]"))); // empty array + public void shouldMatchJsonPathToJsonArray() { + final String json = "{\"list\": [ \"one\",\"two\",\"three\"]}"; + + assertThat(json, hasJsonPath("$.list")); + assertThat(json, hasJsonPath("$.list[*]")); + assertThat(json, isJson(withJsonPath("$.list"))); + assertThat(json, isJson(withJsonPath("$.list[*]"))); + assertThat(json, hasJsonPath("$.list", contains("one", "two", "three"))); + assertThat(json, isJson(withJsonPath("$.list", hasItem("two")))); + + assertThat(json, not(hasJsonPath("$.list", hasSize(2)))); + assertThat(json, not(isJson(withJsonPath("$.list", contains("four"))))); } @Test - public void shouldNotMatchNonExistentArrays() { - assertThat(BOOKS_JSON, not(hasJsonPath("$.store.not_here[*]"))); + public void shouldMatchJsonPathToEmptyJsonArray() { + final String json = "{\"empty_list\": []}"; + + assertThat(json, hasJsonPath("$.empty_list")); + assertThat(json, hasJsonPath("$.empty_list[*]")); + assertThat(json, isJson(withJsonPath("$.empty_list"))); + assertThat(json, isJson(withJsonPath("$.empty_list[*]"))); + assertThat(json, hasJsonPath("$.empty_list", empty())); + assertThat(json, isJson(withJsonPath("$.empty_list", hasSize(0)))); + + assertThat(json, not(hasJsonPath("$.empty_list", hasSize(2)))); + assertThat(json, not(isJson(withJsonPath("$.empty_list", contains("four"))))); } @Test public void willMatchIndefiniteJsonPathsEvaluatedToEmptyLists() { - // This is just a test to demonstrate that wildcard paths + // This is just a test to demonstrate that indefinite paths // will always match, regardless of result. This is because - // the evaluation of these expressions will at least return - // an empty list. + // the evaluation of these expressions will return lists, + // even though they may be empty. String json = "{\"items\": []}"; - assertThat(json, hasJsonPath("$.items[*]")); assertThat(json, hasJsonPath("$.items[*].name")); + assertThat(json, hasJsonPath("$.items[*]")); assertThat(json, hasJsonPath("$.items[*]", hasSize(0))); } @Test - public void shouldNotMatchInvalidJsonWithPath() { - assertThat(INVALID_JSON, not(hasJsonPath("$.path"))); - assertThat(new Object(), not(hasJsonPath("$.path"))); - assertThat("{}", not(hasJsonPath("$.path"))); - assertThat(null, not(hasJsonPath("$.path"))); - } + public void shouldMatchJsonPathToNullValue() { + final String json = "{\"none\": null}"; - @Test - public void shouldNotMatchInvalidJsonWithPathAndValue() { - assertThat(INVALID_JSON, not(hasJsonPath("$.path", anything()))); - assertThat(new Object(), not(hasJsonPath("$.path", anything()))); - assertThat(null, not(hasJsonPath("$.message", anything()))); - } + assertThat(json, hasJsonPath("$.none")); + assertThat(json, isJson(withJsonPath("$.none"))); + assertThat(json, hasJsonPath("$.none", nullValue())); + assertThat(json, isJson(withJsonPath("$.none", nullValue()))); - @Test - public void shouldNotMatchNonExistingJsonPath() { - assertThat(BOOKS_JSON, not(hasJsonPath("$.not_there"))); - assertThat(BOOKS_JSON, not(hasJsonPath("$.store.not_there"))); - assertThat(BOOKS_JSON, not(hasJsonPath("$.store.book[1].isbn"))); - assertThat(BOOKS_JSON, not(hasJsonPath("$.store.book[5].title"))); + assertThat(json, not(hasJsonPath("$.none", equalTo("something")))); + assertThat(json, not(isJson(withJsonPath("$.none", empty())))); } @Test - public void shouldNotMatchNonExistingJsonPathAlternative() { - assertThat(BOOKS_JSON, not(isJson(withJsonPath("$.not_there")))); - assertThat(BOOKS_JSON, not(isJson(withJsonPath(("$.store.not_there"))))); - assertThat(BOOKS_JSON, not(isJson(withJsonPath(("$.store.book[1].isbn"))))); - assertThat(BOOKS_JSON, not(isJson(withJsonPath("$.store.book[5].title")))); - } - - @Test - public void shouldMatchJsonPathWithStringValue() { - assertThat(BOOKS_JSON, hasJsonPath("$.store.name", equalTo("Little Shop"))); - assertThat(BOOKS_JSON, hasJsonPath("$.store.book[2].title", equalTo("Moby Dick"))); - } + public void shouldNotMatchNonExistingJsonPath() { + final String json = "{}"; - @Test - public void shouldMatchJsonPathWithIntegerValue() { - assertThat(BOOKS_JSON, hasJsonPath("$.expensive", equalTo(10))); + assertThat(json, not(hasJsonPath("$.not_there"))); + assertThat(json, not(hasJsonPath("$.not_there", anything()))); + assertThat(json, not(hasJsonPath("$.not_there[*]"))); + assertThat(json, not(hasJsonPath("$.not_there[*]", anything()))); + assertThat(json, not(isJson(withJsonPath("$.not_there")))); + assertThat(json, not(isJson(withJsonPath("$.not_there", anything())))); + assertThat(json, not(isJson(withJsonPath("$.not_there[*]")))); + assertThat(json, not(isJson(withJsonPath("$.not_there[*]", anything())))); } @Test - public void shouldMatchJsonPathWithDoubleValue() { - assertThat(BOOKS_JSON, hasJsonPath("$.store.bicycle.price", equalTo(19.95))); + public void shouldNotMatchInvalidJsonWithPath() { + assertThat(INVALID_JSON, not(hasJsonPath("$.path"))); + assertThat(new Object(), not(hasJsonPath("$.path"))); + assertThat(null, not(hasJsonPath("$.path"))); } @Test - public void shouldMatchJsonPathWithCollectionValue() { - assertThat(BOOKS_JSON, hasJsonPath("$.store.book[*].author", instanceOf(Collection.class))); - assertThat(BOOKS_JSON, hasJsonPath("$.store.book[*].author", hasSize(4))); - assertThat(BOOKS_JSON, hasJsonPath("$.store.book[*].author", hasItem("Evelyn Waugh"))); - assertThat(BOOKS_JSON, hasJsonPath("$..book[2].title", hasItem("Moby Dick"))); + public void shouldNotMatchInvalidJsonWithPathAndValue() { + assertThat(INVALID_JSON, not(hasJsonPath("$.path", anything()))); + assertThat(new Object(), not(hasJsonPath("$.path", anything()))); + assertThat(null, not(hasJsonPath("$.message", anything()))); } @Test @@ -185,14 +209,4 @@ public class JsonPathMatchersTest { Object json = Configuration.defaultConfiguration().jsonProvider().parse(BOOKS_JSON); assertThat(json, hasJsonPath("$.store.name", equalTo("Little Shop"))); } - - @Test - public void shouldMatchMissingJsonPath() { - assertThat(BOOKS_JSON, hasNoJsonPath("$.not_there")); - } - - @Test - public void shouldNotMatchExistingJsonPath() { - assertThat(BOOKS_JSON, not(hasNoJsonPath("$.store.name"))); - } } diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithJsonPathTest.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithJsonPathTest.java index 15f2b94d..31b09608 100644 --- a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithJsonPathTest.java +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithJsonPathTest.java @@ -13,7 +13,6 @@ import java.util.List; import static com.jayway.jsonpath.JsonPath.compile; import static com.jayway.jsonpath.matchers.JsonPathMatchers.withJsonPath; -import static com.jayway.jsonpath.matchers.JsonPathMatchers.withoutJsonPath; import static com.jayway.jsonpath.matchers.helpers.ResourceHelpers.resource; import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; @@ -51,26 +50,6 @@ public class WithJsonPathTest { assertThat(BOOKS_JSON, not(withJsonPath("$.store.book[1].not_there"))); } - @Test - public void shouldMatchNonExistingJsonPath() { - assertThat(BOOKS_JSON, withoutJsonPath(compile("$.not_there"))); - } - - @Test - public void shouldMatchNonExistingStringJsonPath() { - assertThat(BOOKS_JSON, withoutJsonPath("$.not_there")); - } - - @Test - public void shouldNotMatchExistingCompiledJsonPath() { - assertThat(BOOKS_JSON, not(withoutJsonPath(compile("$.store.name")))); - } - - @Test - public void shouldNotMatchExistingStringJsonPath() { - assertThat(BOOKS_JSON, not(withoutJsonPath("$.store.name"))); - } - @Test public void shouldMatchJsonPathEvaluatedToStringValue() { assertThat(BOOKS_JSON, withJsonPath(compile("$.store.bicycle.color"), equalTo("red"))); diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithoutJsonPathTest.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithoutJsonPathTest.java new file mode 100644 index 00000000..a2fe7f31 --- /dev/null +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/WithoutJsonPathTest.java @@ -0,0 +1,44 @@ +package com.jayway.jsonpath.matchers; + +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.ReadContext; +import org.junit.Test; + +import static com.jayway.jsonpath.JsonPath.compile; +import static com.jayway.jsonpath.matchers.JsonPathMatchers.withoutJsonPath; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertThat; + +public class WithoutJsonPathTest { + private static final String JSON_STRING = "{" + + "\"name\": \"Jessie\"," + + "\"flag\": false," + + "\"empty_array\": []," + + "\"empty_object\": {}," + + "\"none\": null" + + "}"; + private static final ReadContext JSON = JsonPath.parse(JSON_STRING); + + @Test + public void shouldMatchNonExistingJsonPath() { + assertThat(JSON, withoutJsonPath(compile("$.not_there"))); + assertThat(JSON, withoutJsonPath("$.not_there")); + } + + @Test + public void shouldNotMatchExistingJsonPath() { + assertThat(JSON, not(withoutJsonPath(compile("$.name")))); + assertThat(JSON, not(withoutJsonPath("$.name"))); + assertThat(JSON, not(withoutJsonPath("$.flag"))); + assertThat(JSON, not(withoutJsonPath("$.empty_array"))); + assertThat(JSON, not(withoutJsonPath("$.empty_object"))); + assertThat(JSON, not(withoutJsonPath("$.none"))); + } + + @Test + public void shouldBeDescriptive() { + assertThat(withoutJsonPath("$.name"), + hasToString(equalTo("without json path \"$['name']\""))); + } + +} diff --git a/json-path-assert/src/test/resources/books.json b/json-path-assert/src/test/resources/books.json index 78004291..5d049d21 100644 --- a/json-path-assert/src/test/resources/books.json +++ b/json-path-assert/src/test/resources/books.json @@ -1,6 +1,7 @@ { "store": { "name": "Little Shop", + "none": null, "switch": true, "magazine": [], "truck": {}, From 3406213da16e2fd805a6f1f2db9fabd650d23879 Mon Sep 17 00:00:00 2001 From: Patrik Helsing Date: Sun, 29 May 2016 09:58:45 +0200 Subject: [PATCH 4/5] Removing redundant boiler plate --- .../com/jayway/jsonpath/matchers/JsonPathMatchers.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java index 7689a22b..6f4c66da 100644 --- a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java +++ b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java @@ -23,7 +23,7 @@ public class JsonPathMatchers { jsonPath); } - public static Matcher hasJsonPath(final String jsonPath, final Matcher resultMatcher) { + public static Matcher hasJsonPath(String jsonPath, Matcher resultMatcher) { return isJson(withJsonPath(jsonPath, resultMatcher)); } @@ -35,15 +35,15 @@ public class JsonPathMatchers { return isJson(withJsonPath("$", anyOf(instanceOf(Map.class), instanceOf(List.class)))); } - public static Matcher isJson(final Matcher matcher) { + public static Matcher isJson(Matcher matcher) { return new IsJson(matcher); } - public static Matcher isJsonString(final Matcher matcher) { + public static Matcher isJsonString(Matcher matcher) { return new IsJson(matcher); } - public static Matcher isJsonFile(final Matcher matcher) { + public static Matcher isJsonFile(Matcher matcher) { return new IsJson(matcher); } @@ -69,7 +69,7 @@ public class JsonPathMatchers { return withJsonPath(JsonPath.compile(jsonPath), resultMatcher); } - public static Matcher withJsonPath(final JsonPath jsonPath, final Matcher resultMatcher) { + public static Matcher withJsonPath(JsonPath jsonPath, Matcher resultMatcher) { return new WithJsonPath(jsonPath, resultMatcher); } } From ba7189c688335937d6f59e63ba284f213ef036d9 Mon Sep 17 00:00:00 2001 From: Patrik Helsing Date: Sun, 29 May 2016 11:48:32 +0200 Subject: [PATCH 5/5] Get rid of Java 7 dependencies --- .../jsonpath/matchers/helpers/ResourceHelpers.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/helpers/ResourceHelpers.java b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/helpers/ResourceHelpers.java index c2c8724a..6c263850 100644 --- a/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/helpers/ResourceHelpers.java +++ b/json-path-assert/src/test/java/com/jayway/jsonpath/matchers/helpers/ResourceHelpers.java @@ -4,11 +4,8 @@ import org.apache.commons.io.IOUtils; import java.io.File; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; import static java.lang.ClassLoader.getSystemResource; import static java.lang.ClassLoader.getSystemResourceAsStream; @@ -18,18 +15,16 @@ public class ResourceHelpers { try { return IOUtils.toString(getSystemResourceAsStream(resource)); } catch (IOException e) { - throw new AssertionError("Resource not found", e); + throw new AssertionError("Resource not found: " + e.getMessage()); } } public static File resourceAsFile(String resource) { try { URL systemResource = getSystemResource(resource); - URI uri = systemResource.toURI(); - Path path = Paths.get(uri); - return path.toFile(); + return new File(systemResource.toURI()); } catch (URISyntaxException e) { - throw new AssertionError("URI syntax error", e); + throw new AssertionError("URI syntax error:" + e.getMessage()); } } }