From e1d0f04ca86465022edcddd83542aaf2e5a7867e Mon Sep 17 00:00:00 2001 From: vpoturaev Date: Fri, 9 Feb 2018 08:47:15 +0700 Subject: [PATCH] #6 renumerating arrays after item removal --- src/JsonDiff.php | 13 +++++++++-- src/JsonPointer.php | 3 +++ tests/src/Issues/Issue6Test.php | 39 +++++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/JsonDiff.php b/src/JsonDiff.php index b80c4d8..41f51c9 100644 --- a/src/JsonDiff.php +++ b/src/JsonDiff.php @@ -220,12 +220,18 @@ private function process($original, $new) $newOrdered = array(); $originalKeys = $original instanceof \stdClass ? get_object_vars($original) : $original; + $isArray = is_array($original); + $removedOffset = 0; foreach ($originalKeys as $key => $originalValue) { $path = $this->path; $pathItems = $this->pathItems; - $this->path .= '/' . JsonPointer::escapeSegment($key, $this->options & self::JSON_URI_FRAGMENT_ID); - $this->pathItems[] = $key; + $actualKey = $key; + if ($isArray) { + $actualKey -= $removedOffset; + } + $this->path .= '/' . JsonPointer::escapeSegment($actualKey, $this->options & self::JSON_URI_FRAGMENT_ID); + $this->pathItems[] = $actualKey; if (array_key_exists($key, $newArray)) { $newOrdered[$key] = $this->process($originalValue, $newArray[$key]); @@ -233,6 +239,9 @@ private function process($original, $new) } else { $this->removedCnt++; $this->removedPaths [] = $this->path; + if ($isArray) { + $removedOffset++; + } $this->jsonPatch->op(new Remove($this->path)); diff --git a/src/JsonPointer.php b/src/JsonPointer.php index 25686e9..2ff34c9 100644 --- a/src/JsonPointer.php +++ b/src/JsonPointer.php @@ -159,6 +159,9 @@ public static function remove(&$holder, $pathItems) unset($parent->$refKey); } else { unset($parent[$refKey]); + if ($refKey !== count($parent)) { + $parent = array_values($parent); + } } } return $ref; diff --git a/tests/src/Issues/Issue6Test.php b/tests/src/Issues/Issue6Test.php index 99b00da..36292ed 100644 --- a/tests/src/Issues/Issue6Test.php +++ b/tests/src/Issues/Issue6Test.php @@ -11,7 +11,7 @@ */ class Issue6Test extends \PHPUnit_Framework_TestCase { - public function testIssue6() + public function testDefault() { $json1 = json_decode('[{"name":"a"},{"name":"b"},{"name":"c"}]'); $json2 = json_decode('[{"name":"b"}]'); @@ -37,7 +37,7 @@ public function testIssue6() }, { "op": "remove", - "path": "/2" + "path": "/1" } ] JSON @@ -49,21 +49,42 @@ public function testIssue6() $this->assertEquals($json2, $json1a); } + public function testOriginal() + { + $originalJson = '[{"name":"a"},{"name":"b"},{"name":"c"}]'; + $newJson = '[{"name":"b"}]'; + $diff = new JsonDiff(json_decode($originalJson), json_decode($newJson)); + + $patchJson = json_decode(json_encode($diff->getPatch()->jsonSerialize()), true); + + $original = json_decode($originalJson); + $patch = JsonPatch::import($patchJson); + $patch->apply($original); + $this->assertEquals($original, json_decode($newJson)); + } + + + public function testDoubleInverseRemove() + { + $json1 = json_decode('[{"name":"a"},{"name":"b"},{"name":"c"}]'); + $json2 = json_decode('[{"name":"b"}]'); + + $patch = JsonPatch::import(json_decode('[{"op":"remove","path":"/2"},{"op":"remove","path":"/0"}]')); + + $json1a = $json1; + $patch->apply($json1a); + $this->assertEquals(json_encode($json2), json_encode($json1a)); + } - public function testIssue6Remove() + public function testDoubleRemove() { $json1 = json_decode('[{"name":"a"},{"name":"b"},{"name":"c"}]'); $json2 = json_decode('[{"name":"b"}]'); - $patch = JsonPatch::import(json_decode('[{"op":"remove","path":"/0"},{"op":"remove","path":"/2"}]')); + $patch = JsonPatch::import(json_decode('[{"op":"remove","path":"/0"},{"op":"remove","path":"/1"}]')); $json1a = $json1; $patch->apply($json1a); $this->assertEquals(json_encode($json2), json_encode($json1a)); - /* - Failed asserting that two strings are equal. - Expected :'[{"name":"b"}]' - Actual :'{"1":{"name":"b"}}' - */ } } \ No newline at end of file