Skip to content

Ignore strings that can be matched by other matchers in TextMatcher #49

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 1 commit into from
Jan 26, 2015
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
15 changes: 15 additions & 0 deletions src/Coduo/PHPMatcher/Exception/UnknownTypeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
36 changes: 6 additions & 30 deletions src/Coduo/PHPMatcher/Matcher/JsonMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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;
Expand All @@ -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);
}

}
52 changes: 52 additions & 0 deletions src/Coduo/PHPMatcher/Matcher/Pattern/Assert/Json.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Coduo\PHPMatcher\Matcher\Pattern\Assert;

class Json
{
const TRANSFORM_QUOTATION_PATTERN = '/([^"])@([a-zA-Z0-9\.]+)@([^"])/';
const TRANSFORM_QUOTATION_REPLACEMENT = '$1"@$2@"$3';

/**
* @param string $value
* @return bool
*/
public static function isValid($value)
{
if (!is_string($value)) {
return false;
}

if (null === json_decode($value) && JSON_ERROR_NONE !== json_last_error()) {
return false;
}

return true;
}

/**
* Before checking json it wraps type patterns (@type@) with quotes ("@type@")
*
* @param string $value
* @return bool
*/
public static function isValidPattern($value)
{
if (!is_string($value)) {
return false;
}

return self::isValid(self::transformPattern($value));
}

/**
* Wraps placeholders which arent wrapped with quotes yet
*
* @param $pattern
* @return mixed
*/
public static function transformPattern($pattern)
{
return preg_replace(self::TRANSFORM_QUOTATION_PATTERN, self::TRANSFORM_QUOTATION_REPLACEMENT, $pattern);
}
}
24 changes: 24 additions & 0 deletions src/Coduo/PHPMatcher/Matcher/Pattern/Assert/Xml.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Coduo\PHPMatcher\Matcher\Pattern\Assert;

class Xml
{
/**
* @param $value
* @return bool
*/
public static function isValid($value)
{
if (!is_string($value)) {
return false;

}
$xml = @simplexml_load_string($value);
if (!$xml instanceof \SimpleXMLElement) {
return false;
}

return true;
}
}
6 changes: 3 additions & 3 deletions src/Coduo/PHPMatcher/Matcher/Pattern/RegexConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

class RegexConverter
{
public function toRegex(TypePattern $type)
public function toRegex(TypePattern $typePattern)
{
switch ($type->getType()) {
switch ($typePattern->getType()) {
case 'string':
case 'wildcard':
case '*':
Expand All @@ -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());
}
}
}
18 changes: 17 additions & 1 deletion src/Coduo/PHPMatcher/Matcher/TextMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -79,6 +87,14 @@ public function canMatch($pattern)
return false;
}

if (Json::isValidPattern($pattern)) {
return false;
}

if (Xml::isValid($pattern)) {
return false;
}

return true;
}

Expand Down
21 changes: 3 additions & 18 deletions src/Coduo/PHPMatcher/Matcher/XmlMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Coduo\PHPMatcher\Matcher;

use Coduo\PHPMatcher\Matcher\Pattern\Assert\Xml;
use LSS\XML2Array;

class XmlMatcher extends Matcher
Expand All @@ -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;
}

Expand All @@ -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);
}
}
42 changes: 42 additions & 0 deletions tests/Coduo/PHPMatcher/Matcher/TextMatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <<<XML
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Body xmlns:m="http://www.example.org/stock">
<m:GetStockPrice>
<m:StockName>@string@</m:StockName>
<m:StockValue>Any Value</m:StockValue>
</m:GetStockPrice>
</soap:Body>

</soap:Envelope>
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(
Expand Down
10 changes: 10 additions & 0 deletions tests/Coduo/PHPMatcher/MatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down