Skip to content

Commit b586f9c

Browse files
committed
Added InArray expander
1 parent 87df512 commit b586f9c

File tree

8 files changed

+160
-12
lines changed

8 files changed

+160
-12
lines changed

src/Coduo/PHPMatcher/Factory/SimpleFactory.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function createMatcher()
2323
protected function buildMatchers()
2424
{
2525
$scalarMatchers = $this->buildScalarMatchers();
26-
$arrayMatcher = new Matcher\ArrayMatcher($scalarMatchers);
26+
$arrayMatcher = new Matcher\ArrayMatcher($scalarMatchers, $this->buildParser());
2727

2828
return new Matcher\ChainMatcher(array(
2929
$scalarMatchers,
@@ -37,7 +37,7 @@ protected function buildMatchers()
3737
*/
3838
protected function buildScalarMatchers()
3939
{
40-
$parser = new Parser(new Lexer());
40+
$parser = $this->buildParser();
4141

4242
return new Matcher\ChainMatcher(array(
4343
new Matcher\CallbackMatcher(),
@@ -52,4 +52,12 @@ protected function buildScalarMatchers()
5252
new Matcher\WildcardMatcher()
5353
));
5454
}
55+
56+
/**
57+
* @return Parser
58+
*/
59+
protected function buildParser()
60+
{
61+
return new Parser(new Lexer());
62+
}
5563
}

src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22

33
namespace Coduo\PHPMatcher\Matcher;
44

5+
use Coduo\PHPMatcher\Parser;
56
use Coduo\ToString\String;
67
use Symfony\Component\PropertyAccess\PropertyAccess;
78
use Symfony\Component\PropertyAccess\PropertyAccessor;
89

910
class ArrayMatcher extends Matcher
1011
{
11-
const ARRAY_PATTERN = "/^@array@$/";
12-
1312
const UNBOUNDED_PATTERN = '@...@';
1413

1514
/**
@@ -22,12 +21,18 @@ class ArrayMatcher extends Matcher
2221
*/
2322
private $accessor;
2423

24+
/**
25+
* @var Parser
26+
*/
27+
private $parser;
28+
2529
/**
2630
* @param ValueMatcher $propertyMatcher
2731
*/
28-
public function __construct(ValueMatcher $propertyMatcher)
32+
public function __construct(ValueMatcher $propertyMatcher, Parser $parser)
2933
{
3034
$this->propertyMatcher = $propertyMatcher;
35+
$this->parser = $parser;
3136
}
3237

3338
/**
@@ -41,7 +46,7 @@ public function match($value, $pattern)
4146
}
4247

4348
if ($this->isArrayPattern($pattern)) {
44-
return true;
49+
return $this->allExpandersMatch($value, $pattern);
4550
}
4651

4752
if (false === $this->iterateMatch($value, $pattern)) {
@@ -61,7 +66,11 @@ public function canMatch($pattern)
6166

6267
private function isArrayPattern($pattern)
6368
{
64-
return is_string($pattern) && 0 !== preg_match(self::ARRAY_PATTERN, $pattern);
69+
if (!is_string($pattern)) {
70+
return false;
71+
}
72+
73+
return $this->parser->hasValidSyntax($pattern) && $this->parser->parse($pattern)->is('array');
6574
}
6675

6776
/**
@@ -100,6 +109,10 @@ private function iterateMatch(array $values, array $patterns, $parentPath = "")
100109
}
101110

102111
if ($this->isArrayPattern($pattern)) {
112+
if (!$this->allExpandersMatch($value, $pattern)) {
113+
return false;
114+
}
115+
103116
continue;
104117
}
105118

@@ -227,4 +240,21 @@ private function shouldSkippValueMatchingFor($lastPattern)
227240
{
228241
return $lastPattern === self::UNBOUNDED_PATTERN;
229242
}
243+
244+
/**
245+
* @param $value
246+
* @param $pattern
247+
* @return bool
248+
* @throws \Coduo\PHPMatcher\Exception\UnknownExpanderException
249+
*/
250+
private function allExpandersMatch($value, $pattern)
251+
{
252+
$typePattern = $this->parser->parse($pattern);
253+
if (!$typePattern->matchExpanders($value)) {
254+
$this->error = $typePattern->getError();
255+
return false;
256+
}
257+
258+
return true;
259+
}
230260
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Coduo\PHPMatcher\Matcher\Pattern\Expander;
4+
5+
use Coduo\PHPMatcher\Matcher\Pattern\PatternExpander;
6+
use Coduo\ToString\String;
7+
8+
class InArray implements PatternExpander
9+
{
10+
/**
11+
* @var null|string
12+
*/
13+
private $error;
14+
15+
/**
16+
* @var
17+
*/
18+
private $value;
19+
20+
/**
21+
* @param $value
22+
*/
23+
public function __construct($value)
24+
{
25+
$this->value = $value;
26+
}
27+
28+
/**
29+
* @param $value
30+
* @return boolean
31+
*/
32+
public function match($value)
33+
{
34+
if (!is_array($value)) {
35+
$this->error = sprintf("InArray expander require \"array\", got \"%s\".", new String($value));
36+
return false;
37+
}
38+
39+
if (!in_array($this->value, $value, true)) {
40+
$this->error = sprintf("%s doesn't have \"%s\" element.", new String($value), new String($this->value));
41+
return false;
42+
}
43+
44+
return true;
45+
}
46+
47+
/**
48+
* @return string|null
49+
*/
50+
public function getError()
51+
{
52+
return $this->error;
53+
}
54+
}

src/Coduo/PHPMatcher/Parser.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ class Parser
2727
"endsWith" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\EndsWith",
2828
"notEmpty" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\NotEmpty",
2929
"lowerThan" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\LowerThan",
30-
"greaterThan" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\GreaterThan"
30+
"greaterThan" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\GreaterThan",
31+
"inArray" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\InArray"
3132
);
3233

3334
/**

tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public function setUp()
2828
new Matcher\NumberMatcher(),
2929
new Matcher\ScalarMatcher(),
3030
new Matcher\WildcardMatcher(),
31-
))
31+
)),
32+
$parser
3233
);
3334
}
3435

@@ -53,7 +54,8 @@ public function test_negative_match_when_cant_find_matcher_that_can_match_array_
5354
$matcher = new Matcher\ArrayMatcher(
5455
new Matcher\ChainMatcher(array(
5556
new Matcher\WildcardMatcher()
56-
))
57+
)),
58+
$parser = new Parser(new Lexer())
5759
);
5860

5961
$this->assertFalse($matcher->match(array('test' => 1), array('test' => 1)));
@@ -110,6 +112,14 @@ public function test_error_message_when_matching_non_array_value()
110112
public function test_matching_array_to_array_pattern()
111113
{
112114
$this->assertTrue($this->matcher->match(array("foo", "bar"), "@array@"));
115+
$this->assertTrue($this->matcher->match(array("foo"), "@[email protected](\"foo\")"));
116+
$this->assertTrue($this->matcher->match(
117+
array("foo", array("bar")),
118+
array(
119+
"@string@",
120+
"@[email protected](\"bar\")"
121+
)
122+
));
113123
}
114124

115125
public static function positiveMatchData()

tests/Coduo/PHPMatcher/Matcher/JsonMatcherTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function setUp()
3030
));
3131
$this->matcher = new Matcher\JsonMatcher(new Matcher\ChainMatcher(array(
3232
$scalarMatchers,
33-
new Matcher\ArrayMatcher($scalarMatchers)
33+
new Matcher\ArrayMatcher($scalarMatchers, $parser)
3434
)));
3535
}
3636

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace Coduo\PHPMatcher\Tests\Matcher\Pattern\Expander;
4+
5+
use Coduo\PHPMatcher\Matcher;
6+
use Coduo\PHPMatcher\Matcher\Pattern\Expander\InArray;
7+
8+
class InArrayTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @dataProvider examplesProvider
12+
*/
13+
public function test_matching_values($needle, $haystack, $expectedResult)
14+
{
15+
$expander = new InArray($needle);
16+
$this->assertEquals($expectedResult, $expander->match($haystack));
17+
}
18+
19+
public static function examplesProvider()
20+
{
21+
return array(
22+
array("ipsum", array("ipsum"), true),
23+
array(1, array("foo", 1), true),
24+
array(array("foo" => "bar"), array(array("foo" => "bar")), true),
25+
);
26+
}
27+
28+
/**
29+
* @dataProvider invalidCasesProvider
30+
*/
31+
public function test_error_when_matching_fail($boundary, $value, $errorMessage)
32+
{
33+
$expander = new InArray($boundary);
34+
$this->assertFalse($expander->match($value));
35+
$this->assertEquals($errorMessage, $expander->getError());
36+
}
37+
38+
public static function invalidCasesProvider()
39+
{
40+
return array(
41+
array("ipsum", array("ipsum lorem"), "Array(1) doesn't have \"ipsum\" element."),
42+
array("lorem", new \DateTime(), "InArray expander require \"array\", got \"\\DateTime\"."),
43+
);
44+
}
45+
}

tests/Coduo/PHPMatcher/MatcherTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function setUp()
3434
new Matcher\WildcardMatcher(),
3535
));
3636

37-
$arrayMatcher = new Matcher\ArrayMatcher($scalarMatchers);
37+
$arrayMatcher = new Matcher\ArrayMatcher($scalarMatchers, $parser);
3838

3939
$this->matcher = new Matcher(new Matcher\ChainMatcher(array(
4040
$scalarMatchers,

0 commit comments

Comments
 (0)