diff --git a/Test/Unit/Visitor/Asserter.php b/Test/Unit/Visitor/Asserter.php index 65b9087..c6defc2 100644 --- a/Test/Unit/Visitor/Asserter.php +++ b/Test/Unit/Visitor/Asserter.php @@ -36,6 +36,7 @@ namespace Hoa\Ruler\Test\Unit\Visitor; +use ArrayObject; use Hoa\Ruler as LUT; use Hoa\Ruler\Visitor\Asserter as SUT; use Hoa\Test; @@ -591,6 +592,51 @@ function ($x) { ->isIdenticalTo($result); } + public function case_visit_operator_array_like_dimension_1() + { + $this + ->given( + $operator = new LUT\Model\Operator('c', [7]), + $operator->index('x'), + $asserter = new SUT(), + $asserter->setOperator( + 'c', + function ($x) { + return new ArrayObject(['x' => $x * 6]); + } + ) + ) + ->when($result = $this->invoke($asserter)->visitOperator($operator)) + ->then + ->integer($result) + ->isEqualTo(42) + ->integer($asserter->visit($operator)) + ->isIdenticalTo($result); + } + + public function case_visit_operator_array_like_dimension_2() + { + $this + ->given( + $operator = new LUT\Model\Operator('c', [7]), + $operator->index('x'), + $operator->index('y'), + $asserter = new SUT(), + $asserter->setOperator( + 'c', + function ($x) { + return new ArrayObject(['x' => new ArrayObject(['y' => $x * 6])]); + } + ) + ) + ->when($result = $this->invoke($asserter)->visitOperator($operator)) + ->then + ->integer($result) + ->isEqualTo(42) + ->integer($asserter->visit($operator)) + ->isIdenticalTo($result); + } + public function case_visit_operator_array_dimension_1_undefined_index() { $this @@ -643,6 +689,32 @@ function ($x) { ->hasMessage('Try to access to an undefined index: y (dimension number 1 of c()), because it is not an array.'); } + public function case_visit_operator_array_like_dimension_1_undefined_index() + { + $this + ->given( + $operator = new LUT\Model\Operator('c', [7]), + $operator->index('z'), + $asserter = new SUT(), + $asserter->setOperator( + 'c', + function ($x) { + return new ArrayObject(['x' => 42]); + } + ) + ) + ->exception(function () use ($asserter, $operator) { + $this->invoke($asserter)->visitOperator($operator); + }) + ->isInstanceOf(LUT\Exception\Asserter::class) + ->hasMessage('Try to access to an undefined index: z (dimension number 1 of c()).') + ->exception(function () use ($asserter, $operator) { + $asserter->visit($operator); + }) + ->isInstanceOf(LUT\Exception\Asserter::class) + ->hasMessage('Try to access to an undefined index: z (dimension number 1 of c()).'); + } + public function case_visit_operator_attribute_dimension_1() { $this diff --git a/Visitor/Asserter.php b/Visitor/Asserter.php index ca15d60..1840d39 100644 --- a/Visitor/Asserter.php +++ b/Visitor/Asserter.php @@ -36,6 +36,7 @@ namespace Hoa\Ruler\Visitor; +use ArrayAccess; use Hoa\Consistency; use Hoa\Ruler; use Hoa\Visitor; @@ -341,7 +342,10 @@ protected function visitArrayDimension( $value = $dimension[Ruler\Model\Bag\Context::ACCESS_VALUE]; $key = $value->accept($this, $handle, $eldnah); - if (!is_array($contextPointer)) { + $isArray = is_array($contextPointer); + $isArrayLike = !$isArray && $contextPointer instanceof ArrayAccess; + + if (false === $isArray && false === $isArrayLike) { throw new Ruler\Exception\Asserter( 'Try to access to an undefined index: %s ' . '(dimension number %d of %s), because it is ' . @@ -351,7 +355,8 @@ protected function visitArrayDimension( ); } - if (false === array_key_exists($key, $contextPointer)) { + if ((true === $isArray && false === array_key_exists($key, $contextPointer)) || + (true === $isArrayLike && false === $contextPointer->offsetExists($key))) { throw new Ruler\Exception\Asserter( 'Try to access to an undefined index: %s ' . '(dimension number %d of %s).',