diff --git a/src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php b/src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php index 82eacb66..6eea68ec 100644 --- a/src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php +++ b/src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php @@ -49,15 +49,16 @@ public function canMatch($pattern) /** * @param array $value * @param array $pattern + * @param string $parentPath * @return bool */ - private function iterateMatch(array $value, array $pattern) + private function iterateMatch(array $value, array $pattern, $parentPath = "") { foreach ($value as $key => $element) { $path = sprintf("[%s]", $key); if (!$this->hasValue($pattern, $path)) { - $this->error = sprintf('There is no element under path %s in pattern array.', $path); + $this->error = sprintf('There is no element under path %s%s in pattern.', $parentPath, $path); return false; } $elementPattern = $this->getValue($pattern, $path); @@ -72,20 +73,12 @@ private function iterateMatch(array $value, array $pattern) return false; } - if (false === $this->iterateMatch($element, $elementPattern)) { + if (false === $this->iterateMatch($element, $elementPattern, $parentPath . $path)) { return false; } } - if(is_array($pattern)) { - $notExistingKeys = array_diff_key($pattern, $value); - - if (count($notExistingKeys) > 0) { - $keyNames = array_keys($notExistingKeys); - $this->error = sprintf('There is no element under path [%s] in value array.', $keyNames[0]); - return false; - } - } + return $this->checkIfPathsFromPatternExistInValue($value, $pattern, $parentPath); } /** @@ -122,4 +115,25 @@ private function getPropertyAccessor() return $this->accessor; } + + /** + * @param array $value + * @param array $pattern + * @param $parentPath + * @return bool + */ + private function checkIfPathsFromPatternExistInValue(array $value, array $pattern, $parentPath) + { + if (is_array($pattern)) { + $notExistingKeys = array_diff_key($pattern, $value); + + if (count($notExistingKeys) > 0) { + $keyNames = array_keys($notExistingKeys); + $this->error = sprintf('There is no element under path %s[%s] in value.', $parentPath, $keyNames[0]); + return false; + } + } + + return true; + } } diff --git a/tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php b/tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php index ef48e0ea..766a4fd1 100644 --- a/tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php +++ b/tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php @@ -50,16 +50,40 @@ public function test_negative_match_when_cant_find_matcher_that_can_match_array_ $this->assertFalse($matcher->match(array('test' => 1), array('test' => 1))); } - public function test_error_when_path_does_not_exist() + public function test_error_when_path_in_pattern_does_not_exist() { $this->assertFalse($this->matcher->match(array('foo' => 'foo value'), array('bar' => 'bar value'))); - $this->assertEquals($this->matcher->getError(), 'There is no element under path [foo] in pattern array.'); + $this->assertEquals($this->matcher->getError(), 'There is no element under path [foo] in pattern.'); + } + + 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->assertEquals($this->matcher->getError(), 'There is no element under path [foo][bar][baz] in pattern.'); } public function test_error_when_path_in_value_does_not_exist() { - $this->assertFalse($this->matcher->match(array('foo' => 'foo'), array('foo' => 'foo', 'bar' => 'bar'))); - $this->assertEquals($this->matcher->getError(), 'There is no element under path [bar] in value array.'); + $array = array('foo' => 'foo'); + $pattern = array('foo' => 'foo', 'bar' => 'bar'); + + $this->assertFalse($this->matcher->match($array, $pattern)); + + $this->assertEquals($this->matcher->getError(), 'There is no element under path [bar] in value.'); + } + + public function test_error_when_path_in_nested_value_does_not_exist() + { + $array = array('foo' => array('bar' => array())); + $pattern = array('foo' => array('bar' => array('faz' => 'faz value'))); + + $this->assertFalse($this->matcher->match($array, $pattern)); + + $this->assertEquals($this->matcher->getError(), 'There is no element under path [foo][bar][faz] in value.'); } public function test_error_when_matching_fail() @@ -142,5 +166,4 @@ public static function negativeMatchData() array(array(), array('foo' => 'bar')) ); } - } diff --git a/tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php b/tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php index fe36dbb7..53a03a7c 100644 --- a/tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php +++ b/tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php @@ -79,6 +79,26 @@ public function test_error_when_matching_fail() $this->assertEquals($this->matcher->getError(), '"MichaƂ" does not match "@boolean@".'); } + public function test_error_when_path_in_nested_pattern_does_not_exist() + { + $value = json_encode(array('foo' => array('bar' => array('baz' => 'bar value')))); + $pattern = json_encode(array('foo' => array('bar' => array('faz' => 'faz value')))); + + $this->assertFalse($this->matcher->match($value, $pattern)); + + $this->assertEquals($this->matcher->getError(), 'There is no element under path [foo][bar][baz] in pattern.'); + } + + public function test_error_when_path_in_nested_value_does_not_exist() + { + $value = json_encode(array('foo' => array('bar' => array()))); + $pattern = json_encode(array('foo' => array('bar' => array('faz' => 'faz value')))); + + $this->assertFalse($this->matcher->match($value, $pattern)); + + $this->assertEquals($this->matcher->getError(), 'There is no element under path [foo][bar][faz] in value.'); + } + public static function positivePatterns() { return array(