diff --git a/src/Coduo/PHPMatcher/Exception/UnknownTypeException.php b/src/Coduo/PHPMatcher/Exception/UnknownTypeException.php index b6a0f832..197e47d1 100644 --- a/src/Coduo/PHPMatcher/Exception/UnknownTypeException.php +++ b/src/Coduo/PHPMatcher/Exception/UnknownTypeException.php @@ -4,4 +4,19 @@ class UnknownTypeException extends Exception { + private $type; + + public function __construct($type) + { + $this->type = "@" . $type . "@"; + parent::__construct(sprintf("Type pattern \"%s\" is not supported.", $this->type), 0, null); + } + + /** + * @return mixed + */ + public function getType() + { + return $this->type; + } } diff --git a/src/Coduo/PHPMatcher/Matcher/JsonMatcher.php b/src/Coduo/PHPMatcher/Matcher/JsonMatcher.php index 9682a3e3..e033d649 100644 --- a/src/Coduo/PHPMatcher/Matcher/JsonMatcher.php +++ b/src/Coduo/PHPMatcher/Matcher/JsonMatcher.php @@ -2,11 +2,10 @@ namespace Coduo\PHPMatcher\Matcher; +use Coduo\PHPMatcher\Matcher\Pattern\Assert\Json; + class JsonMatcher extends Matcher { - const TRANSFORM_QUOTATION_PATTERN = '/([^"])@([a-zA-Z0-9\.]+)@([^"])/'; - const TRANSFORM_QUOTATION_REPLACEMENT = '$1"@$2@"$3'; - /** * @var */ @@ -25,12 +24,12 @@ public function __construct(ValueMatcher $matcher) */ public function match($value, $pattern) { - if (!is_string($value) || !$this->isValidJson($value)) { + if (!Json::isValid($value)) { return false; } - $pattern = $this->transformPattern($pattern); - $match = $this->matcher->match(json_decode($value, true), json_decode($pattern, true)); + $transformedPattern = Json::transformPattern($pattern); + $match = $this->matcher->match(json_decode($value, true), json_decode($transformedPattern, true)); if (!$match) { $this->error = $this->matcher->getError(); return false; @@ -44,29 +43,6 @@ public function match($value, $pattern) */ public function canMatch($pattern) { - if (!is_string($pattern)) { - return false; - } - - return $this->isValidJson($this->transformPattern($pattern)); + return Json::isValidPattern($pattern); } - - private function isValidJson($string) - { - @json_decode($string, true); - - return (json_last_error() === JSON_ERROR_NONE); - } - - /** - * Wraps placeholders which arent wrapped with quotes yet - * - * @param $pattern - * @return mixed - */ - private function transformPattern($pattern) - { - return preg_replace(self::TRANSFORM_QUOTATION_PATTERN, self::TRANSFORM_QUOTATION_REPLACEMENT, $pattern); - } - } diff --git a/src/Coduo/PHPMatcher/Matcher/Pattern/Assert/Json.php b/src/Coduo/PHPMatcher/Matcher/Pattern/Assert/Json.php new file mode 100644 index 00000000..d9f6d45f --- /dev/null +++ b/src/Coduo/PHPMatcher/Matcher/Pattern/Assert/Json.php @@ -0,0 +1,52 @@ +getType()) { + switch ($typePattern->getType()) { case 'string': case 'wildcard': case '*': @@ -20,7 +20,7 @@ public function toRegex(TypePattern $type) case 'double': return "(\\-?[0-9]*[\\.|\\,][0-9]*)"; default: - throw new UnknownTypeException(); + throw new UnknownTypeException($typePattern->getType()); } } } diff --git a/src/Coduo/PHPMatcher/Matcher/TextMatcher.php b/src/Coduo/PHPMatcher/Matcher/TextMatcher.php index 4a5d0de6..73b85962 100644 --- a/src/Coduo/PHPMatcher/Matcher/TextMatcher.php +++ b/src/Coduo/PHPMatcher/Matcher/TextMatcher.php @@ -2,6 +2,9 @@ namespace Coduo\PHPMatcher\Matcher; +use Coduo\PHPMatcher\Exception\UnknownTypeException; +use Coduo\PHPMatcher\Matcher\Pattern\Assert\Json; +use Coduo\PHPMatcher\Matcher\Pattern\Assert\Xml; use Coduo\PHPMatcher\Matcher\Pattern\TypePattern; use Coduo\PHPMatcher\Parser; use Coduo\PHPMatcher\Matcher\Pattern\RegexConverter; @@ -46,7 +49,12 @@ public function match($value, $pattern) $patternRegex = $pattern; $patternsReplacedWithRegex = $this->replaceTypePatternsWithPlaceholders($patternRegex); $patternRegex = $this->prepareRegex($patternRegex); - $patternRegex = $this->replacePlaceholderWithPatternRegexes($patternRegex, $patternsReplacedWithRegex); + try { + $patternRegex = $this->replacePlaceholderWithPatternRegexes($patternRegex, $patternsReplacedWithRegex); + } catch (UnknownTypeException $exception) { + $this->error = sprintf(sprintf("Type pattern \"%s\" is not supported by TextMatcher.", $exception->getType())); + return false; + } if (!preg_match($patternRegex, $value, $matchedValues)) { $this->error = sprintf("\"%s\" does not match \"%s\" pattern", $value, $pattern); @@ -79,6 +87,14 @@ public function canMatch($pattern) return false; } + if (Json::isValidPattern($pattern)) { + return false; + } + + if (Xml::isValid($pattern)) { + return false; + } + return true; } diff --git a/src/Coduo/PHPMatcher/Matcher/XmlMatcher.php b/src/Coduo/PHPMatcher/Matcher/XmlMatcher.php index 6b00120a..2179bc81 100644 --- a/src/Coduo/PHPMatcher/Matcher/XmlMatcher.php +++ b/src/Coduo/PHPMatcher/Matcher/XmlMatcher.php @@ -2,6 +2,7 @@ namespace Coduo\PHPMatcher\Matcher; +use Coduo\PHPMatcher\Matcher\Pattern\Assert\Xml; use LSS\XML2Array; class XmlMatcher extends Matcher @@ -24,7 +25,7 @@ public function __construct(ValueMatcher $matcher) */ public function match($value, $pattern) { - if (!is_string($value) || !$this->isValidXml($value) || !$this->isValidXml($pattern)) { + if (!Xml::isValid($value) || !Xml::isValid($pattern)) { return false; } @@ -45,22 +46,6 @@ public function match($value, $pattern) */ public function canMatch($pattern) { - if (!is_string($pattern)) { - return false; - } - - return $this->isValidXml($pattern); - } - - private function isValidXml($string) - { - $xml = @simplexml_load_string($string); - - if (!$xml instanceof \SimpleXMLElement) { - - return false; - } - - return true; + return Xml::isValid($pattern); } } diff --git a/tests/Coduo/PHPMatcher/Matcher/TextMatcherTest.php b/tests/Coduo/PHPMatcher/Matcher/TextMatcherTest.php index 79f2800f..2434ecc5 100644 --- a/tests/Coduo/PHPMatcher/Matcher/TextMatcherTest.php +++ b/tests/Coduo/PHPMatcher/Matcher/TextMatcherTest.php @@ -45,6 +45,48 @@ public function test_positive_matches($value, $pattern, $expectedResult) $this->assertEquals($expectedResult, $this->matcher->match($value, $pattern)); } + public function test_ignore_valid_json_patterns() + { + $jsonPattern = json_encode(array( + 'users' => array( + array('id' => '@number@', 'name' => 'Norbert'), + array('id' => '@number@', 'name' => 'Michal') + ) + )); + + $this->assertFalse($this->matcher->canMatch($jsonPattern)); + } + + public function test_ignore_valid_xml_patterns() + { + $xmlPattern = << + + + + + @string@ + Any Value + + + + +XML; + + $this->assertFalse($this->matcher->canMatch($xmlPattern)); + } + + public function test_error_when_unsupported_type_pattern_used() + { + $pattern = "lorem ipsum @null@ bla bla"; + $value = "lorem ipsum bla bla"; + + $this->assertFalse($this->matcher->match($value, $pattern)); + $this->assertSame("Type pattern \"@null@\" is not supported by TextMatcher.", $this->matcher->getError()); + } + public function matchingData() { return array( diff --git a/tests/Coduo/PHPMatcher/MatcherTest.php b/tests/Coduo/PHPMatcher/MatcherTest.php index 58df8b1b..dd66dd49 100644 --- a/tests/Coduo/PHPMatcher/MatcherTest.php +++ b/tests/Coduo/PHPMatcher/MatcherTest.php @@ -203,6 +203,16 @@ public function test_text_matcher() $this->assertTrue(match($value, $pattern)); } + + public function test_error_when_json_value_does_not_match_json_pattern() + { + $pattern = '{"a": @null@, "b": 4}'; + $value = '{"a": null, "b": 5}'; + + $this->assertFalse($this->matcher->match($value, $pattern)); + $this->assertSame('"5" does not match "4".', $this->matcher->getError()); + } + public function test_matcher_with_captures() { $this->assertTrue($this->matcher->match(