Skip to content

Commit 0cef84a

Browse files
committed
Merge pull request #3 from norzechowicz/dev
match global function
2 parents b817283 + d1e1a41 commit 0cef84a

File tree

5 files changed

+246
-3
lines changed

5 files changed

+246
-3
lines changed

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"license": "MIT",
66
"require": {
77
"php": ">=5.3.0",
8-
"symfony/property-access": "~2.3"
8+
"symfony/property-access": "~2.3",
9+
"symfony/expression-language": "~2.4"
910
},
1011
"require-dev": {
1112
"phpunit/phpunit": "3.7.*"
@@ -14,7 +15,8 @@
1415
"psr-0": {
1516
"JsonMatcher": "src/",
1617
"JsonMatcher\\Tests": "tests/"
17-
}
18+
},
19+
"files": ["match.php"]
1820
},
1921
"config": {
2022
"bin-dir": "bin"

match.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
use JsonMatcher\Matcher\ArrayMatcher;
4+
use JsonMatcher\Matcher\ChainMatcher;
5+
use JsonMatcher\Matcher\ExpressionMatcher;
6+
use JsonMatcher\Matcher\JsonMatcher;
7+
use JsonMatcher\Matcher\ScalarMatcher;
8+
use JsonMatcher\Matcher\TypeMatcher;
9+
use JsonMatcher\Matcher\WildcardMatcher;
10+
use JsonMatcher\Matcher;
11+
12+
if (is_dir($vendor = __DIR__ . '/../vendor')) {
13+
require_once($vendor . '/autoload.php');
14+
} elseif (is_dir($vendor = __DIR__ . '/../../../vendor')) {
15+
require_once($vendor . '/autoload.php');
16+
} elseif (is_dir($vendor = __DIR__ . '/vendor')) {
17+
require_once($vendor . '/autoload.php');
18+
} else {
19+
die(
20+
'You must set up the project dependencies, run the following commands:' . PHP_EOL .
21+
'curl -s http://getcomposer.org/installer | php' . PHP_EOL .
22+
'php composer.phar install' . PHP_EOL
23+
);
24+
}
25+
26+
if (!function_exists('match')) {
27+
/**
28+
* @param mixed $value
29+
* @param mixed $pattern
30+
* @return boolean
31+
*/
32+
function match($value, $pattern)
33+
{
34+
$scalarMatchers = new ChainMatcher(array(
35+
new ExpressionMatcher(),
36+
new TypeMatcher(),
37+
new ScalarMatcher(),
38+
new WildcardMatcher()
39+
));
40+
$arrayMatcher = new ArrayMatcher($scalarMatchers);
41+
$matcher = new Matcher(new ChainMatcher(array(
42+
$scalarMatchers,
43+
$arrayMatcher,
44+
new JsonMatcher($arrayMatcher)
45+
)));
46+
47+
return $matcher->match($value, $pattern);
48+
}
49+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace JsonMatcher\Matcher;
4+
5+
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
6+
7+
class ExpressionMatcher implements PropertyMatcher
8+
{
9+
/**
10+
* {@inheritDoc}
11+
*/
12+
public function match($value, $pattern)
13+
{
14+
$language = new ExpressionLanguage();
15+
preg_match("/^expr\((.*?)\)$/", $pattern, $matches);
16+
return $language->evaluate($matches[1], array('value' => $value));
17+
}
18+
19+
/**
20+
* {@inheritDoc}
21+
*/
22+
public function canMatch($pattern)
23+
{
24+
return is_string($pattern) && 0 !== preg_match("/^expr\((.*?)\)$/", $pattern);
25+
}
26+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
namespace JsonMatcher\Tests\Matcher;
3+
4+
use JsonMatcher\Matcher\ExpressionMatcher;
5+
6+
class ExpressionMatcherTest extends \PHPUnit_Framework_TestCase
7+
{
8+
/**
9+
* @dataProvider positiveCanMatchData
10+
*/
11+
public function test_positive_can_matches($pattern)
12+
{
13+
$matcher = new ExpressionMatcher();
14+
$this->assertTrue($matcher->canMatch($pattern));
15+
}
16+
17+
/**
18+
* @dataProvider negativeCanMatchData
19+
*/
20+
public function test_negative_can_matches($pattern)
21+
{
22+
$matcher = new ExpressionMatcher();
23+
$this->assertFalse($matcher->canMatch($pattern));
24+
}
25+
26+
/**
27+
* @dataProvider positiveMatchData
28+
*/
29+
public function test_positive_match($value, $pattern)
30+
{
31+
$matcher = new ExpressionMatcher();
32+
$this->assertTrue($matcher->match($value, $pattern));
33+
}
34+
35+
/**
36+
* @dataProvider negativeMatchData
37+
*/
38+
public function test_negative_match($value, $pattern)
39+
{
40+
$matcher = new ExpressionMatcher();
41+
$this->assertFalse($matcher->match($value, $pattern));
42+
}
43+
44+
public static function positiveCanMatchData()
45+
{
46+
return array(
47+
array("expr(1 > 2)"),
48+
array("expr(value == 'foo')"),
49+
);
50+
}
51+
52+
public static function negativeCanMatchData()
53+
{
54+
return array(
55+
array("@integer"),
56+
array("expr("),
57+
array("@string"),
58+
array(new \stdClass),
59+
array(array("foobar"))
60+
);
61+
}
62+
63+
public static function positiveMatchData()
64+
{
65+
return array(
66+
array(4, "expr(value > 2)"),
67+
array("foo", "expr(value == 'foo')"),
68+
array(new \DateTime('2014-04-01'), "expr(value.format('Y-m-d') == '2014-04-01')")
69+
);
70+
}
71+
72+
public static function negativeMatchData()
73+
{
74+
return array(
75+
array(4, "expr(value < 2)"),
76+
array("foo", "expr(value != 'foo')"),
77+
);
78+
}
79+
}

tests/JsonMatcher/MatcherTest.php

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
use JsonMatcher\Matcher\ArrayMatcher;
55
use JsonMatcher\Matcher\ChainMatcher;
6+
use JsonMatcher\Matcher\ExpressionMatcher;
7+
use JsonMatcher\Matcher\JsonMatcher;
68
use JsonMatcher\Matcher\ScalarMatcher;
79
use JsonMatcher\Matcher\TypeMatcher;
810
use JsonMatcher\Matcher\WildcardMatcher;
@@ -17,13 +19,18 @@ class MatcherTest extends \PHPUnit_Framework_TestCase
1719
public function setUp()
1820
{
1921
$scalarMatchers = new ChainMatcher(array(
22+
new ExpressionMatcher(),
2023
new TypeMatcher(),
2124
new ScalarMatcher(),
2225
new WildcardMatcher()
2326
));
27+
28+
$arrayMatcher = new ArrayMatcher($scalarMatchers);
29+
2430
$this->matcher = new Matcher(new ChainMatcher(array(
2531
$scalarMatchers,
26-
new ArrayMatcher($scalarMatchers)
32+
$arrayMatcher,
33+
new JsonMatcher($arrayMatcher)
2734
)));
2835

2936
$this->arrayValue = array(
@@ -69,6 +76,28 @@ public function test_matcher_with_array_value()
6976
'data' => '@wildcard@',
7077
)
7178
));
79+
80+
$this->assertTrue(match(
81+
$this->arrayValue,
82+
array(
83+
'users' => array(
84+
array(
85+
'id' => '@integer@',
86+
'firstName' => '@string@',
87+
'lastName' => 'Orzechowicz',
88+
'enabled' => '@boolean@'
89+
),
90+
array(
91+
'id' => '@integer@',
92+
'firstName' => '@string@',
93+
'lastName' => 'Dąbrowski',
94+
'enabled' => '@boolean@',
95+
)
96+
),
97+
'readyToUse' => true,
98+
'data' => '@wildcard@',
99+
)
100+
));
72101
}
73102

74103
public function test_matcher_with_scalar_values()
@@ -77,9 +106,67 @@ public function test_matcher_with_scalar_values()
77106
'Norbert Orzechowicz',
78107
'@string@'
79108
));
109+
$this->assertTrue(match(
110+
'Norbert Orzechowicz',
111+
'@string@'
112+
));
80113
$this->assertTrue($this->matcher->match(
81114
6.66,
82115
'@double@'
83116
));
117+
$this->assertTrue(match(
118+
6.66,
119+
'@double@'
120+
));
121+
}
122+
123+
public function test_matcher_with_json()
124+
{
125+
$json = '
126+
{
127+
"users":[
128+
{
129+
"id": 131,
130+
"firstName": "Norbert",
131+
"lastName": "Orzechowicz",
132+
"enabled": true,
133+
"roles": ["ROLE_DEVELOPER"]
134+
},
135+
{
136+
"id": 132,
137+
"firstName": "Michał",
138+
"lastName": "Dąbrowski",
139+
"enabled": false,
140+
"roles": ["ROLE_DEVELOPER"]
141+
}
142+
],
143+
"prevPage": "http:\/\/example.com\/api\/users\/1?limit=2",
144+
"nextPage": "http:\/\/example.com\/api\/users\/3?limit=2"
145+
}';
146+
$jsonPattern = '
147+
{
148+
"users":[
149+
{
150+
"id": "@integer@",
151+
"firstName":"Norbert",
152+
"lastName":"Orzechowicz",
153+
"enabled": "@boolean@",
154+
"roles": "@array@"
155+
},
156+
{
157+
"id": "@integer@",
158+
"firstName": "Michał",
159+
"lastName": "Dąbrowski",
160+
"enabled": "expr(value == false)",
161+
"roles": "@array@"
162+
}
163+
],
164+
"prevPage": "@string@",
165+
"nextPage": "@string@"
166+
}';
167+
168+
169+
$this->assertTrue($this->matcher->match($json, $jsonPattern));
170+
$this->assertTrue(match($json, $jsonPattern));
84171
}
85172
}

0 commit comments

Comments
 (0)