Skip to content

Commit 85e6c89

Browse files
Gameshnorberttech
authored andcommitted
Allow @...@ to match none or more elements (#97)
* fixes issue #72 - unbound array matches none or more elements * added tests cases for MatcherTest - test_matcher_with_json
1 parent 4c4e6b1 commit 85e6c89

File tree

3 files changed

+151
-53
lines changed

3 files changed

+151
-53
lines changed

src/Matcher/ArrayMatcher.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ private function iterateMatch(array $values, array $patterns, $parentPath = "")
144144
private function isPatternValid(array $pattern, array $values, $parentPath)
145145
{
146146
if (is_array($pattern)) {
147+
$skipPattern = static::UNBOUNDED_PATTERN;
148+
149+
$pattern = array_filter(
150+
$pattern,
151+
function ($item) use ($skipPattern) {
152+
return $item !== $skipPattern;
153+
}
154+
);
155+
147156
$notExistingKeys = array_diff_key($pattern, $values);
148157

149158
if (count($notExistingKeys) > 0) {

tests/Matcher/ArrayMatcherTest.php

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public static function positiveMatchData()
147147
'firstName' => '@string@',
148148
'lastName' => '@string@'
149149
),
150-
'@...@'
150+
Matcher\ArrayMatcher::UNBOUNDED_PATTERN
151151
),
152152
true,
153153
false,
@@ -163,7 +163,25 @@ public static function positiveMatchData()
163163
array(array('foo' => null), array('foo' => "@null@")),
164164
array(array('key' => 'val'), array('key' => 'val')),
165165
array(array(1), array(1)),
166-
array(array('roles' => array('ROLE_ADMIN', 'ROLE_DEVELOPER')), array('roles' => '@wildcard@'))
166+
array(
167+
array('roles' => array('ROLE_ADMIN', 'ROLE_DEVELOPER')),
168+
array('roles' => '@wildcard@'),
169+
),
170+
'unbound array should match one or none elements' => array(
171+
array(
172+
'users' => array(
173+
array(
174+
'firstName' => 'Norbert',
175+
'lastName' => 'Foobar',
176+
),
177+
),
178+
true,
179+
false,
180+
1,
181+
6.66,
182+
),
183+
$simpleArrPattern,
184+
),
167185
);
168186
}
169187

@@ -210,7 +228,22 @@ public static function negativeMatchData()
210228
array(array('key' => 'val'), array('key' => 'val2')),
211229
array(array(1), array(2)),
212230
array(array('foo', 1, 3), array('foo', 2, 3)),
213-
array(array(), array('foo' => 'bar'))
231+
array(array(), array('foo' => 'bar')),
232+
'unbound array should match one or none elements' => array(
233+
array(
234+
'users' => array(
235+
array(
236+
'firstName' => 'Norbert',
237+
'lastName' => 'Foobar',
238+
),
239+
),
240+
true,
241+
false,
242+
1,
243+
6.66,
244+
),
245+
$simpleDiff,
246+
),
214247
);
215248
}
216249
}

tests/MatcherTest.php

Lines changed: 106 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Coduo\PHPMatcher\Factory\SimpleFactory;
66
use Coduo\PHPMatcher\Matcher;
7-
use Coduo\PHPMatcher\Parser;
87
use Coduo\PHPMatcher\PHPMatcher;
98

109
class MatcherTest extends \PHPUnit\Framework\TestCase
@@ -28,14 +27,14 @@ public function test_matcher_with_array_value()
2827
'id' => 1,
2928
'firstName' => 'Norbert',
3029
'lastName' => 'Orzechowicz',
31-
'enabled' => true
30+
'enabled' => true,
3231
),
3332
array(
3433
'id' => 2,
3534
'firstName' => 'Michał',
3635
'lastName' => 'Dąbrowski',
3736
'enabled' => true,
38-
)
37+
),
3938
),
4039
'readyToUse' => true,
4140
'data' => new \stdClass(),
@@ -47,14 +46,14 @@ public function test_matcher_with_array_value()
4746
'id' => '@integer@',
4847
'firstName' => '@string@',
4948
'lastName' => 'Orzechowicz',
50-
'enabled' => '@boolean@'
49+
'enabled' => '@boolean@',
5150
),
5251
array(
5352
'id' => '@integer@',
5453
'firstName' => '@string@',
5554
'lastName' => 'Dąbrowski',
5655
'enabled' => '@boolean@',
57-
)
56+
),
5857
),
5958
'readyToUse' => true,
6059
'data' => '@wildcard@',
@@ -73,55 +72,112 @@ public function test_matcher_with_scalar_values($value, $pattern)
7372
$this->assertTrue(PHPMatcher::match($value, $pattern));
7473
}
7574

76-
public function test_matcher_with_json()
75+
/**
76+
* @dataProvider jsonDataProvider
77+
*/
78+
public function test_matcher_with_json($json, $jsonPattern)
7779
{
78-
$json = '
79-
{
80-
"users":[
81-
{
82-
"id": 131,
83-
"firstName": "Norbert",
84-
"lastName": "Orzechowicz",
85-
"enabled": true,
86-
"roles": ["ROLE_DEVELOPER"]
87-
},
88-
{
89-
"id": 132,
90-
"firstName": "Michał",
91-
"lastName": "Dąbrowski",
92-
"enabled": false,
93-
"roles": ["ROLE_DEVELOPER"]
94-
}
95-
],
96-
"prevPage": "http:\/\/example.com\/api\/users\/1?limit=2",
97-
"nextPage": "http:\/\/example.com\/api\/users\/3?limit=2"
98-
}';
99-
$jsonPattern = '
100-
{
101-
"users":[
102-
{
103-
"id": "@integer@",
104-
"firstName":"Norbert",
105-
"lastName":"Orzechowicz",
106-
"enabled": "@boolean@",
107-
"roles": "@array@"
108-
},
109-
{
110-
"id": "@integer@",
111-
"firstName": "Michał",
112-
"lastName": "Dąbrowski",
113-
"enabled": "expr(value == false)",
114-
"roles": "@array@"
115-
}
116-
],
117-
"prevPage": "@string@",
118-
"nextPage": "@string@"
119-
}';
120-
12180
$this->assertTrue($this->matcher->match($json, $jsonPattern));
12281
$this->assertTrue(PHPMatcher::match($json, $jsonPattern));
12382
}
12483

84+
public function jsonDataProvider()
85+
{
86+
return array(
87+
'matches exactly' => array(
88+
/** @lang JSON */
89+
'{
90+
"users":[
91+
{
92+
"id": 131,
93+
"firstName": "Norbert",
94+
"lastName": "Orzechowicz",
95+
"enabled": true,
96+
"roles": ["ROLE_DEVELOPER"]
97+
},
98+
{
99+
"id": 132,
100+
"firstName": "Michał",
101+
"lastName": "Dąbrowski",
102+
"enabled": false,
103+
"roles": ["ROLE_DEVELOPER"]
104+
}
105+
],
106+
"prevPage": "http:\/\/example.com\/api\/users\/1?limit=2",
107+
"nextPage": "http:\/\/example.com\/api\/users\/3?limit=2"
108+
}',
109+
/** @lang JSON */
110+
'{
111+
"users":[
112+
{
113+
"id": "@integer@",
114+
"firstName":"Norbert",
115+
"lastName":"Orzechowicz",
116+
"enabled": "@boolean@",
117+
"roles": "@array@"
118+
},
119+
{
120+
"id": "@integer@",
121+
"firstName": "Michał",
122+
"lastName": "Dąbrowski",
123+
"enabled": "expr(value == false)",
124+
"roles": "@array@"
125+
}
126+
],
127+
"prevPage": "@string@",
128+
"nextPage": "@string@"
129+
}',
130+
),
131+
'matches none elements - empty array' => array(
132+
/** @lang JSON */
133+
'{
134+
"users":[],
135+
"prevPage": "http:\/\/example.com\/api\/users\/1?limit=2",
136+
"nextPage": "http:\/\/example.com\/api\/users\/3?limit=2"
137+
}',
138+
/** @lang JSON */
139+
'{
140+
"users":[
141+
"@...@"
142+
],
143+
"prevPage": "@string@",
144+
"nextPage": "@string@"
145+
}',
146+
),
147+
'matches one element' => array(
148+
/** @lang JSON */
149+
'{
150+
"users":[
151+
{
152+
"id": 131,
153+
"firstName": "Norbert",
154+
"lastName": "Orzechowicz",
155+
"enabled": true,
156+
"roles": ["ROLE_DEVELOPER"]
157+
}
158+
],
159+
"prevPage": "http:\/\/example.com\/api\/users\/1?limit=2",
160+
"nextPage": "http:\/\/example.com\/api\/users\/3?limit=2"
161+
}',
162+
/** @lang JSON */
163+
'{
164+
"users":[
165+
{
166+
"id": "@integer@",
167+
"firstName":"Norbert",
168+
"lastName":"Orzechowicz",
169+
"enabled": "@boolean@",
170+
"roles": "@array@"
171+
},
172+
"@...@"
173+
],
174+
"prevPage": "@string@",
175+
"nextPage": "@string@"
176+
}',
177+
),
178+
);
179+
}
180+
125181
public function test_matcher_with_xml()
126182
{
127183
$xml = <<<XML
@@ -284,7 +340,7 @@ public static function nullExamples()
284340
'{"proformaInvoiceLink":null}', '{"proformaInvoiceLink":null}',
285341
'{"proformaInvoiceLink":null, "test":"test"}', '{"proformaInvoiceLink":null, "test":"@string@"}',
286342
'{"proformaInvoiceLink":null, "test":"test"}', '{"proformaInvoiceLink":@null@, "test":"@string@"}',
287-
)
343+
),
288344
);
289345
}
290346
}

0 commit comments

Comments
 (0)