Skip to content

Commit 4a2dbe1

Browse files
author
Michal Szczur
committed
#53 Added OR operator support
1 parent 87ff316 commit 4a2dbe1

File tree

4 files changed

+273
-30
lines changed

4 files changed

+273
-30
lines changed

src/Factory/SimpleFactory.php

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

28-
return new Matcher\ChainMatcher(array(
28+
$chainMatcher = new Matcher\ChainMatcher(array(
2929
$scalarMatchers,
30-
$arrayMatcher,
31-
new Matcher\JsonMatcher($arrayMatcher),
32-
new Matcher\XmlMatcher($arrayMatcher),
30+
$orMatcher,
31+
new Matcher\JsonMatcher($orMatcher),
32+
new Matcher\XmlMatcher($orMatcher),
3333
new Matcher\TextMatcher($scalarMatchers, $this->buildParser())
3434
));
35+
36+
return $chainMatcher;
37+
}
38+
39+
/**
40+
* @return Matcher\ChainMatcher
41+
*/
42+
protected function buildOrMatcher()
43+
{
44+
$scalarMatchers = $this->buildScalarMatchers();
45+
$orMatcher = new Matcher\OrMatcher($scalarMatchers);
46+
$arrayMatcher = new Matcher\ArrayMatcher(
47+
new Matcher\ChainMatcher(array(
48+
$orMatcher,
49+
$scalarMatchers
50+
)),
51+
$this->buildParser()
52+
);
53+
54+
$chainMatcher = new Matcher\ChainMatcher(array(
55+
$orMatcher,
56+
$arrayMatcher,
57+
));
58+
59+
return $chainMatcher;
3560
}
3661

3762
/**

src/Matcher/OrMatcher.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace Coduo\PHPMatcher\Matcher;
4+
5+
final class OrMatcher extends Matcher
6+
{
7+
const MATCH_PATTERN = "/\|\|/";
8+
9+
/**
10+
* @var ChainMatcher
11+
*/
12+
private $chainMatcher;
13+
14+
/**
15+
* @param ChainMatcher $chainMatcher
16+
*/
17+
public function __construct(ChainMatcher $chainMatcher)
18+
{
19+
$this->chainMatcher = $chainMatcher;
20+
}
21+
22+
/**
23+
* {@inheritDoc}
24+
*/
25+
public function match($value, $pattern)
26+
{
27+
$patterns = explode('||', $pattern);
28+
foreach ($patterns as $childPattern) {
29+
if ($this->matchChild($value, $childPattern)){
30+
return true;
31+
}
32+
}
33+
34+
return false;
35+
}
36+
37+
/**
38+
* Matches single pattern
39+
*
40+
* @param $value
41+
* @param $pattern
42+
* @return bool
43+
*/
44+
private function matchChild($value, $pattern)
45+
{
46+
if (!$this->chainMatcher->canMatch($pattern)) {
47+
return false;
48+
}
49+
50+
if ($this->chainMatcher->match($value, $pattern)) {
51+
return true;
52+
}
53+
54+
return false;
55+
}
56+
57+
/**
58+
* {@inheritDoc}
59+
*/
60+
public function canMatch($pattern)
61+
{
62+
return is_string($pattern) && 0 !== preg_match_all(self::MATCH_PATTERN, $pattern, $matches);
63+
}
64+
}

tests/Matcher/OrMatcherTest.php

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
namespace Coduo\PHPMatcher\Tests\Matcher;
3+
4+
use Coduo\PHPMatcher\Factory\SimpleFactory;
5+
use Coduo\PHPMatcher\Matcher;
6+
use Coduo\PHPMatcher\Parser;
7+
8+
class OrMatcherTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @var Matcher\OrMatcher
12+
*/
13+
private $matcher;
14+
15+
public function setUp()
16+
{
17+
$factory = new SimpleFactory();
18+
$this->matcher = $factory->createMatcher();
19+
}
20+
21+
/**
22+
* @dataProvider positiveMatchData
23+
*/
24+
public function test_positive_match_arrays($value, $pattern)
25+
{
26+
$this->assertTrue(
27+
$this->matcher->match($value, $pattern),
28+
$this->matcher->getError()
29+
);
30+
}
31+
32+
/**
33+
* @dataProvider negativeMatchData
34+
*/
35+
public function test_negative_match_arrays($value, $pattern)
36+
{
37+
$this->assertFalse(
38+
$this->matcher->match($value, $pattern),
39+
$this->matcher->getError()
40+
);
41+
}
42+
43+
public static function positiveMatchData()
44+
{
45+
$simpleArr = array(
46+
'users' => array(
47+
array(
48+
'firstName' => 'Norbert',
49+
'lastName' => 'Orzechowicz'
50+
),
51+
array(
52+
'firstName' => 1,
53+
'lastName' => 2
54+
)
55+
),
56+
true,
57+
false,
58+
1,
59+
6.66
60+
);
61+
62+
$simpleArrPattern = array(
63+
'users' => array(
64+
array(
65+
'firstName' => '@string@',
66+
'lastName' => '@null@||@string@||@integer@'
67+
),
68+
'@...@'
69+
),
70+
true,
71+
false,
72+
1,
73+
6.66
74+
);
75+
76+
return array(
77+
array('test', '@string@'),
78+
array(null, '@array@||@string@||@null@'),
79+
array(
80+
array(
81+
'test' => 1
82+
),
83+
array(
84+
'test' => '@integer@'
85+
)
86+
),
87+
array(
88+
array(
89+
'test' => null
90+
),
91+
array(
92+
'test' => '@integer@||@null@'
93+
)
94+
),
95+
array(
96+
array(
97+
'first_level' => array('second_level', array('third_level'))
98+
),
99+
'@array@||@null@||@*@'
100+
),
101+
array($simpleArr, $simpleArr),
102+
array($simpleArr, $simpleArrPattern),
103+
);
104+
}
105+
106+
public static function negativeMatchData()
107+
{
108+
$simpleArr = array(
109+
'users' => array(
110+
array(
111+
'firstName' => 'Norbert',
112+
'lastName' => 'Orzechowicz'
113+
),
114+
array(
115+
'firstName' => 'Michał',
116+
'lastName' => 'Dąbrowski'
117+
)
118+
),
119+
true,
120+
false,
121+
1,
122+
6.66
123+
);
124+
125+
$simpleDiff = array(
126+
'users' => array(
127+
array(
128+
'firstName' => 'Norbert',
129+
'lastName' => 'Orzechowicz'
130+
),
131+
array(
132+
'firstName' => 'Pablo',
133+
'lastName' => '@integer@||@null@||@double@'
134+
)
135+
),
136+
true,
137+
false,
138+
1,
139+
6.66
140+
);
141+
142+
return array(
143+
array($simpleArr, $simpleDiff),
144+
array(array("status" => "ok", "data" => array(array('foo'))), array("status" => "ok", "data" => array())),
145+
array(array(1), array()),
146+
array(array('key' => 'val'), array('key' => 'val2')),
147+
array(array(1), array(2)),
148+
array(array('foo', 1, 3), array('foo', 2, 3)),
149+
array(array(), array('foo' => 'bar')),
150+
array(10, '@null@||@[email protected](10)'),
151+
);
152+
}
153+
}

tests/MatcherTest.php

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Coduo\PHPMatcher\Tests;
44

5-
use Coduo\PHPMatcher\Lexer;
5+
use Coduo\PHPMatcher\Factory\SimpleFactory;
66
use Coduo\PHPMatcher\Matcher;
77
use Coduo\PHPMatcher\Parser;
88
use Coduo\PHPMatcher\PHPMatcher;
@@ -16,29 +16,8 @@ class MatcherTest extends \PHPUnit_Framework_TestCase
1616

1717
public function setUp()
1818
{
19-
$parser = new Parser(new Lexer(), new Parser\ExpanderInitializer());
20-
$scalarMatchers = new Matcher\ChainMatcher(array(
21-
new Matcher\CallbackMatcher(),
22-
new Matcher\ExpressionMatcher(),
23-
new Matcher\NullMatcher(),
24-
new Matcher\StringMatcher($parser),
25-
new Matcher\IntegerMatcher($parser),
26-
new Matcher\BooleanMatcher(),
27-
new Matcher\DoubleMatcher($parser),
28-
new Matcher\NumberMatcher(),
29-
new Matcher\ScalarMatcher(),
30-
new Matcher\WildcardMatcher(),
31-
));
32-
33-
$arrayMatcher = new Matcher\ArrayMatcher($scalarMatchers, $parser);
34-
35-
$this->matcher = new Matcher(new Matcher\ChainMatcher(array(
36-
$scalarMatchers,
37-
$arrayMatcher,
38-
new Matcher\JsonMatcher($arrayMatcher),
39-
new Matcher\XmlMatcher($arrayMatcher),
40-
new Matcher\TextMatcher($scalarMatchers, $parser)
41-
)));
19+
$factory = new SimpleFactory();
20+
$this->matcher = $factory->createMatcher();
4221
}
4322

4423
public function test_matcher_with_array_value()
@@ -217,6 +196,15 @@ public function test_matcher_with_wildcard()
217196
$this->assertTrue(PHPMatcher::match('test', '@wildcard@'));
218197
}
219198

199+
/**
200+
* @dataProvider orExamples()
201+
*/
202+
public function test_matcher_with_or($value, $pattern, $expectedResult)
203+
{
204+
$this->assertSame($expectedResult, $this->matcher->match($value, $pattern));
205+
$this->assertSame($expectedResult, PHPMatcher::match($value, $pattern));
206+
}
207+
220208
/**
221209
* @dataProvider expanderExamples()
222210
*/
@@ -235,7 +223,7 @@ public function scalarValueExamples()
235223
array(array('foo'), '@array@')
236224
);
237225
}
238-
226+
239227
public static function expanderExamples()
240228
{
241229
return array(
@@ -262,4 +250,17 @@ public static function expanderExamples()
262250
array("lorem ipsum", "@[email protected](\"/^foo/\")", false),
263251
);
264252
}
253+
254+
public static function orExamples()
255+
{
256+
return array(
257+
array("lorem ipsum", "@[email protected](\"lorem\")||@[email protected](\"lorem\")", true),
258+
array("[email protected]", "@[email protected]()||@null@", true),
259+
array(null, "@[email protected]()||@null@", true),
260+
array(null, "@[email protected]()||@null@", true),
261+
array("2014-08-19", "@[email protected]()||@integer@", true),
262+
array(null, "@integer@||@string@", false),
263+
array(1, "@[email protected](10)||@[email protected](\"10\")", false),
264+
);
265+
}
265266
}

0 commit comments

Comments
 (0)