diff --git a/src/Rs/Json/Patch/Operations/Test.php b/src/Rs/Json/Patch/Operations/Test.php index 6ef8cbf..c66d27e 100755 --- a/src/Rs/Json/Patch/Operations/Test.php +++ b/src/Rs/Json/Patch/Operations/Test.php @@ -41,15 +41,15 @@ public function perform($targetDocument) try { $get = $pointer->get($this->getPath()); + // Pointer::get() method can return mixed result, we should force type to array for json string + if($this->isValidJsonString($get)) { + $get = json_decode($get, true); + } } catch (NonexistentValueReferencedException $e) { $get = null; } - if (is_string($this->getValue())) { - $value = json_decode($this->getValue(), true); - } else { - $value = $this->getValue(); - } + $value = is_object($this->getValue())? (array) $this->getValue() : $this->getValue(); if (is_array($value) && is_array($get)) { asort($get); @@ -60,4 +60,20 @@ public function perform($targetDocument) return $get === $this->getValue(); } + + /** + * Method check if string is valid JSON string + * + * @param $string + * @return boolean + */ + private function isValidJsonString($string) + { + if(is_string($string) && strlen($string)) { + // Decode and check last error + json_decode($string); + return json_last_error() === JSON_ERROR_NONE; + } + return false; + } } diff --git a/tests/integration/Rs/Json/PatchTestTest.php b/tests/integration/Rs/Json/PatchTestTest.php index 9176891..b9cb7ba 100755 --- a/tests/integration/Rs/Json/PatchTestTest.php +++ b/tests/integration/Rs/Json/PatchTestTest.php @@ -83,6 +83,33 @@ public function shouldThrowFailedTestExceptionWhenTestFailsForUnsuccessfulCompar $patchedDocument ); } + /** + * @test + */ + public function testSuccessfulComparison() + { + $expectedDocument = $targetDocument = json_encode( + [ + 'arrayField' => [ + ['name' => 'foo'], + ['name' => 'bar'] + ] + ] + ); + $patchDocument = json_encode( + [ + ['op' => 'test', 'path' => '/arrayField/0', 'value' => ['name' => 'foo']] + ] + ); + + $patch = new Patch($targetDocument, $patchDocument); + $patchedDocument = $patch->apply(); + + $this->assertJsonStringEqualsJsonString( + $expectedDocument, + $patchedDocument + ); + } /** * @test * @expectedException Rs\Json\Pointer\InvalidPointerException diff --git a/tests/unit/Rs/Json/Patch/Operations/TestTest.php b/tests/unit/Rs/Json/Patch/Operations/TestTest.php index e507dd4..e172324 100755 --- a/tests/unit/Rs/Json/Patch/Operations/TestTest.php +++ b/tests/unit/Rs/Json/Patch/Operations/TestTest.php @@ -129,7 +129,7 @@ public function shouldReturnTrueForMatchingArrays() { $operation = new \stdClass; $operation->path = '/chars/array'; - $operation->value = '["abc", "def"]'; + $operation->value = array("abc", "def"); $testOperation = new Test($operation); @@ -142,7 +142,7 @@ public function shouldReturnFalseForNoneMatchingArrays() { $operation = new \stdClass; $operation->path = '/chars/array'; - $operation->value = '["def", "hij"]'; + $operation->value = array("def", "hij"); $testOperation = new Test($operation); @@ -305,11 +305,11 @@ public function matchingObjectProvider() return array( array(array( 'given-json' => '{"foo":"bar"}', - 'test-operation' => (object) array('path' => '', 'value' => '{"foo":"bar"}'), + 'test-operation' => (object) array('path' => '', 'value' => array("foo" => "bar")), )), array(array( 'given-json' => '{"foo":{"coo":{"koo":"roo","moo":"zoo"}}}', - 'test-operation' => (object) array('path' => '/foo/coo', 'value' => '{"koo":"roo","moo":"zoo"}'), + 'test-operation' => (object) array('path' => '/foo/coo', 'value' => array("koo" => "roo", "moo" => "zoo")), )) ); }