Skip to content

Commit 1181f80

Browse files
committed
Added OneOf expander, fixed NotEmpty tests
1 parent 326b117 commit 1181f80

File tree

7 files changed

+177
-10
lines changed

7 files changed

+177
-10
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ $match = $matcher->match("lorem ipsum dolor", "@string@")
5454
* lowerThan($boundry)
5555
* greaterThan($boundry)
5656
* inArray($value)
57+
* oneOf(...$expanders) - example usage ```"@[email protected](contains('foo'), contains('bar'), contains('baz'))"```
5758

5859
##Example usage
5960

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 OneOf implements PatternExpander
9+
{
10+
/**
11+
* @var PatternExpander[]
12+
*/
13+
protected $expanders;
14+
15+
protected $error;
16+
17+
public function __construct()
18+
{
19+
if (func_num_args() < 2) {
20+
throw new \InvalidArgumentException("OneOf expander require at least two expanders.");
21+
}
22+
foreach (func_get_args() as $argument) {
23+
if (!$argument instanceof PatternExpander) {
24+
throw new \InvalidArgumentException("OneOf expander require each argument to be a valid PatternExpander.");
25+
}
26+
27+
$this->expanders[] = $argument;
28+
}
29+
}
30+
31+
/**
32+
* @param $value
33+
* @return boolean
34+
*/
35+
public function match($value)
36+
{
37+
foreach ($this->expanders as $expander) {
38+
if ($expander->match($value)) {
39+
return true;
40+
}
41+
}
42+
43+
$this->error = sprintf("Any expander available in OneOf expander does not match \"%s\".", new String($value));
44+
return false;
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: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ class Parser
2929
"lowerThan" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\LowerThan",
3030
"greaterThan" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\GreaterThan",
3131
"inArray" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\InArray",
32-
"contains" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\Contains"
32+
"contains" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\Contains",
33+
34+
"oneOf" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\OneOf"
3335
);
3436

3537
/**
@@ -222,6 +224,10 @@ private function getNextArgumentValue()
222224
return $this->getArrayArgument();
223225
}
224226

227+
if ($this->lexer->isNextToken(Lexer::T_EXPANDER_NAME)) {
228+
return $this->getNextExpanderNode();
229+
}
230+
225231
if (!$this->lexer->isNextTokenAny($validArgumentTypes)) {
226232
$this->unexpectedSyntaxError($this->lexer->lookahead, "string, number, boolean or null argument");
227233
}
@@ -343,16 +349,26 @@ private function endOfPattern()
343349
}
344350

345351
/**
346-
* @param AST\Expander $expander
352+
* @param AST\Expander $expanderNode
347353
* @throws InvalidExpanderTypeException
348354
* @return Pattern\PatternExpander
349355
*/
350-
private function initializeExpander(AST\Expander $expander)
356+
private function initializeExpander(AST\Expander $expanderNode)
351357
{
352-
$reflection = new \ReflectionClass($this->expanderDefinitions[$expander->getName()]);
353-
$expander = !$expander->hasArguments()
354-
? $reflection->newInstance()
355-
: $reflection->newInstanceArgs($expander->getArguments());
358+
$reflection = new \ReflectionClass($this->expanderDefinitions[$expanderNode->getName()]);
359+
360+
if ($expanderNode->hasArguments()) {
361+
$arguments = array();
362+
foreach ($expanderNode->getArguments() as $argument) {
363+
$arguments[] = ($argument instanceof AST\Expander)
364+
? $this->initializeExpander($argument)
365+
: $argument;
366+
}
367+
368+
$expander = $reflection->newInstanceArgs($arguments);
369+
} else {
370+
$expander = $reflection->newInstance();
371+
}
356372

357373
if (!$expander instanceof Pattern\PatternExpander) {
358374
throw new InvalidExpanderTypeException();
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Coduo\PHPMatcher\Tests\Matcher\Pattern\Expander;
4+
5+
use Coduo\PHPMatcher\Matcher\Pattern\Expander\Contains;
6+
use Coduo\PHPMatcher\Matcher\Pattern\Expander\OneOf;
7+
8+
class OneOfTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @expectedException \InvalidArgumentException
12+
* @expectedExceptionMessage OneOf expander require at least two expanders.
13+
*/
14+
public function test_not_enough_arguments()
15+
{
16+
$expander = new OneOf();
17+
}
18+
19+
/**
20+
* @expectedException \InvalidArgumentException
21+
* @expectedExceptionMessage OneOf expander require each argument to be a valid PatternExpander.
22+
*/
23+
public function test_invalid_argument_types()
24+
{
25+
$expander = new OneOf("arg1", array("test"));
26+
}
27+
28+
public function test_positive_match()
29+
{
30+
$expander = new OneOf(
31+
new Contains("lorem"),
32+
new Contains("test")
33+
);
34+
35+
$this->assertTrue($expander->match("lorem ipsum"));
36+
}
37+
38+
public function test_negative_match()
39+
{
40+
$expander = new OneOf(
41+
new Contains("lorem"),
42+
new Contains("test")
43+
);
44+
45+
$this->assertFalse($expander->match("this is random stiring"));
46+
$this->assertSame(
47+
"Any expander available in OneOf expander does not match \"this is random stiring\".",
48+
$expander->getError()
49+
);
50+
}
51+
}

tests/Coduo/PHPMatcher/MatcherTest.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,16 +202,41 @@ public function test_matcher_with_captures()
202202
));
203203
$this->assertEquals($this->captureMatcher['uid'], 5);
204204
}
205-
206-
function test_matcher_with_callback()
205+
206+
public function test_matcher_with_callback()
207207
{
208208
$this->assertTrue($this->matcher->match('test', function($value) { return $value === 'test';}));
209209
$this->assertFalse($this->matcher->match('test', function($value) { return $value !== 'test';}));
210210
}
211211

212-
function test_matcher_with_wildcard()
212+
public function test_matcher_with_wildcard()
213213
{
214214
$this->assertTrue($this->matcher->match('test', '@*@'));
215215
$this->assertTrue($this->matcher->match('test', '@wildcard@'));
216216
}
217+
218+
/**
219+
* @dataProvider expanderExamples()
220+
*/
221+
public function test_expanders($value, $pattern, $expectedResult)
222+
{
223+
$this->assertSame($expectedResult, $this->matcher->match($value, $pattern));
224+
}
225+
226+
public static function expanderExamples()
227+
{
228+
return array(
229+
array("lorem ipsum", "@[email protected](\"lorem\")", true),
230+
array("lorem ipsum", "@[email protected](\"LOREM\", true)", true),
231+
array("lorem ipsum", "@[email protected](\"ipsum\")", true),
232+
array("lorem ipsum", "@[email protected](\"IPSUM\", true)", true),
233+
array("lorem ipsum", "@[email protected](\"lorem\")", true),
234+
array(100, "@[email protected](101).greaterThan(10)", true),
235+
array("", "@[email protected]()", false),
236+
array("lorem ipsum", "@[email protected]()", true),
237+
array(array("foo", "bar"), "@[email protected](\"bar\")", true),
238+
array("lorem ipsum", "@[email protected](contains(\"lorem\"), contains(\"test\"))", true),
239+
array("lorem ipsum", "@[email protected](contains(\"lorem\"), contains(\"test\")).endsWith(\"ipsum\")", true),
240+
);
241+
}
217242
}

tests/Coduo/PHPMatcher/ParserTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Coduo\PHPMatcher\Tests;
44

5+
use Coduo\PHPMatcher\AST\Expander;
56
use Coduo\PHPMatcher\Lexer;
67
use Coduo\PHPMatcher\Parser;
78

@@ -131,4 +132,23 @@ public static function expandersWithArrayArguments()
131132
)
132133
);
133134
}
135+
136+
public function test_expanders_that_takes_other_expanders_as_arguments()
137+
{
138+
$pattern = "@[email protected](expander(\"test\"), expander(1))";
139+
$expanders = $this->parser->getAST($pattern)->getExpanders();
140+
141+
$firstExpander = new Expander("expander");
142+
$firstExpander->addArgument("test");
143+
$secondExpander = new Expander("expander");
144+
$secondExpander->addArgument(1);
145+
146+
$this->assertEquals(
147+
$expanders[0]->getArguments(),
148+
array(
149+
$firstExpander,
150+
$secondExpander
151+
)
152+
);
153+
}
134154
}

0 commit comments

Comments
 (0)