diff --git a/composer.json b/composer.json index 221f8892..3df7478a 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,8 @@ "license": "MIT", "require": { "php": ">=5.3.0", - "symfony/property-access": "~2.3" + "symfony/property-access": "~2.3", + "symfony/expression-language": "~2.4" }, "require-dev": { "phpunit/phpunit": "3.7.*" @@ -14,7 +15,8 @@ "psr-0": { "JsonMatcher": "src/", "JsonMatcher\\Tests": "tests/" - } + }, + "files": ["match.php"] }, "config": { "bin-dir": "bin" diff --git a/match.php b/match.php new file mode 100644 index 00000000..fa26bb33 --- /dev/null +++ b/match.php @@ -0,0 +1,49 @@ +match($value, $pattern); + } +} diff --git a/src/JsonMatcher/Matcher/ExpressionMatcher.php b/src/JsonMatcher/Matcher/ExpressionMatcher.php new file mode 100644 index 00000000..4ac93545 --- /dev/null +++ b/src/JsonMatcher/Matcher/ExpressionMatcher.php @@ -0,0 +1,26 @@ +evaluate($matches[1], array('value' => $value)); + } + + /** + * {@inheritDoc} + */ + public function canMatch($pattern) + { + return is_string($pattern) && 0 !== preg_match("/^expr\((.*?)\)$/", $pattern); + } +} diff --git a/tests/JsonMatcher/Matcher/ExpressionMatcherTest.php b/tests/JsonMatcher/Matcher/ExpressionMatcherTest.php new file mode 100644 index 00000000..3bedaa59 --- /dev/null +++ b/tests/JsonMatcher/Matcher/ExpressionMatcherTest.php @@ -0,0 +1,79 @@ +assertTrue($matcher->canMatch($pattern)); + } + + /** + * @dataProvider negativeCanMatchData + */ + public function test_negative_can_matches($pattern) + { + $matcher = new ExpressionMatcher(); + $this->assertFalse($matcher->canMatch($pattern)); + } + + /** + * @dataProvider positiveMatchData + */ + public function test_positive_match($value, $pattern) + { + $matcher = new ExpressionMatcher(); + $this->assertTrue($matcher->match($value, $pattern)); + } + + /** + * @dataProvider negativeMatchData + */ + public function test_negative_match($value, $pattern) + { + $matcher = new ExpressionMatcher(); + $this->assertFalse($matcher->match($value, $pattern)); + } + + public static function positiveCanMatchData() + { + return array( + array("expr(1 > 2)"), + array("expr(value == 'foo')"), + ); + } + + public static function negativeCanMatchData() + { + return array( + array("@integer"), + array("expr("), + array("@string"), + array(new \stdClass), + array(array("foobar")) + ); + } + + public static function positiveMatchData() + { + return array( + array(4, "expr(value > 2)"), + array("foo", "expr(value == 'foo')"), + array(new \DateTime('2014-04-01'), "expr(value.format('Y-m-d') == '2014-04-01')") + ); + } + + public static function negativeMatchData() + { + return array( + array(4, "expr(value < 2)"), + array("foo", "expr(value != 'foo')"), + ); + } +} diff --git a/tests/JsonMatcher/MatcherTest.php b/tests/JsonMatcher/MatcherTest.php index 87cecfcf..595a9a22 100644 --- a/tests/JsonMatcher/MatcherTest.php +++ b/tests/JsonMatcher/MatcherTest.php @@ -3,6 +3,8 @@ use JsonMatcher\Matcher\ArrayMatcher; use JsonMatcher\Matcher\ChainMatcher; +use JsonMatcher\Matcher\ExpressionMatcher; +use JsonMatcher\Matcher\JsonMatcher; use JsonMatcher\Matcher\ScalarMatcher; use JsonMatcher\Matcher\TypeMatcher; use JsonMatcher\Matcher\WildcardMatcher; @@ -17,13 +19,18 @@ class MatcherTest extends \PHPUnit_Framework_TestCase public function setUp() { $scalarMatchers = new ChainMatcher(array( + new ExpressionMatcher(), new TypeMatcher(), new ScalarMatcher(), new WildcardMatcher() )); + + $arrayMatcher = new ArrayMatcher($scalarMatchers); + $this->matcher = new Matcher(new ChainMatcher(array( $scalarMatchers, - new ArrayMatcher($scalarMatchers) + $arrayMatcher, + new JsonMatcher($arrayMatcher) ))); $this->arrayValue = array( @@ -69,6 +76,28 @@ public function test_matcher_with_array_value() 'data' => '@wildcard@', ) )); + + $this->assertTrue(match( + $this->arrayValue, + array( + 'users' => array( + array( + 'id' => '@integer@', + 'firstName' => '@string@', + 'lastName' => 'Orzechowicz', + 'enabled' => '@boolean@' + ), + array( + 'id' => '@integer@', + 'firstName' => '@string@', + 'lastName' => 'Dąbrowski', + 'enabled' => '@boolean@', + ) + ), + 'readyToUse' => true, + 'data' => '@wildcard@', + ) + )); } public function test_matcher_with_scalar_values() @@ -77,9 +106,67 @@ public function test_matcher_with_scalar_values() 'Norbert Orzechowicz', '@string@' )); + $this->assertTrue(match( + 'Norbert Orzechowicz', + '@string@' + )); $this->assertTrue($this->matcher->match( 6.66, '@double@' )); + $this->assertTrue(match( + 6.66, + '@double@' + )); + } + + public function test_matcher_with_json() + { + $json = ' + { + "users":[ + { + "id": 131, + "firstName": "Norbert", + "lastName": "Orzechowicz", + "enabled": true, + "roles": ["ROLE_DEVELOPER"] + }, + { + "id": 132, + "firstName": "Michał", + "lastName": "Dąbrowski", + "enabled": false, + "roles": ["ROLE_DEVELOPER"] + } + ], + "prevPage": "http:\/\/example.com\/api\/users\/1?limit=2", + "nextPage": "http:\/\/example.com\/api\/users\/3?limit=2" + }'; + $jsonPattern = ' + { + "users":[ + { + "id": "@integer@", + "firstName":"Norbert", + "lastName":"Orzechowicz", + "enabled": "@boolean@", + "roles": "@array@" + }, + { + "id": "@integer@", + "firstName": "Michał", + "lastName": "Dąbrowski", + "enabled": "expr(value == false)", + "roles": "@array@" + } + ], + "prevPage": "@string@", + "nextPage": "@string@" + }'; + + + $this->assertTrue($this->matcher->match($json, $jsonPattern)); + $this->assertTrue(match($json, $jsonPattern)); } }