From 7c729f54b1f3bca69dc0ce094e36c51f1ff25c64 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 29 Apr 2013 22:50:06 +1000 Subject: [PATCH] [PropertyAccess] Added negative path replaces and optional string arguments for PropertyPathBuilder. --- .../PropertyAccess/PropertyPathBuilder.php | 48 +++++++++++-------- .../Tests/PropertyPathBuilderTest.php | 42 +++++++++++++--- 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyPathBuilder.php b/src/Symfony/Component/PropertyAccess/PropertyPathBuilder.php index 07674f7df5d8a..f4eb0fb93ff50 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyPathBuilder.php +++ b/src/Symfony/Component/PropertyAccess/PropertyPathBuilder.php @@ -31,10 +31,10 @@ class PropertyPathBuilder /** * Creates a new property path builder. * - * @param null|PropertyPathInterface $path The path to initially store - * in the builder. Optional. + * @param null|PropertyPathInterface|string $path The path to initially store + * in the builder. Optional. */ - public function __construct(PropertyPathInterface $path = null) + public function __construct($path = null) { if (null !== $path) { $this->append($path); @@ -44,14 +44,18 @@ public function __construct(PropertyPathInterface $path = null) /** * Appends a (sub-) path to the current path. * - * @param PropertyPathInterface $path The path to append - * @param integer $offset The offset where the appended piece - * starts in $path - * @param integer $length The length of the appended piece. - * If 0, the full path is appended. + * @param PropertyPathInterface|string $path The path to append. + * @param integer $offset The offset where the appended + * piece starts in $path. + * @param integer $length The length of the appended piece. + * If 0, the full path is appended. */ - public function append(PropertyPathInterface $path, $offset = 0, $length = 0) + public function append($path, $offset = 0, $length = 0) { + if (is_string($path)) { + $path = new PropertyPath($path); + } + if (0 === $length) { $end = $path->getLength(); } else { @@ -106,20 +110,26 @@ public function remove($offset, $length = 1) /** * Replaces a sub-path by a different (sub-) path. * - * @param integer $offset The offset at which to replace - * @param integer $length The length of the piece to replace - * @param PropertyPathInterface $path The path to insert - * @param integer $pathOffset The offset where the inserted piece - * starts in $path - * @param integer $pathLength The length of the inserted piece. - * If 0, the full path is inserted. + * @param integer $offset The offset at which to replace. + * @param integer $length The length of the piece to replace. + * @param PropertyPathInterface|string $path The path to insert. + * @param integer $pathOffset The offset where the inserted piece + * starts in $path. + * @param integer $pathLength The length of the inserted piece. + * If 0, the full path is inserted. * * @throws OutOfBoundsException If the offset is invalid */ - public function replace($offset, $length, PropertyPathInterface $path, $pathOffset = 0, $pathLength = 0) + public function replace($offset, $length, $path, $pathOffset = 0, $pathLength = 0) { - if (!isset($this->elements[$offset])) { - throw new OutOfBoundsException(sprintf('The offset %s is not within the property path', $offset)); + if (is_string($path)) { + $path = new PropertyPath($path); + } + + if ($offset < 0 && abs($offset) <= $this->getLength()) { + $offset = $this->getLength() + $offset; + } elseif (!isset($this->elements[$offset])) { + throw new OutOfBoundsException('The offset ' . $offset . ' is not within the property path'); } if (0 === $pathLength) { diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyPathBuilderTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyPathBuilderTest.php index 0d4872661da82..14300b1ded102 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyPathBuilderTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyPathBuilderTest.php @@ -73,6 +73,15 @@ public function testAppend() $this->assertEquals($path, $this->builder->getPropertyPath()); } + public function testAppendUsingString() + { + $this->builder->append('new1[new2]'); + + $path = new PropertyPath(self::PREFIX . '.new1[new2]'); + + $this->assertEquals($path, $this->builder->getPropertyPath()); + } + public function testAppendWithOffset() { $this->builder->append(new PropertyPath('new1[new2].new3'), 1); @@ -168,20 +177,39 @@ public function testReplace() $this->assertEquals($path, $this->builder->getPropertyPath()); } - /** - * @expectedException \OutOfBoundsException - */ - public function testReplaceDoesNotAllowInvalidOffsets() + public function testReplaceUsingString() + { + $this->builder->replace(1, 1, 'new1[new2].new3'); + + $path = new PropertyPath('old1.new1[new2].new3.old3[old4][old5].old6'); + + $this->assertEquals($path, $this->builder->getPropertyPath()); + } + + public function testReplaceNegative() { - $this->builder->replace(6, 1, new PropertyPath('new1[new2].new3')); + $this->builder->replace(-1, 1, new PropertyPath('new1[new2].new3')); + + $path = new PropertyPath('old1[old2].old3[old4][old5].new1[new2].new3'); + + $this->assertEquals($path, $this->builder->getPropertyPath()); } /** + * @dataProvider provideInvalidOffsets * @expectedException \OutOfBoundsException */ - public function testReplaceDoesNotAllowNegativeOffsets() + public function testReplaceDoesNotAllowInvalidOffsets($offset) { - $this->builder->replace(-1, 1, new PropertyPath('new1[new2].new3')); + $this->builder->replace($offset, 1, new PropertyPath('new1[new2].new3')); + } + + public function provideInvalidOffsets() + { + return array( + array(6), + array(-7), + ); } public function testReplaceWithLengthGreaterOne()