Skip to content

Commit 9e2e519

Browse files
authored
added HasProperty pattern expander (#185)
* added HasProperty pattern expander * CS Fixes
1 parent a93f851 commit 9e2e519

27 files changed

+167
-24
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ $matcher->getError(); // returns null or error message
9090
* ``lowerThan($boundry)``
9191
* ``greaterThan($boundry)``
9292
* ``inArray($value)``
93+
* ``hasProperty($propertyName)`` - example ``"@[email protected](\"property_name\")"``
9394
* ``oneOf(...$expanders)`` - example ``"@[email protected](contains('foo'), contains('bar'), contains('baz'))"``
9495
* ``matchRegex($regex)`` - example ``"@[email protected]('/^lorem.+/')"``
9596
* ``optional()`` - work's only with ``ArrayMatcher``, ``JsonMatcher`` and ``XmlMatcher``

src/Matcher/Pattern/Expander/After.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class After implements PatternExpander
1111
{
12-
const NAME = 'after';
12+
public const NAME = 'after';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/Before.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class Before implements PatternExpander
1111
{
12-
const NAME = 'before';
12+
public const NAME = 'before';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/Contains.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class Contains implements PatternExpander
1111
{
12-
const NAME = 'contains';
12+
public const NAME = 'contains';
1313

1414
use BacktraceBehavior;
1515

@@ -51,7 +51,7 @@ public function match($value) : bool
5151
}
5252

5353
$this->backtrace->expanderSucceed(self::NAME, $value);
54-
54+
5555
return true;
5656
}
5757

src/Matcher/Pattern/Expander/Count.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class Count implements PatternExpander
1111
{
12-
const NAME = 'count';
12+
public const NAME = 'count';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/EndsWith.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class EndsWith implements PatternExpander
1111
{
12-
const NAME = 'endsWith';
12+
public const NAME = 'endsWith';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/GreaterThan.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class GreaterThan implements PatternExpander
1111
{
12-
const NAME = 'greaterThan';
12+
public const NAME = 'greaterThan';
1313

1414
use BacktraceBehavior;
1515

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Coduo\PHPMatcher\Matcher\Pattern\Expander;
6+
7+
use Coduo\PHPMatcher\Matcher\Pattern\Assert\Json;
8+
use Coduo\PHPMatcher\Matcher\Pattern\PatternExpander;
9+
use Coduo\ToString\StringConverter;
10+
11+
final class HasProperty implements PatternExpander
12+
{
13+
public const NAME = 'hasProperty';
14+
15+
use BacktraceBehavior;
16+
17+
private $propertyName;
18+
private $error;
19+
20+
public function __construct($propertyName)
21+
{
22+
$this->propertyName = $propertyName;
23+
}
24+
25+
public static function is(string $name): bool
26+
{
27+
return self::NAME === $name;
28+
}
29+
30+
public function match($value): bool
31+
{
32+
$this->backtrace->expanderEntrance(self::NAME, $value);
33+
34+
if (\is_array($value)) {
35+
$hasProperty = \array_key_exists($this->propertyName, $value);
36+
37+
if (!$hasProperty) {
38+
$this->error = \sprintf('"json" object "%s" does not have "%s" propety.', new StringConverter($value), new StringConverter($this->propertyName));
39+
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);
40+
41+
return false;
42+
}
43+
44+
$this->backtrace->expanderSucceed(self::NAME, $value);
45+
46+
return true;
47+
}
48+
49+
if (!Json::isValid($value)) {
50+
$this->error = \sprintf('HasProperty expander require valid "json" string, got "%s".', new StringConverter($value));
51+
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);
52+
53+
return false;
54+
}
55+
56+
$jsonArray = \json_decode(Json::reformat($value), true);
57+
58+
$hasProperty = \array_key_exists($this->propertyName, $jsonArray);
59+
60+
if (!$hasProperty) {
61+
$this->error = \sprintf('"json" object "%s" does not have "%s" propety.', new StringConverter($value), new StringConverter($this->propertyName));
62+
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);
63+
64+
return false;
65+
}
66+
67+
$this->backtrace->expanderSucceed(self::NAME, $value);
68+
69+
return true;
70+
}
71+
72+
public function getError(): ?string
73+
{
74+
return $this->error;
75+
}
76+
}

src/Matcher/Pattern/Expander/InArray.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class InArray implements PatternExpander
1111
{
12-
const NAME = 'inArray';
12+
public const NAME = 'inArray';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/IsDateTime.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class IsDateTime implements PatternExpander
1111
{
12-
const NAME = 'isDateTime';
12+
public const NAME = 'isDateTime';
1313

1414
use BacktraceBehavior;
1515

@@ -39,7 +39,7 @@ public function match($value) : bool
3939
}
4040

4141
$this->backtrace->expanderSucceed(self::NAME, $value);
42-
42+
4343
return true;
4444
}
4545

src/Matcher/Pattern/Expander/IsEmail.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class IsEmail implements PatternExpander
1111
{
12-
const NAME = 'isEmail';
12+
public const NAME = 'isEmail';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/IsEmpty.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class IsEmpty implements PatternExpander
1111
{
12-
const NAME = 'isEmpty';
12+
public const NAME = 'isEmpty';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/IsIp.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class IsIp implements PatternExpander
1111
{
12-
const NAME = 'isIp';
12+
public const NAME = 'isIp';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/IsNotEmpty.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class IsNotEmpty implements PatternExpander
1111
{
12-
const NAME = 'isNotEmpty';
12+
public const NAME = 'isNotEmpty';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/IsUrl.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class IsUrl implements PatternExpander
1111
{
12-
const NAME = 'isUrl';
12+
public const NAME = 'isUrl';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/LowerThan.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class LowerThan implements PatternExpander
1111
{
12-
const NAME = 'lowerThan';
12+
public const NAME = 'lowerThan';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/Match.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class Match implements Matcher\Pattern\PatternExpander
1111
{
12-
const NAME = 'match';
12+
public const NAME = 'match';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/MatchRegex.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class MatchRegex implements PatternExpander
1111
{
12-
const NAME = 'matchRegex';
12+
public const NAME = 'matchRegex';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/NotContains.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class NotContains implements PatternExpander
1111
{
12-
const NAME = 'notContains';
12+
public const NAME = 'notContains';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/OneOf.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class OneOf implements PatternExpander
1111
{
12-
const NAME = 'oneOf';
12+
public const NAME = 'oneOf';
1313

1414
use BacktraceBehavior;
1515

src/Matcher/Pattern/Expander/Optional.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
final class Optional implements PatternExpander
1010
{
11-
const NAME = 'optional';
11+
public const NAME = 'optional';
1212

1313
use BacktraceBehavior;
1414

src/Matcher/Pattern/Expander/Repeat.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
final class Repeat implements PatternExpander
1313
{
14-
const NAME = 'repeat';
14+
public const NAME = 'repeat';
1515

1616
use BacktraceBehavior;
1717

src/Matcher/Pattern/Expander/StartsWith.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
final class StartsWith implements PatternExpander
1111
{
12-
const NAME = 'startsWith';
12+
public const NAME = 'startsWith';
1313

1414
use BacktraceBehavior;
1515

src/Parser/ExpanderInitializer.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ final class ExpanderInitializer
3636
Expander\Optional::NAME => Expander\Optional::class,
3737
Expander\StartsWith::NAME => Expander\StartsWith::class,
3838
Expander\Repeat::NAME => Expander\Repeat::class,
39-
Expander\Match::NAME => Expander\Match::class
39+
Expander\Match::NAME => Expander\Match::class,
40+
Expander\HasProperty::NAME => Expander\HasProperty::class
4041
];
4142

4243
private $backtrace;

tests/Matcher/JsonObjectMatcherTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ public static function positiveMatches()
5757
'{"users":["Norbert","Michał"]}',
5858
'@[email protected]("users")'
5959
],
60+
[
61+
'{"users":["Norbert","Michał"]}',
62+
'@[email protected]("users")'
63+
],
6064
[
6165
[1, 2, 3],
6266
'@json@',
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Coduo\PHPMatcher\Tests\Matcher\Pattern\Expander;
6+
7+
use Coduo\PHPMatcher\Backtrace;
8+
use Coduo\PHPMatcher\Matcher\Pattern\Expander\HasProperty;
9+
use PHPUnit\Framework\TestCase;
10+
11+
class HasPropertyTest extends TestCase
12+
{
13+
/**
14+
* @dataProvider examplesProvider
15+
*/
16+
public function test_examples($propertyName, $value, $expectedResult)
17+
{
18+
$expander = new HasProperty($propertyName);
19+
$expander->setBacktrace(new Backtrace());
20+
$this->assertEquals($expectedResult, $expander->match($value));
21+
}
22+
23+
public static function examplesProvider()
24+
{
25+
return [
26+
['property','{"property":1}',true],
27+
['property','{"property_02":1}',false],
28+
['property',['property' => 1],true],
29+
['property',['property_02' => 1],false],
30+
['property','{"object_nested":{"property": 1}}',false],
31+
];
32+
}
33+
}

tests/MatcherTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,34 @@ public static function nullExamples()
211211
public function jsonDataProvider()
212212
{
213213
return [
214+
[
215+
'{"data": {"createUserFormSchema":{"formData":"test","schema":"test","uiSchema":"test"}}}',
216+
'{"data": {"createUserFormSchema":"@[email protected](\"formData\").hasProperty(\"schema\").hasProperty(\"uiSchema\")"}}'
217+
],
218+
[
219+
/** @lang JSON */
220+
'{
221+
"users":[
222+
{
223+
"id": 131,
224+
"firstName": "Norbert",
225+
"lastName": "Orzechowicz",
226+
"enabled": true,
227+
"roles": ["ROLE_DEVELOPER"]
228+
},
229+
{
230+
"id": 132,
231+
"firstName": "Michał",
232+
"lastName": "Dąbrowski",
233+
"enabled": false,
234+
"roles": ["ROLE_DEVELOPER"]
235+
}
236+
],
237+
"prevPage": "http:\/\/example.com\/api\/users\/1?limit=2",
238+
"nextPage": "http:\/\/example.com\/api\/users\/3?limit=2"
239+
}',
240+
'@[email protected]("users")'
241+
],
214242
[
215243
/** @lang JSON */
216244
'{

0 commit comments

Comments
 (0)