Skip to content

Commit

Permalink
Allow to mark JSON properties & XML nodes as optional (#102) (#107)
Browse files Browse the repository at this point in the history
* Allow to mark JSON properties & XML nodes as optional (#102)

* Add optional expander definition

* Add hasExpander method for Pattern

* Allow mark JSON properties & xml nodes as optional

* Use intuitive matcher type definition in Xml test stock qty node definition

* Add information about optional Expander to README

* Remove return type declaration

* Catch PHPMatcher Exception when parsing pattern for optional values

* Add getName to PatternExpander interface

* Remove unncessary ExpanderInitializer dependency in TypePattern

* Use constants for expander name instead of method

* Redeclare $expanderDefinitions using constants

* Add static is($name) method to PatternExpander interface

* revert php 7.0 feature

* drop php 5.3, 5.4 support

* Use proper test case base class

* Use proper test case base class

* Fixed has expander method
  • Loading branch information
norberttech authored Sep 4, 2017
1 parent 5be920e commit 79a27d1
Show file tree
Hide file tree
Showing 26 changed files with 503 additions and 33 deletions.
5 changes: 1 addition & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ cache:

matrix:
include:
- php: 5.3
- php: 5.6
env: DEPENDENCIES='low'
- php: 5.3
- php: 5.4
- php: 5.5
- php: 5.6
- php: 7.0
- php: 7.1
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ $matcher->getError(); // returns null or error message
* ``inArray($value)``
* ``oneOf(...$expanders)`` - example usage ``"@[email protected](contains('foo'), contains('bar'), contains('baz'))"``
* ``matchRegex($regex)`` - example usage ``"@[email protected]('/^lorem.+/')"``
* ``optional()`` - work's only with ``ArrayMatcher``, ``JsonMatcher`` and ``XmlMatcher``

##Example usage

Expand Down Expand Up @@ -237,7 +238,8 @@ $matcher->match(
'id' => 1,
'firstName' => 'Norbert',
'lastName' => 'Orzechowicz',
'roles' => array('ROLE_USER')
'roles' => array('ROLE_USER'),
'position' => 'Developer',
),
array(
'id' => 2,
Expand All @@ -261,7 +263,8 @@ $matcher->match(
'id' => '@[email protected](0)',
'firstName' => '@string@',
'lastName' => 'Orzechowicz',
'roles' => '@array@'
'roles' => '@array@',
'position' => '@[email protected]()'
),
array(
'id' => '@integer@',
Expand Down Expand Up @@ -303,7 +306,8 @@ $matcher->match(
"firstName": @string@,
"lastName": @string@,
"created": "@[email protected]()",
"roles": @array@
"roles": @array@,
"posiiton": "@[email protected]()"
}
]
}'
Expand Down Expand Up @@ -347,6 +351,7 @@ XML
<m:GetStockPrice>
<m:StockName>@string@</m:StockName>
<m:StockValue>@string@</m:StockValue>
<m:StockQty>@[email protected]()</m:StockQty>
</m:GetStockPrice>
</soap:Body>

Expand Down
40 changes: 39 additions & 1 deletion src/Matcher/ArrayMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Coduo\PHPMatcher\Matcher;

use Coduo\PHPMatcher\Exception\Exception;
use Coduo\PHPMatcher\Parser;
use Coduo\ToString\StringConverter;
use Symfony\Component\PropertyAccess\PropertyAccess;
Expand Down Expand Up @@ -144,19 +145,56 @@ private function iterateMatch(array $values, array $patterns, $parentPath = "")
private function isPatternValid(array $pattern, array $values, $parentPath)
{
if (is_array($pattern)) {
$notExistingKeys = array_diff_key($pattern, $values);
$skipPattern = static::UNBOUNDED_PATTERN;

$pattern = array_filter(
$pattern,
function ($item) use ($skipPattern) {
return $item !== $skipPattern;
}
);

$notExistingKeys = $this->findNotExistingKeys($pattern, $values);

if (count($notExistingKeys) > 0) {
$keyNames = array_keys($notExistingKeys);
$path = $this->formatFullPath($parentPath, $this->formatAccessPath($keyNames[0]));
$this->setMissingElementInError('value', $path);

return false;
}
}

return true;
}

/**
* Finds not existing keys
* Excludes keys with pattern which includes Optional Expander
*
* @param $pattern
* @param $values
* @return array
*/
private function findNotExistingKeys($pattern, $values)
{
$notExistingKeys = array_diff_key($pattern, $values);

return array_filter($notExistingKeys, function ($pattern) use ($values) {
if (is_array($pattern)) {
return !$this->match($values, $pattern);
}

try {
$typePattern = $this->parser->parse($pattern);
} catch (Exception $e) {
return true;
}

return !$typePattern->hasExpander('optional');
});
}

/**
* @param $value
* @param $pattern
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/Contains.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

final class Contains implements PatternExpander
{
const NAME = 'contains';

/**
* @var null|string
*/
Expand All @@ -22,6 +24,14 @@ final class Contains implements PatternExpander
*/
private $ignoreCase;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param $string
* @param bool $ignoreCase
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/Count.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

final class Count implements PatternExpander
{
const NAME = 'count';

/**
* @var null|string
*/
Expand All @@ -17,6 +19,14 @@ final class Count implements PatternExpander
*/
private $value;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param $value
*/
Expand Down
12 changes: 11 additions & 1 deletion src/Matcher/Pattern/Expander/EndsWith.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

final class EndsWith implements PatternExpander
{
const NAME = 'endsWith';

/**
* @var
*/
Expand All @@ -22,6 +24,14 @@ final class EndsWith implements PatternExpander
*/
private $ignoreCase;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param string $stringEnding
* @param bool $ignoreCase
Expand All @@ -31,7 +41,7 @@ public function __construct($stringEnding, $ignoreCase = false)
if (!is_string($stringEnding)) {
throw new \InvalidArgumentException("String ending must be a valid string.");
}

$this->stringEnding = $stringEnding;
$this->ignoreCase = $ignoreCase;
}
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/GreaterThan.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

final class GreaterThan implements PatternExpander
{
const NAME = 'greaterThan';

/**
* @var
*/
Expand All @@ -17,6 +19,14 @@ final class GreaterThan implements PatternExpander
*/
private $error;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param $boundary
*/
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/InArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

final class InArray implements PatternExpander
{
const NAME = 'inArray';

/**
* @var null|string
*/
Expand All @@ -17,6 +19,14 @@ final class InArray implements PatternExpander
*/
private $value;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param $value
*/
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/IsDateTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,21 @@

final class IsDateTime implements PatternExpander
{
const NAME = 'isDateTime';

/**
* @var null|string
*/
private $error;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param string $value
* @return boolean
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/IsEmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,21 @@

final class IsEmail implements PatternExpander
{
const NAME = 'isEmail';

/**
* @var null|string
*/
private $error;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param string $value
* @return boolean
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/IsEmpty.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@

final class IsEmpty implements PatternExpander
{
const NAME = 'isEmpty';

private $error;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param mixed $value
*
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/IsNotEmpty.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@

final class IsNotEmpty implements PatternExpander
{
const NAME = 'isNotEmpty';

private $error;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param $value
* @return boolean
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/IsUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,21 @@

final class IsUrl implements PatternExpander
{
const NAME = 'isUrl';

/**
* @var null|string
*/
private $error;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param string $value
* @return boolean
Expand Down
10 changes: 10 additions & 0 deletions src/Matcher/Pattern/Expander/LowerThan.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

final class LowerThan implements PatternExpander
{
const NAME = 'lowerThan';

/**
* @var
*/
Expand All @@ -17,6 +19,14 @@ final class LowerThan implements PatternExpander
*/
private $error;

/**
* {@inheritdoc}
*/
public static function is($name)
{
return self::NAME === $name;
}

/**
* @param $boundary
*/
Expand Down
Loading

0 comments on commit 79a27d1

Please sign in to comment.