diff --git a/src/Components/NestedAccessor.php b/src/Components/NestedAccessor.php index d15b54d..a1687f3 100644 --- a/src/Components/NestedAccessor.php +++ b/src/Components/NestedAccessor.php @@ -89,7 +89,12 @@ public function set($path, $value): self $source = &$this->getRef($this->getPathStack($path)); if ($source instanceof ProxyInterface) { - $source->setValue($value); + try { + $source->setValue($value); + } catch (\BadMethodCallException $e) { + [$key, $path] = $this->cutPathTail($path); + throw new PathNotWritableException($key, $path, $this->pathDelimiter); + } } else { $source = $value; } diff --git a/tests/unit/NestedAccessor/NestedAccessorSetTest.php b/tests/unit/NestedAccessor/NestedAccessorSetTest.php index ba4fa95..f30dd1e 100644 --- a/tests/unit/NestedAccessor/NestedAccessorSetTest.php +++ b/tests/unit/NestedAccessor/NestedAccessorSetTest.php @@ -5,6 +5,7 @@ namespace Smoren\Schemator\Tests\Unit\NestedAccessor; use Smoren\Schemator\Components\NestedAccessor; +use Smoren\Schemator\Exceptions\PathNotWritableException; use Smoren\Schemator\Tests\Unit\Fixtures\ClassWithAccessibleProperties; class NestedAccessorSetTest extends \Codeception\Test\Unit @@ -90,6 +91,12 @@ public function dataProviderForArray(): array [1], ['a' => ['b' => ['c' => [0], 'd' => [1]]]], ], + [ + ['a' => ['b' => 1]], + ['a', 'b', 'd'], + [1], + ['a' => ['b' => ['d' => [1]]]], + ], ]; } @@ -260,4 +267,40 @@ public function dataProviderForObject(): array ], ]; } + + /** + * @dataProvider dataProviderForPathNotWritable + */ + public function testPathNotWritable($source, $path, $value) + { + // Given + $accessor = new NestedAccessor($source); + + // Then + $this->expectException(PathNotWritableException::class); + + // When + $accessor->set($path, $value); + } + + public function dataProviderForPathNotWritable(): array + { + return [ + [ + new ClassWithAccessibleProperties(), + 'protectedProperty', + 22, + ], + [ + new ClassWithAccessibleProperties(), + 'privateProperty', + 22, + ], + [ + 1, + 'test', + 22, + ], + ]; + } }