Skip to content

Commit

Permalink
Fix, correct object behavior of remove operation - closes #35
Browse files Browse the repository at this point in the history
  • Loading branch information
narcoticfresh authored and raphaelstolt committed Aug 25, 2016
1 parent c92286c commit dd419ab
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 8 deletions.
25 changes: 19 additions & 6 deletions src/Rs/Json/Patch/Operations/Remove.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,21 @@ public function perform($targetDocument)
return $targetDocument;
}

$targetDocument = json_decode($targetDocument, true);
$targetDocument = json_decode($targetDocument);
$this->remove($targetDocument, $this->getPointerParts());

return json_encode($targetDocument, JSON_UNESCAPED_UNICODE);
}

/**
* @param array $json The json_decode'd Json structure.
* @param array $pointerParts The parts of the fed pointer.
* @param array|object $json The json_decode'd Json structure.
* @param array $pointerParts The parts of the fed pointer.
*/
private function remove(array &$json, array $pointerParts)
private function remove(&$json, array $pointerParts)
{
$pointerPart = array_shift($pointerParts);

if (isset($json[$pointerPart])) {
if (is_array($json) && isset($json[$pointerPart])) {
if (count($pointerParts) === 0) {
unset($json[$pointerPart]);
if (ctype_digit($pointerPart)) {
Expand All @@ -72,10 +72,23 @@ private function remove(array &$json, array $pointerParts)
$pointerParts
);
}
} elseif (is_object($json) && isset($json->{$pointerPart})) {
if (count($pointerParts) === 0) {
unset($json->{$pointerPart});
} else {
$this->remove(
$json->{$pointerPart},
$pointerParts
);
}
} elseif ($pointerPart === Pointer::LAST_ARRAY_ELEMENT_CHAR && is_array($json)) {
unset($json[count($json) - 1]);
} else {
unset($json[$pointerPart]);
if (is_object($json)) {
unset($json->{$pointerPart});
} else {
unset($json[$pointerPart]);
}
}
}
}
38 changes: 37 additions & 1 deletion tests/integration/Rs/Json/PatchRemoveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function removeNullProvider()
array(
'{"a":{"b":null}}', // target document
'[ {"op":"remove", "path":"/a/b"} ]', // patch document
'{"a":[]}' // expected doument
'{"a":{}}' // expected document
),
array(
'{"a":null}',
Expand Down Expand Up @@ -105,6 +105,42 @@ public function shouldReturnTargetDocumentWhenPathPointerIsNonexistent()
$patch = new Patch($targetDocument, $patchDocument);
$patchedDocument = $patch->apply();

$this->assertJsonStringEqualsJsonString(
$expectedDocument,
$patchedDocument
);
}
/**
* @test
* @ticket 35 (https://github.com/raphaelstolt/php-jsonpatch/issues/35)
*/
public function shouldPreserveEmptyObject()
{
$targetDocument = '{"foo":{"bar":{"baz": {}, "qux": "val"}}, "bar": {}}';
$patchDocument = '[{"op":"remove", "path":"/foo/bar/qux"}]';
$expectedDocument = '{"foo":{"bar":{"baz": {}}}, "bar": {}}';

$patch = new Patch($targetDocument, $patchDocument);
$patchedDocument = $patch->apply();

$this->assertJsonStringEqualsJsonString(
$expectedDocument,
$patchedDocument
);
}
/**
* @test
* @ticket 35 (https://github.com/raphaelstolt/php-jsonpatch/issues/35)
*/
public function shouldPreserveEmptyObjectNumericObjectProperties()
{
$targetDocument = '{"foo":{"bar":{"baz": {}, "3": "val"}}, "bar": {}}';
$patchDocument = '[{"op":"remove", "path":"/foo/bar/3"}]';
$expectedDocument = '{"foo":{"bar":{"baz": {}}}, "bar": {}}';

$patch = new Patch($targetDocument, $patchDocument);
$patchedDocument = $patch->apply();

$this->assertJsonStringEqualsJsonString(
$expectedDocument,
$patchedDocument
Expand Down
40 changes: 39 additions & 1 deletion tests/unit/Rs/Json/Patch/Operations/RemoveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,44 @@ public function shouldNotRemoveElementWhenPathDoesNotExist()
$removeOperation->perform($targetJson)
);
}
/**
* @test
* @ticket 35 (https://github.com/raphaelstolt/php-jsonpatch/issues/35)
*/
public function shouldPreserveEmptyObject()
{
$targetJson = '{"foo":{"bar":{"baz": {}, "qux": "val"}}, "bar": {}}';
$expectedJson = '{"foo":{"bar":{"baz": {}}}, "bar": {}}';

$operation = new \stdClass;
$operation->path = '/foo/bar/qux';

$removeOperation = new Remove($operation);

$this->assertJsonStringEqualsJsonString(
$expectedJson,
$removeOperation->perform($targetJson)
);
}
/**
* @test
* @ticket 35 (https://github.com/raphaelstolt/php-jsonpatch/issues/35)
*/
public function shouldPreserveEmptyObjectNumericObjectProperties()
{
$targetJson = '{"foo":{"bar":{"baz": {}, "3": "val"}}, "bar": {}}';
$expectedJson = '{"foo":{"bar":{"baz": {}}}, "bar": {}}';

$operation = new \stdClass;
$operation->path = '/foo/bar/3';

$removeOperation = new Remove($operation);

$this->assertJsonStringEqualsJsonString(
$expectedJson,
$removeOperation->perform($targetJson)
);
}
/**
* @test
* @dataProvider removeProvider
Expand Down Expand Up @@ -75,7 +113,7 @@ public function removeProvider()
)),
array(array(
'given-json' => '{"baz":{"boo":{"bar":"zoo"}}}',
'expected-json' => '{"baz":{"boo":[]}}',
'expected-json' => '{"baz":{"boo":{}}}',
'remove-operation' => (object) array('path' => '/baz/boo/bar'),
)),
array(array(
Expand Down

0 comments on commit dd419ab

Please sign in to comment.