Skip to content

Commit 6becf62

Browse files
committed
Adding chain matcher and refactoring
1 parent 64dd127 commit 6becf62

File tree

11 files changed

+247
-179
lines changed

11 files changed

+247
-179
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"symfony/property-access": "~2.3"
99
},
1010
"require-dev": {
11-
"phpunit/phpunit": "3.7.*@dev"
11+
"phpunit/phpunit": "3.7.*"
1212
},
1313
"autoload": {
1414
"psr-0": {

src/JsonMatcher/ArrayMatcher.php

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/JsonMatcher/Matcher.php

Lines changed: 14 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,29 @@
11
<?php
22
namespace JsonMatcher;
33

4-
class Matcher
5-
{
6-
public function match($matcher, $matchTo)
7-
{
8-
9-
if (is_array($matcher)) {
10-
if (-1 === $this->matchArray($matcher, $matchTo)) {
11-
return false;
12-
}
13-
} elseif(is_scalar($matcher) && strpos($matchTo, '@') > -1) {
14-
if (-1 === $this->matchType($matcher, $matchTo)) {
15-
return false;
16-
}
17-
} elseif (is_scalar($matcher)) {
18-
if (-1 === $this->matchScalar($matcher, $matchTo)) {
19-
return false;
20-
}
21-
}
22-
return true;
23-
}
4+
use JsonMatcher\Matcher\PropertyMatcher;
245

6+
class Matcher implements PropertyMatcher
7+
{
8+
/**
9+
* @var Matcher\PropertyMatcher
10+
*/
11+
private $matcher;
2512

26-
private function matchScalar($json, $expectedJson)
13+
public function __construct(PropertyMatcher $matcher)
2714
{
28-
if ($json !== $expectedJson) {
29-
return -1;
30-
}
15+
$this->matcher = $matcher;
3116
}
3217

33-
private function matchType($json, $type)
18+
public function match($matcher, $pattern)
3419
{
35-
$type = str_replace("@", "", $type);
36-
37-
if (gettype($json) !== $type) {
38-
return -1;
39-
}
20+
return $this->matcher->match($matcher, $pattern);
4021
}
4122

42-
43-
private function matchArray(array $array, array $arrayToMatch)
23+
public function canMatch($pattern)
4424
{
45-
46-
if (count($array) !== count($arrayToMatch) ) {
47-
return -1;
48-
}
49-
50-
$match = function($value, $array, $arrayToMatch) {
51-
52-
$key = array_search($value, $arrayToMatch);
53-
if ($key !== false) {
54-
$this->match($array[$key], $arrayToMatch[$key]);
55-
56-
return true;
57-
}
58-
59-
$key = array_search($value, $array);
60-
if (is_scalar($arrayToMatch[$key]) && strpos($arrayToMatch[$key], '@') > - 1) {
61-
$this->match($value, $arrayToMatch[$key]);
62-
63-
return true;
64-
} else {
65-
return false;
66-
}
67-
68-
};
69-
70-
foreach ($array as $value) {
71-
72-
if ($match($value, $array, $arrayToMatch)) {
73-
//unset($array[$key], $arrayToMatch[$key]);
74-
} else {
75-
return -1;
76-
}
77-
}
25+
return true;
7826
}
7927

80-
28+
8129
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace JsonMatcher\Matcher;
4+
5+
use JsonMatcher\Matcher\PropertyMatcher;
6+
use Symfony\Component\PropertyAccess\PropertyAccess;
7+
use Symfony\Component\PropertyAccess\Exception\NoSuchIndexException;
8+
class ArrayMatcher implements PropertyMatcher
9+
{
10+
/**
11+
* @var Matcher\PropertyMatcher
12+
*/
13+
private $propertyMatcher;
14+
15+
public function __construct(PropertyMatcher $propertyMatcher)
16+
{
17+
$this->propertyMatcher = $propertyMatcher;
18+
}
19+
20+
public function match($matcher, $pattern)
21+
{
22+
$accessorBuilder = PropertyAccess::createPropertyAccessorBuilder();
23+
$accessorBuilder->enableExceptionOnInvalidIndex();
24+
$accessor = $accessorBuilder->getPropertyAccessor();
25+
26+
$paths = [];
27+
foreach ($matcher as $key => $element) {
28+
$path = sprintf("[%s]", $key);
29+
30+
if (is_array($element)) {
31+
$this->buildPath($element, $path);
32+
continue;
33+
}
34+
35+
$paths[] = $path;
36+
}
37+
38+
foreach ($paths as $path) {
39+
$value = $accessor->getValue($matcher, $path);
40+
try {
41+
$patternValue = $accessor->getValue($pattern, $path);
42+
} catch (NoSuchIndexException $e) {
43+
return false;
44+
}
45+
46+
if ($this->propertyMatcher->canMatch($patternValue)) {
47+
if (false === $this->propertyMatcher->match($value, $patternValue)) {
48+
return false;
49+
}
50+
}
51+
52+
}
53+
54+
return true;
55+
}
56+
57+
public function canMatch($pattern)
58+
{
59+
return is_array($pattern);
60+
}
61+
62+
63+
private function buildPath(array $array, $parentPath)
64+
{
65+
foreach ($array as $key => $element) {
66+
$path = sprintf("%s[%s]", $parentPath, $key);
67+
68+
if (is_array($element)) {
69+
$this->buildPath($element, $path);
70+
continue;
71+
}
72+
73+
$this->paths[] = $path;
74+
}
75+
}
76+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace JsonMatcher\Matcher;
4+
5+
class ChainMatcher implements PropertyMatcher
6+
{
7+
private $matchers;
8+
9+
public function __construct(array $matchers = array())
10+
{
11+
$this->matchers = $matchers;
12+
}
13+
14+
public function addMatcher(PropertyMatcher $matcher)
15+
{
16+
$this->matchers[] = $matcher;
17+
}
18+
19+
/**
20+
* {@inheritDoc}
21+
*/
22+
public function match($matcher, $pattern)
23+
{
24+
foreach ($this->matchers as $m) {
25+
if (false === $m->match($matcher, $pattern)) {
26+
return false;
27+
}
28+
}
29+
30+
return true;
31+
}
32+
33+
public function canMatch($pattern)
34+
{
35+
return true;
36+
}
37+
38+
39+
/**
40+
* {@inheritDoc}
41+
*/
42+
public function getName()
43+
{
44+
return 'chain';
45+
}
46+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace JsonMatcher\Matcher;
4+
5+
interface PropertyMatcher
6+
{
7+
public function match($matcher, $pattern);
8+
9+
public function canMatch($pattern);
10+
11+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace JsonMatcher\Matcher;
4+
5+
class ScalarMatcher implements PropertyMatcher
6+
{
7+
8+
/**
9+
* {@inheritDoc}
10+
*/
11+
public function match($matcher, $pattern)
12+
{
13+
return $matcher === $pattern;
14+
}
15+
16+
public function canMatch($pattern)
17+
{
18+
return is_scalar($pattern);
19+
}
20+
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace JsonMatcher\Matcher;
4+
5+
class TypeMatcher implements PropertyMatcher
6+
{
7+
8+
/**
9+
* {@inheritDoc}
10+
*/
11+
public function match($matcher, $pattern)
12+
{
13+
return gettype($matcher) === $this->extractType($pattern);
14+
}
15+
16+
public function canMatch($pattern)
17+
{
18+
return is_scalar($pattern);
19+
}
20+
21+
private function extractType($pattern)
22+
{
23+
return str_replace("@", "", $pattern);
24+
}
25+
26+
}

0 commit comments

Comments
 (0)