diff --git a/src/Matcher/ArrayMatcher.php b/src/Matcher/ArrayMatcher.php index 1cf47187..c811ffbd 100644 --- a/src/Matcher/ArrayMatcher.php +++ b/src/Matcher/ArrayMatcher.php @@ -6,13 +6,14 @@ use Coduo\ToString\StringConverter; use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyAccessor; +use Symfony\Component\PropertyAccess\PropertyPath; final class ArrayMatcher extends Matcher { const UNBOUNDED_PATTERN = '@...@'; /** - * @var PropertyMatcher + * @var ValueMatcher */ private $propertyMatcher; @@ -147,7 +148,7 @@ private function isPatternValid(array $pattern, array $values, $parentPath) if (count($notExistingKeys) > 0) { $keyNames = array_keys($notExistingKeys); - $path = $this->formatFullPath($parentPath, $this->formatAccessPath($keyNames[0])); + $path = $this->formatFullPath($parentPath, $this->formatAccessPath($keyNames[0])); $this->setMissingElementInError('value', $path); return false; } @@ -180,7 +181,33 @@ private function valueMatchPattern($value, $pattern) */ private function valueExist($path, array $haystack) { - return null !== $this->getPropertyAccessor()->getValue($haystack, $path); + $propertyPath = new PropertyPath($path); + $length = $propertyPath->getLength(); + $valueExist = true; + for ($i = 0; $i < $length; ++$i) { + $property = $propertyPath->getElement($i); + $isIndex = $propertyPath->isIndex($i); + $propertyExist = $this->arrayPropertyExists($property, $haystack); + + if ($isIndex && !$propertyExist) { + $valueExist = false; + break; + } + } + + unset($propertyPath); + return $valueExist; + } + + /** + * @param string $property + * @param array $objectOrArray + * @return bool + */ + private function arrayPropertyExists($property, array $objectOrArray) + { + return ($objectOrArray instanceof \ArrayAccess && isset($objectOrArray[$property])) || + (is_array($objectOrArray) && array_key_exists($property, $objectOrArray)); } /** diff --git a/src/Matcher/NullMatcher.php b/src/Matcher/NullMatcher.php index f6b96038..f3e891d4 100644 --- a/src/Matcher/NullMatcher.php +++ b/src/Matcher/NullMatcher.php @@ -26,6 +26,6 @@ public function match($value, $pattern) */ public function canMatch($pattern) { - return $pattern === null || (is_string($pattern) && 0 !== preg_match(self::MATCH_PATTERN, $pattern)); + return is_null($pattern) || (is_string($pattern) && 0 !== preg_match(self::MATCH_PATTERN, $pattern)); } } diff --git a/tests/Matcher/ArrayMatcherTest.php b/tests/Matcher/ArrayMatcherTest.php index 864b5b86..eb009740 100644 --- a/tests/Matcher/ArrayMatcherTest.php +++ b/tests/Matcher/ArrayMatcherTest.php @@ -72,7 +72,7 @@ public function test_error_when_path_in_nested_pattern_does_not_exist() $array = array('foo' => array('bar' => array('baz' => 'bar value'))); $pattern = array('foo' => array('bar' => array('faz' => 'faz value'))); - $this->assertFalse($this->matcher->match($array,$pattern)); + $this->assertFalse($this->matcher->match($array, $pattern)); $this->assertEquals($this->matcher->getError(), 'There is no element under path [foo][bar][baz] in pattern.'); } @@ -124,7 +124,7 @@ public function test_matching_array_to_array_pattern() public static function positiveMatchData() { - $simpleArr = array( + $simpleArr = array( 'users' => array( array( 'firstName' => 'Norbert', @@ -141,7 +141,7 @@ public static function positiveMatchData() 6.66 ); - $simpleArrPattern = array( + $simpleArrPattern = array( 'users' => array( array( 'firstName' => '@string@', @@ -169,7 +169,7 @@ public static function positiveMatchData() public static function negativeMatchData() { - $simpleArr = array( + $simpleArr = array( 'users' => array( array( 'firstName' => 'Norbert', @@ -186,7 +186,7 @@ public static function negativeMatchData() 6.66 ); - $simpleDiff = array( + $simpleDiff = array( 'users' => array( array( 'firstName' => 'Norbert', diff --git a/tests/Matcher/JsonMatcherTest.php b/tests/Matcher/JsonMatcherTest.php index 68fcff4b..377592ef 100644 --- a/tests/Matcher/JsonMatcherTest.php +++ b/tests/Matcher/JsonMatcherTest.php @@ -161,6 +161,10 @@ public static function positiveMatches() '{"null":null}', '{"null":@null@}' ), + array( + '{"username":null,"some_data":"test"}', + '{"username":null, "some_data": @string@}' + ), array( '{"null":null}', '{"null":null}' @@ -176,7 +180,7 @@ public static function positiveMatches() array( '[{"name": "Norbert"},{"name":"MichaƂ"},{"name":"Bob"},{"name":"Martin"}]', '[{"name": "Norbert"},@...@]' - ), + ) ); }