Skip to content

Commit 64972f5

Browse files
authored
Merge pull request #7 from swaggest/issue-6
Issue 6
2 parents e583f89 + 688b9df commit 64972f5

File tree

4 files changed

+106
-4
lines changed

4 files changed

+106
-4
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
/json-diff
44
/json-diff.tar.gz
55
/composer.lock
6-
/composer.phar
6+
/composer.phar
7+
/clover.xml

src/JsonDiff.php

+11-2
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ private function process($original, $new)
231231
$newOrdered = array();
232232

233233
$originalKeys = $original instanceof \stdClass ? get_object_vars($original) : $original;
234+
$isArray = is_array($original);
235+
$removedOffset = 0;
234236

235237
foreach ($originalKeys as $key => $originalValue) {
236238
if ($this->options & self::STOP_ON_DIFF) {
@@ -241,8 +243,12 @@ private function process($original, $new)
241243

242244
$path = $this->path;
243245
$pathItems = $this->pathItems;
244-
$this->path .= '/' . JsonPointer::escapeSegment($key, $this->options & self::JSON_URI_FRAGMENT_ID);
245-
$this->pathItems[] = $key;
246+
$actualKey = $key;
247+
if ($isArray) {
248+
$actualKey -= $removedOffset;
249+
}
250+
$this->path .= '/' . JsonPointer::escapeSegment($actualKey, $this->options & self::JSON_URI_FRAGMENT_ID);
251+
$this->pathItems[] = $actualKey;
246252

247253
if (array_key_exists($key, $newArray)) {
248254
$newOrdered[$key] = $this->process($originalValue, $newArray[$key]);
@@ -253,6 +259,9 @@ private function process($original, $new)
253259
return null;
254260
}
255261
$this->removedPaths [] = $this->path;
262+
if ($isArray) {
263+
$removedOffset++;
264+
}
256265

257266
$this->jsonPatch->op(new Remove($this->path));
258267

src/JsonPointer.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ public static function remove(&$holder, $pathItems)
202202
unset($parent->$refKey);
203203
} else {
204204
unset($parent[$refKey]);
205-
$parent = array_values($parent);
205+
if ($refKey !== count($parent)) {
206+
$parent = array_values($parent);
207+
}
206208
}
207209
}
208210
return $ref;

tests/src/Issues/Issue6Test.php

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace Swaggest\JsonDiff\Tests\Issues;
4+
5+
use Swaggest\JsonDiff\JsonDiff;
6+
use Swaggest\JsonDiff\JsonPatch;
7+
8+
9+
/**
10+
* @see https://github.com/swaggest/json-diff/issues/6
11+
*/
12+
class Issue6Test extends \PHPUnit_Framework_TestCase
13+
{
14+
public function testDefault()
15+
{
16+
$json1 = json_decode('[{"name":"a"},{"name":"b"},{"name":"c"}]');
17+
$json2 = json_decode('[{"name":"b"}]');
18+
19+
$diff = new JsonDiff($json1, $json2);
20+
$patch = $diff->getPatch();
21+
22+
$this->assertSame(<<<'JSON'
23+
[
24+
{
25+
"value": "a",
26+
"op": "test",
27+
"path": "/0/name"
28+
},
29+
{
30+
"value": "b",
31+
"op": "replace",
32+
"path": "/0/name"
33+
},
34+
{
35+
"op": "remove",
36+
"path": "/1"
37+
},
38+
{
39+
"op": "remove",
40+
"path": "/1"
41+
}
42+
]
43+
JSON
44+
, json_encode($patch, JSON_PRETTY_PRINT + JSON_UNESCAPED_SLASHES));
45+
46+
$json1a = $json1;
47+
$patch->apply($json1a);
48+
49+
$this->assertEquals($json2, $json1a);
50+
}
51+
52+
public function testOriginal()
53+
{
54+
$originalJson = '[{"name":"a"},{"name":"b"},{"name":"c"}]';
55+
$newJson = '[{"name":"b"}]';
56+
$diff = new JsonDiff(json_decode($originalJson), json_decode($newJson));
57+
58+
$patchJson = json_decode(json_encode($diff->getPatch()->jsonSerialize()), true);
59+
60+
$original = json_decode($originalJson);
61+
$patch = JsonPatch::import($patchJson);
62+
$patch->apply($original);
63+
$this->assertEquals($original, json_decode($newJson));
64+
}
65+
66+
67+
public function testDoubleInverseRemove()
68+
{
69+
$json1 = json_decode('[{"name":"a"},{"name":"b"},{"name":"c"}]');
70+
$json2 = json_decode('[{"name":"b"}]');
71+
72+
$patch = JsonPatch::import(json_decode('[{"op":"remove","path":"/2"},{"op":"remove","path":"/0"}]'));
73+
74+
$json1a = $json1;
75+
$patch->apply($json1a);
76+
$this->assertEquals(json_encode($json2), json_encode($json1a));
77+
}
78+
79+
public function testDoubleRemove()
80+
{
81+
$json1 = json_decode('[{"name":"a"},{"name":"b"},{"name":"c"}]');
82+
$json2 = json_decode('[{"name":"b"}]');
83+
84+
$patch = JsonPatch::import(json_decode('[{"op":"remove","path":"/0"},{"op":"remove","path":"/1"}]'));
85+
86+
$json1a = $json1;
87+
$patch->apply($json1a);
88+
$this->assertEquals(json_encode($json2), json_encode($json1a));
89+
}
90+
}

0 commit comments

Comments
 (0)