diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/Jackson3JsonNodeJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/Jackson3JsonNodeJsonProvider.java index 779a23e6..0b84c7fe 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/Jackson3JsonNodeJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/Jackson3JsonNodeJsonProvider.java @@ -133,7 +133,11 @@ public boolean isArray(Object obj) { @Override public Object getArrayIndex(Object obj, int idx) { - return toJsonArray(obj).get(idx); + JsonNode value = toJsonArray(obj).get(idx); + if (value == null) { + throw new IndexOutOfBoundsException("Index: " + idx); + } + return value; } @Override diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java index ae165927..394a4295 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java @@ -135,7 +135,11 @@ public boolean isArray(Object obj) { @Override public Object getArrayIndex(Object obj, int idx) { - return toJsonArray(obj).get(idx); + JsonNode value = toJsonArray(obj).get(idx); + if (value == null) { + throw new IndexOutOfBoundsException("Index: " + idx); + } + return value; } @Override diff --git a/json-path/src/test/java/com/jayway/jsonpath/Jackson3JsonNodeJsonProviderTest.java b/json-path/src/test/java/com/jayway/jsonpath/Jackson3JsonNodeJsonProviderTest.java index 06b595a5..a3e81dd8 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/Jackson3JsonNodeJsonProviderTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/Jackson3JsonNodeJsonProviderTest.java @@ -50,6 +50,48 @@ public class Jackson3JsonNodeJsonProviderTest extends BaseTest { "}" + "]"; + @Test + public void missing_array_indexes_are_not_found() { + DocumentContext context = using(JACKSON3_JSON_NODE_CONFIGURATION).parse("[1, null]"); + Assertions.assertThrows(PathNotFoundException.class, () -> context.read("$[2]")); + Assertions.assertThrows(PathNotFoundException.class, () -> context.read("$[-3]")); + + DocumentContext empty = using(JACKSON3_JSON_NODE_CONFIGURATION).parse("[]"); + Assertions.assertThrows(PathNotFoundException.class, () -> empty.read("$[0]")); + Assertions.assertThrows(PathNotFoundException.class, () -> empty.read("$[-1]")); + } + + @Test + public void existing_array_values_are_preserved() { + DocumentContext context = using(JACKSON3_JSON_NODE_CONFIGURATION).parse("[1, null]"); + assertThat(context.read("$[0]").intValue()).isEqualTo(1); + assertThat(context.read("$[-2]").intValue()).isEqualTo(1); + assertThat(context.read("$[1]").isNull()).isTrue(); + assertThat(context.read("$[-1]").isNull()).isTrue(); + } + + @Test + public void missing_array_indexes_can_be_suppressed() { + DocumentContext context = using(JACKSON3_JSON_NODE_CONFIGURATION.addOptions(Option.SUPPRESS_EXCEPTIONS)) + .parse("[null]"); + assertThat(context.read("$[1]")).isNull(); + assertThat(context.read("$[0]").isNull()).isTrue(); + } + + @Test + public void missing_array_indexes_are_excluded_from_result_lists() { + DocumentContext context = using(JACKSON3_JSON_NODE_CONFIGURATION.addOptions( + Option.SUPPRESS_EXCEPTIONS, Option.ALWAYS_RETURN_LIST)).parse("[null]"); + assertThat(context.read("$[1]").size()).isZero(); + ArrayNode existing = context.read("$[0]"); + assertThat(existing.size()).isEqualTo(1); + assertThat(existing.get(0).isNull()).isTrue(); + + ArrayNode results = using(JACKSON3_JSON_NODE_CONFIGURATION).parse("[[1], [2, null]]").read("$[*][1]"); + assertThat(results.size()).isEqualTo(1); + assertThat(results.get(0).isNull()).isTrue(); + } + @Test public void json_can_be_parsed() { ObjectNode node = using(JACKSON3_JSON_NODE_CONFIGURATION).parse(JSON_DOCUMENT).read("$"); diff --git a/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java b/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java index 1684248b..774d44d7 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java @@ -50,6 +50,48 @@ public class JacksonJsonNodeJsonProviderTest extends BaseTest { "}" + "]"; + @Test + public void missing_array_indexes_are_not_found() { + DocumentContext context = using(JACKSON_JSON_NODE_CONFIGURATION).parse("[1, null]"); + Assertions.assertThrows(PathNotFoundException.class, () -> context.read("$[2]")); + Assertions.assertThrows(PathNotFoundException.class, () -> context.read("$[-3]")); + + DocumentContext empty = using(JACKSON_JSON_NODE_CONFIGURATION).parse("[]"); + Assertions.assertThrows(PathNotFoundException.class, () -> empty.read("$[0]")); + Assertions.assertThrows(PathNotFoundException.class, () -> empty.read("$[-1]")); + } + + @Test + public void existing_array_values_are_preserved() { + DocumentContext context = using(JACKSON_JSON_NODE_CONFIGURATION).parse("[1, null]"); + assertThat(context.read("$[0]").intValue()).isEqualTo(1); + assertThat(context.read("$[-2]").intValue()).isEqualTo(1); + assertThat(context.read("$[1]").isNull()).isTrue(); + assertThat(context.read("$[-1]").isNull()).isTrue(); + } + + @Test + public void missing_array_indexes_can_be_suppressed() { + DocumentContext context = using(JACKSON_JSON_NODE_CONFIGURATION.addOptions(Option.SUPPRESS_EXCEPTIONS)) + .parse("[null]"); + assertThat(context.read("$[1]")).isNull(); + assertThat(context.read("$[0]").isNull()).isTrue(); + } + + @Test + public void missing_array_indexes_are_excluded_from_result_lists() { + DocumentContext context = using(JACKSON_JSON_NODE_CONFIGURATION.addOptions( + Option.SUPPRESS_EXCEPTIONS, Option.ALWAYS_RETURN_LIST)).parse("[null]"); + assertThat(context.read("$[1]").size()).isZero(); + ArrayNode existing = context.read("$[0]"); + assertThat(existing.size()).isEqualTo(1); + assertThat(existing.get(0).isNull()).isTrue(); + + ArrayNode results = using(JACKSON_JSON_NODE_CONFIGURATION).parse("[[1], [2, null]]").read("$[*][1]"); + assertThat(results.size()).isEqualTo(1); + assertThat(results.get(0).isNull()).isTrue(); + } + @Test public void json_can_be_parsed() { ObjectNode node = using(JACKSON_JSON_NODE_CONFIGURATION).parse(JSON_DOCUMENT).read("$");