diff --git a/src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php b/src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php index 6eea68ec..df89d9a3 100644 --- a/src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php +++ b/src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php @@ -7,6 +7,8 @@ class ArrayMatcher extends Matcher { + const UNBOUNDED_PATTERN = '@...@'; + /** * @var PropertyMatcher */ @@ -54,21 +56,33 @@ public function canMatch($pattern) */ private function iterateMatch(array $value, array $pattern, $parentPath = "") { + $lastPattern = array_values($pattern); + $unboundedMode = end($lastPattern) === self::UNBOUNDED_PATTERN; + + if ($unboundedMode) { + $unboundedPattern = prev($lastPattern); + array_pop($pattern); + } + foreach ($value as $key => $element) { $path = sprintf("[%s]", $key); - if (!$this->hasValue($pattern, $path)) { + if ($this->hasValue($pattern, $path)) { + $elementPattern = $this->getValue($pattern, $path); + } else if ($unboundedMode) { + $elementPattern = $unboundedPattern; + } else { $this->error = sprintf('There is no element under path %s%s in pattern.', $parentPath, $path); return false; } - $elementPattern = $this->getValue($pattern, $path); + if ($this->propertyMatcher->canMatch($elementPattern)) { if (true === $this->propertyMatcher->match($element, $elementPattern)) { continue; } } - if (!is_array($element)) { + if (!is_array($element) || !is_array($elementPattern)) { $this->error = $this->propertyMatcher->getError(); return false; } diff --git a/src/Coduo/PHPMatcher/Matcher/JsonMatcher.php b/src/Coduo/PHPMatcher/Matcher/JsonMatcher.php index a8294843..00537b17 100644 --- a/src/Coduo/PHPMatcher/Matcher/JsonMatcher.php +++ b/src/Coduo/PHPMatcher/Matcher/JsonMatcher.php @@ -4,7 +4,7 @@ class JsonMatcher extends Matcher { - const TRANSFORM_QUOTATION_PATTERN = '/([^"])@(integer|string|array|double|wildcard|boolean|null)@([^"])/'; + const TRANSFORM_QUOTATION_PATTERN = '/([^"])@(integer|string|array|double|wildcard|boolean|\.\.\.|null)@([^"])/'; const TRANSFORM_QUOTATION_REPLACEMENT = '$1"@$2@"$3'; /** diff --git a/tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php b/tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php index 766a4fd1..9db75b43 100644 --- a/tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php +++ b/tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php @@ -4,6 +4,7 @@ use Coduo\PHPMatcher\Matcher\ArrayMatcher; use Coduo\PHPMatcher\Matcher\ChainMatcher; use Coduo\PHPMatcher\Matcher\ScalarMatcher; +use Coduo\PHPMatcher\Matcher\TypeMatcher; use Coduo\PHPMatcher\Matcher\WildcardMatcher; class ArrayMatcherTest extends \PHPUnit_Framework_TestCase @@ -18,6 +19,7 @@ public function setUp() $this->matcher = new ArrayMatcher( new ChainMatcher(array( new ScalarMatcher(), + new TypeMatcher(), new WildcardMatcher() )) ); @@ -111,8 +113,23 @@ public static function positiveMatchData() 6.66 ); + $simpleArrPattern = array( + 'users' => array( + array( + 'firstName' => '@string@', + 'lastName' => '@string@' + ), + '@...@' + ), + true, + false, + 1, + 6.66 + ); + return array( array($simpleArr, $simpleArr), + array($simpleArr, $simpleArrPattern), array(array(), array()), array(array('key' => 'val'), array('key' => 'val')), array(array(1), array(1)), diff --git a/tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php b/tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php index 83e72077..47f54e1c 100644 --- a/tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php +++ b/tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php @@ -125,6 +125,14 @@ public static function positiveMatches() '{"users":["Norbert","Michał"]}', '{"users":["@string@","@string@"]}' ), + array( + '{"users":["Norbert","Michał"]}', + '{"users":["@string@","@...@"]}' + ), + array( + '{"users":["Norbert","Michał"]}', + '{"users":["@string@",@...@]}' + ), array( '{"numbers":[1,2]}', '{"numbers":[@integer@, @integer@]}' @@ -151,6 +159,14 @@ public static function negativeMatches() '{"users":["Norbert","Michał"]}', '{"users":["Michał","@string@"]}' ), + array( + '{"users":["Norbert","Michał", "John"], "stuff": [1, 2, 3]}', + '{"users":["@string@", @...@], "stuff": [1, 2]}' + ), + array( + '{"users":["Norbert","Michał", []]}', + '{"users":["@string@", @...@]}' + ), array( '{this_is_not_valid_json', '{"users":["Michał","@string@"]}'