Skip to content

Possibility to get error message when matching fails #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar --dev install

script: phpunit --coverage-text
script: bin/phpunit --coverage-text
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
],
"require": {
"php": ">=5.3.0",
"coduo/php-to-string": "1.0.*@dev",
"symfony/property-access": "~2.3",
"symfony/expression-language": "~2.4"
},
Expand Down
17 changes: 14 additions & 3 deletions src/Coduo/PHPMatcher/Matcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,36 @@

use Coduo\PHPMatcher\Matcher\PropertyMatcher;

class Matcher implements PropertyMatcher
class Matcher
{
/**
* @var Matcher\PropertyMatcher
*/
private $matcher;

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

/**
* @param mixed $value
* @param mixed $pattern
* @return bool
*/
public function match($value, $pattern)
{
return $this->matcher->match($value, $pattern);
}

public function canMatch($pattern)
/**
* @return null|string
*/
public function getError()
{
return true;
return $this->matcher->getError();
}
}
6 changes: 3 additions & 3 deletions src/Coduo/PHPMatcher/Matcher/ArrayMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
use Symfony\Component\PropertyAccess\Exception\NoSuchIndexException;
use Symfony\Component\PropertyAccess\PropertyAccessor;

class ArrayMatcher implements PropertyMatcher
class ArrayMatcher extends Matcher
{
/**
* @var PropertyMatcher
*/
private $propertyMatcher;

private $paths;

/**
* @var PropertyAccessor
*/
Expand Down Expand Up @@ -60,6 +58,7 @@ private function iterateMatch(array $value, array $pattern)
$path = sprintf("[%s]", $key);

if (!$this->hasValue($pattern, $path)) {
$this->error = sprintf('There is no element under path %s in pattern array.', $path);
return false;
}
$elementPattern = $this->getValue($pattern, $path);
Expand All @@ -70,6 +69,7 @@ private function iterateMatch(array $value, array $pattern)
}

if (!is_array($element)) {
$this->error = $this->propertyMatcher->getError();
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion src/Coduo/PHPMatcher/Matcher/CaptureMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Coduo\PHPMatcher\Matcher;

class CaptureMatcher implements PropertyMatcher, \ArrayAccess
class CaptureMatcher extends Matcher implements \ArrayAccess
{
const MATCH_PATTERN = "/^:.*:$/";

Expand Down Expand Up @@ -39,6 +39,7 @@ public function offsetSet($offset, $value)
$this->captures[$offset] = $value;
}
}

public function offsetExists($offset)
{
return isset($this->captures[$offset]);
Expand Down
24 changes: 22 additions & 2 deletions src/Coduo/PHPMatcher/Matcher/ChainMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,26 @@

namespace Coduo\PHPMatcher\Matcher;

class ChainMatcher implements PropertyMatcher
use Coduo\ToString\String;

class ChainMatcher extends Matcher
{
/**
* @var array|PropertyMatcher[]
*/
private $matchers;

/**
* @param array|PropertyMatcher[] $matchers
*/
public function __construct(array $matchers = array())
{
$this->matchers = $matchers;
}

/**
* @param PropertyMatcher $matcher
*/
public function addMatcher(PropertyMatcher $matcher)
{
$this->matchers[] = $matcher;
Expand All @@ -26,9 +37,19 @@ public function match($value, $pattern)
if (true === $propertyMatcher->match($value, $pattern)) {
return true;
}

$this->error = $propertyMatcher->getError();
}
}

if (!isset($this->error)) {
$this->error = sprintf(
'Any matcher from chain can\'t match value "%s" to pattern "%s"',
new String($value),
new String($pattern)
);
}

return false;
}

Expand All @@ -39,5 +60,4 @@ public function canMatch($pattern)
{
return true;
}

}
10 changes: 8 additions & 2 deletions src/Coduo/PHPMatcher/Matcher/ExpressionMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

namespace Coduo\PHPMatcher\Matcher;

use Coduo\ToString\String;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

class ExpressionMatcher implements PropertyMatcher
class ExpressionMatcher extends Matcher
{
const MATCH_PATTERN = "/^expr\((.*?)\)$/";

Expand All @@ -15,8 +16,13 @@ public function match($value, $pattern)
{
$language = new ExpressionLanguage();
preg_match(self::MATCH_PATTERN, $pattern, $matches);
$expressionResult = $language->evaluate($matches[1], array('value' => $value));

return $language->evaluate($matches[1], array('value' => $value));
if (!$expressionResult) {
$this->error = sprintf("\"%s\" expression fails for value \"%s\".", $pattern, new String($value));
}

return $expressionResult;
}

/**
Expand Down
9 changes: 7 additions & 2 deletions src/Coduo/PHPMatcher/Matcher/JsonMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Coduo\PHPMatcher\Matcher;

class JsonMatcher implements PropertyMatcher
class JsonMatcher extends Matcher
{
const TRANSFORM_QUOTATION_PATTERN = '/([^"])@(integer|string|array|double|wildcard|boolean)@([^"])/';
const TRANSFORM_QUOTATION_REPLACEMENT = '$1"@$2@"$3';
Expand Down Expand Up @@ -30,8 +30,13 @@ public function match($value, $pattern)
}

$pattern = $this->transformPattern($pattern);
$match = $this->matcher->match(json_decode($value, true), json_decode($pattern, true));
if (!$match) {
$this->error = $this->matcher->getError();
return false;
}

return $this->matcher->match(json_decode($value, true), json_decode($pattern, true));
return true;
}

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

namespace Coduo\PHPMatcher\Matcher;

abstract class Matcher implements PropertyMatcher
{
/**
* @var string|null
*/
protected $error;

/**
* {@inheritdoc}
*/
public function getError()
{
return $this->error;
}
}
6 changes: 6 additions & 0 deletions src/Coduo/PHPMatcher/Matcher/PropertyMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ public function match($value, $pattern);
*/
public function canMatch($pattern);

/**
* Returns a string description why matching failed
*
* @return null|string
*/
public function getError();
}
11 changes: 9 additions & 2 deletions src/Coduo/PHPMatcher/Matcher/ScalarMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@

namespace Coduo\PHPMatcher\Matcher;

class ScalarMatcher implements PropertyMatcher
use Coduo\ToString\String;

class ScalarMatcher extends Matcher
{
/**
* {@inheritDoc}
*/
public function match($value, $pattern)
{
return $value === $pattern;
if ($value !== $pattern) {
$this->error = sprintf("\"%s\" does not match \"%s\".", new String($value), new String($pattern));
return false;
}

return true;
}

/**
Expand Down
12 changes: 10 additions & 2 deletions src/Coduo/PHPMatcher/Matcher/TypeMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Coduo\PHPMatcher\Matcher;

class TypeMatcher implements PropertyMatcher
use Coduo\ToString\String;

class TypeMatcher extends Matcher
{
const MATCH_PATTERN = "/^@(string|integer|boolean|double|array)@$/";

Expand All @@ -11,7 +13,12 @@ class TypeMatcher implements PropertyMatcher
*/
public function match($value, $pattern)
{
return gettype($value) === $this->extractType($pattern);
if (gettype($value) !== $this->extractType($pattern)) {
$this->error = sprintf("%s \"%s\" does not match %s pattern.", gettype($value), new String($value), $pattern);
return false;
}

return true;
}

/**
Expand All @@ -22,6 +29,7 @@ public function canMatch($pattern)
return is_string($pattern) && 0 !== preg_match(self::MATCH_PATTERN, $pattern);
}


private function extractType($pattern)
{
return str_replace("@", "", $pattern);
Expand Down
3 changes: 1 addition & 2 deletions src/Coduo/PHPMatcher/Matcher/WildcardMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Coduo\PHPMatcher\Matcher;

class WildcardMatcher implements PropertyMatcher
class WildcardMatcher extends Matcher
{
const MATCH_PATTERN = "/^@(\*|wildcard)@$/";

Expand All @@ -21,5 +21,4 @@ public function canMatch($pattern)
{
return is_string($pattern) && 0 !== preg_match(self::MATCH_PATTERN, $pattern);
}

}
12 changes: 12 additions & 0 deletions tests/Coduo/PHPMatcher/Matcher/ArrayMatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ public function test_negative_match_when_cant_find_matcher_that_can_match_array_
$this->assertFalse($matcher->match(array('test' => 1), array('test' => 1)));
}

public function test_error_when_path_does_not_exist()
{
$this->assertFalse($this->matcher->match(array('foo' => 'foo value'), array('bar' => 'bar value')));
$this->assertEquals($this->matcher->getError(), 'There is no element under path [foo] in pattern array.');
}

public function test_error_when_matching_fail()
{
$this->assertFalse($this->matcher->match(array('foo' => 'foo value'), array('foo' => 'bar value')));
$this->assertEquals($this->matcher->getError(), '"foo value" does not match "bar value".');
}

public static function positiveMatchData()
{
$simpleArr = array(
Expand Down
Loading