Skip to content

Handle objects #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/main/php/text/json/patch/ArrayEnd.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public function remove() {
if ($this->parent->exists) {
if (array_key_exists('-', $this->parent->reference)) {
unset($this->parent->reference['-']);
empty($this->parent->reference) && $this->parent->reference= (object)[];
return Applied::$CLEANLY;
} else if (0 === key($this->parent->reference)) {
array_pop($this->parent->reference);
Expand All @@ -56,7 +57,9 @@ public function remove() {
*/
public function add($value) {
if ($this->parent->exists) {
if (empty($this->parent->reference) || 0 === key($this->parent->reference)) {
if (is_object($this->parent->reference)) {
$this->parent->reference= ['-' => $value] + (array)$this->parent->reference;
} else if (empty($this->parent->reference) || 0 === key($this->parent->reference)) {
$this->parent->reference[]= $value;
return Applied::$CLEANLY;
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/main/php/text/json/patch/ArrayIndex.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class ArrayIndex extends Address {
*/
public function __construct($pos, parent $parent) {
$this->pos= $pos;
is_object($parent->reference) && $parent->reference= (array)$parent->reference;

if (is_array($parent->reference) && array_key_exists($this->pos, $parent->reference)) {
parent::__construct($parent->reference[$this->pos], $parent);
} else {
Expand Down
7 changes: 6 additions & 1 deletion src/main/php/text/json/patch/ObjectMember.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class ObjectMember extends Address {
*/
public function __construct($name, parent $parent) {
$this->name= $name;
is_object($parent->reference) && $parent->reference= (array)$parent->reference;

if (is_array($parent->reference) && array_key_exists($this->name, $parent->reference)) {
parent::__construct($parent->reference[$this->name], $parent);
} else {
Expand Down Expand Up @@ -44,6 +46,7 @@ public function modify($value) {
public function remove() {
if ($this->exists) {
unset($this->parent->reference[$this->name]);
empty($this->parent->reference) && $this->parent->reference= (object)[];
return Applied::$CLEANLY;
} else {
return new PathDoesNotExist($this->path());
Expand All @@ -58,7 +61,9 @@ public function remove() {
*/
public function add($value) {
if ($this->parent->exists) {
if (0 === key($this->parent->reference)) {
if (is_object($this->parent->reference)) {
$this->parent->reference= [];
} else if (0 === key($this->parent->reference)) {
return new TypeConflict('Object operation on array target');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php namespace text\json\patch\unittest;

use text\json\patch\{Changes, TestOperation};
use test\Assert;
use test\{Test, TestCase, Values};
use text\json\patch\{Changes, TestOperation};

class ChangesTest {

Expand Down
76 changes: 71 additions & 5 deletions src/test/php/text/json/patch/unittest/PointerTest.class.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php namespace text\json\patch\unittest;

use text\json\patch\{Address, Pointer};
use test\Assert;
use test\{Test, Values};
use text\json\patch\{Address, Pointer};

class PointerTest {

Expand Down Expand Up @@ -115,12 +115,19 @@ public function modify_array_index() {
}

#[Test]
public function modify_object_member() {
public function modify_object_member_on_array() {
$value= ['text' => 'original'];
(new Pointer('/text'))->resolve($value)->modify('modified');
Assert::equals(['text' => 'modified'], $value);
}

#[Test]
public function modify_object_member_on_object() {
$value= (object)['text' => 'original'];
(new Pointer('/text'))->resolve($value)->modify('modified');
Assert::equals(['text' => 'modified'], $value);
}

#[Test]
public function modify_non_existant_array_index() {
$value= [];
Expand All @@ -147,10 +154,24 @@ public function remove_array_index() {
}

#[Test]
public function remove_object_member() {
public function remove_last_object_membery() {
$value= ['text' => 'original'];
(new Pointer('/text'))->resolve($value)->remove();
Assert::equals([], $value);
Assert::equals((object)[], $value);
}

#[Test]
public function remove_object_member_from_array() {
$value= ['text' => 'original', 'key' => 'value'];
(new Pointer('/text'))->resolve($value)->remove();
Assert::equals(['key' => 'value'], $value);
}

#[Test]
public function remove_object_member_from_object() {
$value= (object)['text' => 'original', 'key' => 'value'];
(new Pointer('/text'))->resolve($value)->remove();
Assert::equals(['key' => 'value'], $value);
}

#[Test]
Expand Down Expand Up @@ -186,12 +207,47 @@ public function add_at_end_of_array() {
}

#[Test]
public function add_object_member() {
public function add_object_member_to_array() {
$value= ['a' => 'original'];
(new Pointer('/b'))->resolve($value)->add('added');
Assert::equals(['a' => 'original', 'b' => 'added'], $value);
}

#[Test]
public function add_object_member_to_object() {
$value= (object)['a' => 'original'];
(new Pointer('/b'))->resolve($value)->add('added');
Assert::equals(['a' => 'original', 'b' => 'added'], $value);
}

#[Test]
public function add_object_member_to_empty() {
$value= (object)[];
(new Pointer('/a'))->resolve($value)->add('added');
Assert::equals(['a' => 'added'], $value);
}

#[Test]
public function dash_for_object() {
$value= (object)['key' => 'value'];
(new Pointer('/-'))->resolve($value)->add('added');
Assert::equals(['key' => 'value', '-' => 'added'], $value);
}

#[Test]
public function modify_array_index_of_object() {
$value= (object)['1' => 'test'];
(new Pointer('/1'))->resolve($value)->modify('changed');
Assert::equals(['1' => 'changed'], $value);
}

#[Test]
public function dash_for_empty_object() {
$value= (object)[];
(new Pointer('/-'))->resolve($value)->add('added');
Assert::equals(['-' => 'added'], $value);
}

#[Test]
public function cannot_add_object_member_to_array() {
$value= [1, 2, 3];
Expand All @@ -209,4 +265,14 @@ public function cannot_add_to_nonexistant_object() {
$value= [];
Assert::instance('text.json.patch.PathDoesNotExist', (new Pointer('/non-existant/member'))->resolve($value)->add('test'));
}

#[Test]
public function remove_then_add_back_object_member() {
$value= ['text' => 'original'];
$ptr= new Pointer('/text');
$ptr->resolve($value)->remove();
$ptr->resolve($value)->add('changed');

Assert::equals(['text' => 'changed'], $value);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<?php namespace text\json\patch\unittest;

use test\{Assert, Test};
use text\json\patch\{Applied, RemoveOperation};
use test\Assert;
use test\Test;

class RemoveOperationTest extends OperationTest {

Expand All @@ -15,6 +14,15 @@ public function removing_an_object_member() {
Assert::equals(['foo' => 'bar'], $value);
}

#[Test]
public function removing_last_object_member() {
$operation= new RemoveOperation('/baz');

$value= ['baz' => 'qux'];
Assert::equals(Applied::$CLEANLY, $operation->applyTo($value));
Assert::equals((object)[], $value);
}

#[Test]
public function removing_an_array_element() {
$operation= new RemoveOperation('/foo/1');
Expand Down Expand Up @@ -54,7 +62,7 @@ public function dash_has_no_special_meaning_for_non_arrays() {

$value= ['-' => 4];
Assert::equals(Applied::$CLEANLY, $operation->applyTo($value));
Assert::equals([], $value);
Assert::equals((object)[], $value);
}

#[Test]
Expand Down
Loading