diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java index 34cf1402b..e338d8bf6 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java @@ -133,8 +133,9 @@ private static Object readObjectProperty(String property, Object model, Evaluati protected void handleArrayIndex(int index, String currentPath, Object model, EvaluationContextImpl ctx) { String evalPath = Utils.concat(currentPath, "[", String.valueOf(index), "]"); - PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, index) : PathRef.NO_OP; + // Normalize negative indices before creating PathRef so set/delete/map match read (#1077) int effectiveIndex = index < 0 ? ctx.jsonProvider().length(model) + index : index; + PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, effectiveIndex) : PathRef.NO_OP; try { Object evalHit = ctx.jsonProvider().getArrayIndex(model, effectiveIndex); if (isLeaf()) { diff --git a/json-path/src/test/java/com/jayway/jsonpath/WriteTest.java b/json-path/src/test/java/com/jayway/jsonpath/WriteTest.java index 5dfb0e3e4..a5a9862c8 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/WriteTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/WriteTest.java @@ -100,6 +100,32 @@ public void an_array_index_can_be_updated() { assertThat(res).isEqualTo("a"); } + @Test + public void a_negative_array_index_can_be_updated() { + // set/delete/map must resolve $[-1] like read (#1077) + DocumentContext ctx = parse("[\"a\",\"b\",\"c\"]"); + assertThat(ctx.read("$[-1]")).isEqualTo("c"); + + ctx.set("$[-1]", "z"); + assertThat(ctx.>json()).containsExactly("a", "b", "z"); + assertThat(ctx.read("$[-1]")).isEqualTo("z"); + } + + @Test + public void a_negative_array_index_can_be_deleted() { + DocumentContext ctx = parse("[\"a\",\"b\",\"c\"]"); + ctx.delete("$[-1]"); + assertThat(ctx.>json()).containsExactly("a", "b"); + } + + @Test + public void a_negative_array_index_can_be_mapped() { + DocumentContext ctx = parse("[\"a\",\"b\",\"c\"]"); + ctx.map("$[-1]", (currentValue, configuration) -> currentValue + "!"); + assertThat(ctx.>json()).containsExactly("a", "b", "c!"); + assertThat(ctx.read("$[-1]")).isEqualTo("c!"); + } + @Test public void an_array_slice_can_be_updated() {