Skip to content

Commit

Permalink
Merge pull request #74 from partikus/feature/or-matcher
Browse files Browse the repository at this point in the history
#53 Added OR operator support
  • Loading branch information
Norbert Orzechowicz committed Mar 18, 2016
2 parents 87ff316 + 4a2dbe1 commit 63de6d2
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 30 deletions.
35 changes: 30 additions & 5 deletions src/Factory/SimpleFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,40 @@ public function createMatcher()
protected function buildMatchers()
{
$scalarMatchers = $this->buildScalarMatchers();
$arrayMatcher = new Matcher\ArrayMatcher($scalarMatchers, $this->buildParser());
$orMatcher = $this->buildOrMatcher();

return new Matcher\ChainMatcher(array(
$chainMatcher = new Matcher\ChainMatcher(array(
$scalarMatchers,
$arrayMatcher,
new Matcher\JsonMatcher($arrayMatcher),
new Matcher\XmlMatcher($arrayMatcher),
$orMatcher,
new Matcher\JsonMatcher($orMatcher),
new Matcher\XmlMatcher($orMatcher),
new Matcher\TextMatcher($scalarMatchers, $this->buildParser())
));

return $chainMatcher;
}

/**
* @return Matcher\ChainMatcher
*/
protected function buildOrMatcher()
{
$scalarMatchers = $this->buildScalarMatchers();
$orMatcher = new Matcher\OrMatcher($scalarMatchers);
$arrayMatcher = new Matcher\ArrayMatcher(
new Matcher\ChainMatcher(array(
$orMatcher,
$scalarMatchers
)),
$this->buildParser()
);

$chainMatcher = new Matcher\ChainMatcher(array(
$orMatcher,
$arrayMatcher,
));

return $chainMatcher;
}

/**
Expand Down
64 changes: 64 additions & 0 deletions src/Matcher/OrMatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Coduo\PHPMatcher\Matcher;

final class OrMatcher extends Matcher
{
const MATCH_PATTERN = "/\|\|/";

/**
* @var ChainMatcher
*/
private $chainMatcher;

/**
* @param ChainMatcher $chainMatcher
*/
public function __construct(ChainMatcher $chainMatcher)
{
$this->chainMatcher = $chainMatcher;
}

/**
* {@inheritDoc}
*/
public function match($value, $pattern)
{
$patterns = explode('||', $pattern);
foreach ($patterns as $childPattern) {
if ($this->matchChild($value, $childPattern)){
return true;
}
}

return false;
}

/**
* Matches single pattern
*
* @param $value
* @param $pattern
* @return bool
*/
private function matchChild($value, $pattern)
{
if (!$this->chainMatcher->canMatch($pattern)) {
return false;
}

if ($this->chainMatcher->match($value, $pattern)) {
return true;
}

return false;
}

/**
* {@inheritDoc}
*/
public function canMatch($pattern)
{
return is_string($pattern) && 0 !== preg_match_all(self::MATCH_PATTERN, $pattern, $matches);
}
}
153 changes: 153 additions & 0 deletions tests/Matcher/OrMatcherTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php
namespace Coduo\PHPMatcher\Tests\Matcher;

use Coduo\PHPMatcher\Factory\SimpleFactory;
use Coduo\PHPMatcher\Matcher;
use Coduo\PHPMatcher\Parser;

class OrMatcherTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Matcher\OrMatcher
*/
private $matcher;

public function setUp()
{
$factory = new SimpleFactory();
$this->matcher = $factory->createMatcher();
}

/**
* @dataProvider positiveMatchData
*/
public function test_positive_match_arrays($value, $pattern)
{
$this->assertTrue(
$this->matcher->match($value, $pattern),
$this->matcher->getError()
);
}

/**
* @dataProvider negativeMatchData
*/
public function test_negative_match_arrays($value, $pattern)
{
$this->assertFalse(
$this->matcher->match($value, $pattern),
$this->matcher->getError()
);
}

public static function positiveMatchData()
{
$simpleArr = array(
'users' => array(
array(
'firstName' => 'Norbert',
'lastName' => 'Orzechowicz'
),
array(
'firstName' => 1,
'lastName' => 2
)
),
true,
false,
1,
6.66
);

$simpleArrPattern = array(
'users' => array(
array(
'firstName' => '@string@',
'lastName' => '@null@||@string@||@integer@'
),
'@...@'
),
true,
false,
1,
6.66
);

return array(
array('test', '@string@'),
array(null, '@array@||@string@||@null@'),
array(
array(
'test' => 1
),
array(
'test' => '@integer@'
)
),
array(
array(
'test' => null
),
array(
'test' => '@integer@||@null@'
)
),
array(
array(
'first_level' => array('second_level', array('third_level'))
),
'@array@||@null@||@*@'
),
array($simpleArr, $simpleArr),
array($simpleArr, $simpleArrPattern),
);
}

public static function negativeMatchData()
{
$simpleArr = array(
'users' => array(
array(
'firstName' => 'Norbert',
'lastName' => 'Orzechowicz'
),
array(
'firstName' => 'Michał',
'lastName' => 'Dąbrowski'
)
),
true,
false,
1,
6.66
);

$simpleDiff = array(
'users' => array(
array(
'firstName' => 'Norbert',
'lastName' => 'Orzechowicz'
),
array(
'firstName' => 'Pablo',
'lastName' => '@integer@||@null@||@double@'
)
),
true,
false,
1,
6.66
);

return array(
array($simpleArr, $simpleDiff),
array(array("status" => "ok", "data" => array(array('foo'))), array("status" => "ok", "data" => array())),
array(array(1), array()),
array(array('key' => 'val'), array('key' => 'val2')),
array(array(1), array(2)),
array(array('foo', 1, 3), array('foo', 2, 3)),
array(array(), array('foo' => 'bar')),
array(10, '@null@||@integer@.greaterThan(10)'),
);
}
}
51 changes: 26 additions & 25 deletions tests/MatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Coduo\PHPMatcher\Tests;

use Coduo\PHPMatcher\Lexer;
use Coduo\PHPMatcher\Factory\SimpleFactory;
use Coduo\PHPMatcher\Matcher;
use Coduo\PHPMatcher\Parser;
use Coduo\PHPMatcher\PHPMatcher;
Expand All @@ -16,29 +16,8 @@ class MatcherTest extends \PHPUnit_Framework_TestCase

public function setUp()
{
$parser = new Parser(new Lexer(), new Parser\ExpanderInitializer());
$scalarMatchers = new Matcher\ChainMatcher(array(
new Matcher\CallbackMatcher(),
new Matcher\ExpressionMatcher(),
new Matcher\NullMatcher(),
new Matcher\StringMatcher($parser),
new Matcher\IntegerMatcher($parser),
new Matcher\BooleanMatcher(),
new Matcher\DoubleMatcher($parser),
new Matcher\NumberMatcher(),
new Matcher\ScalarMatcher(),
new Matcher\WildcardMatcher(),
));

$arrayMatcher = new Matcher\ArrayMatcher($scalarMatchers, $parser);

$this->matcher = new Matcher(new Matcher\ChainMatcher(array(
$scalarMatchers,
$arrayMatcher,
new Matcher\JsonMatcher($arrayMatcher),
new Matcher\XmlMatcher($arrayMatcher),
new Matcher\TextMatcher($scalarMatchers, $parser)
)));
$factory = new SimpleFactory();
$this->matcher = $factory->createMatcher();
}

public function test_matcher_with_array_value()
Expand Down Expand Up @@ -217,6 +196,15 @@ public function test_matcher_with_wildcard()
$this->assertTrue(PHPMatcher::match('test', '@wildcard@'));
}

/**
* @dataProvider orExamples()
*/
public function test_matcher_with_or($value, $pattern, $expectedResult)
{
$this->assertSame($expectedResult, $this->matcher->match($value, $pattern));
$this->assertSame($expectedResult, PHPMatcher::match($value, $pattern));
}

/**
* @dataProvider expanderExamples()
*/
Expand All @@ -235,7 +223,7 @@ public function scalarValueExamples()
array(array('foo'), '@array@')
);
}

public static function expanderExamples()
{
return array(
Expand All @@ -262,4 +250,17 @@ public static function expanderExamples()
array("lorem ipsum", "@string@.matchRegex(\"/^foo/\")", false),
);
}

public static function orExamples()
{
return array(
array("lorem ipsum", "@string@.startsWith(\"lorem\")||@string@.contains(\"lorem\")", true),
array("norbert@coduo.pl", "@string@.isEmail()||@null@", true),
array(null, "@string@.isEmail()||@null@", true),
array(null, "@string@.isEmail()||@null@", true),
array("2014-08-19", "@string@.isDateTime()||@integer@", true),
array(null, "@integer@||@string@", false),
array(1, "@integer@.greaterThan(10)||@string@.contains(\"10\")", false),
);
}
}

0 comments on commit 63de6d2

Please sign in to comment.