diff --git a/README.md b/README.md index fd20ac78..ec6a6bda 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,22 @@ $matcher->match("lorem ipsum dolor", "@string@.startsWith('lorem').contains('ips ``` +### Date matching + +```php +createMatcher(); + +$matcher->match('2014-08-19', '@string@.isDateTime()'); +$matcher->match('2014-08-19', '@string@.isDateTime().before("2016-08-19")'); +$matcher->match('2014-08-19', '@string@.isDateTime().before("today").after("+ 100year")'); + +``` + ### Integer matching ```php diff --git a/src/Matcher/Pattern/Expander/After.php b/src/Matcher/Pattern/Expander/After.php new file mode 100644 index 00000000..8369f68a --- /dev/null +++ b/src/Matcher/Pattern/Expander/After.php @@ -0,0 +1,74 @@ +error = \sprintf('After expander require "string", got "%s".', new StringConverter($boundary)); + return false; + } + + if (!$this->is_datetime($boundary)) { + throw new \InvalidArgumentException(\sprintf('Boundary value "%s" is not a valid date.', new StringConverter($boundary))); + } + + $this->boundary = new \DateTime($boundary); + } + + public static function is(string $name) : bool + { + return self::NAME === $name; + } + + public function match($value) : bool + { + if (false === \is_string($value)) { + $this->error = \sprintf('After expander require "string", got "%s".', new StringConverter($value)); + return false; + } + + if (!$this->is_datetime($value)) { + $this->error = \sprintf('Value "%s" is not a valid date.', new StringConverter($value)); + return false; + } + + $value = new \DateTime($value); + + if ($value <= $this->boundary) { + $this->error = \sprintf('Value "%s" is not after "%s".', new StringConverter($value), new StringConverter($this->boundary)); + return false; + } + + return $value > $this->boundary; + } + + private function is_datetime(string $value) : bool + { + try { + new \DateTime($value); + return true; + } catch (\Exception $e) { + return false; + } + } + + public function getError() + { + return $this->error; + } +} diff --git a/src/Matcher/Pattern/Expander/Before.php b/src/Matcher/Pattern/Expander/Before.php new file mode 100644 index 00000000..5803d576 --- /dev/null +++ b/src/Matcher/Pattern/Expander/Before.php @@ -0,0 +1,73 @@ +is_datetime($boundary)) { + throw new \InvalidArgumentException(\sprintf('Boundary value "%s" is not a valid date.', new StringConverter($boundary))); + } + + $this->boundary = new \DateTime($boundary); + } + + public static function is(string $name) : bool + { + return self::NAME === $name; + } + + public function match($value) : bool + { + if (!\is_string($value)) { + $this->error = \sprintf('Before expander require "string", got "%s".', new StringConverter($value)); + return false; + } + + if (!$this->is_datetime($value)) { + $this->error = \sprintf('Value "%s" is not a valid date.', new StringConverter($value)); + return false; + } + + $value = new \DateTime($value); + + if ($value >= $this->boundary) { + $this->error = \sprintf('Value "%s" is before "%s".', new StringConverter($value), new StringConverter($this->boundary)); + return false; + } + + return $value < $this->boundary; + } + + private function is_datetime(string $value) : bool + { + try { + new \DateTime($value); + return true; + } catch (\Exception $e) { + return false; + } + } + + public function getError() + { + return $this->error; + } +} diff --git a/src/Parser/ExpanderInitializer.php b/src/Parser/ExpanderInitializer.php index a52597f7..81f053b6 100644 --- a/src/Parser/ExpanderInitializer.php +++ b/src/Parser/ExpanderInitializer.php @@ -15,6 +15,8 @@ final class ExpanderInitializer { private $expanderDefinitions = [ + Expander\After::NAME => Expander\After::class, + Expander\Before::NAME => Expander\Before::class, Expander\Contains::NAME => Expander\Contains::class, Expander\Count::NAME => Expander\Count::class, Expander\EndsWith::NAME => Expander\EndsWith::class, diff --git a/tests/Matcher/Pattern/Expander/AfterTest.php b/tests/Matcher/Pattern/Expander/AfterTest.php new file mode 100644 index 00000000..4f3ce2e6 --- /dev/null +++ b/tests/Matcher/Pattern/Expander/AfterTest.php @@ -0,0 +1,48 @@ +assertEquals($expectedResult, $expander->match($value)); + } + + public static function examplesProvider() + { + return [ + ['+ 2 day','today',false], + ['2018-02-06T04:20:33','2017-02-06T04:20:33',false], + ['2017-02-06T04:20:33','2018-02-06T04:20:33',true], + ]; + } + + /** + * @dataProvider invalidCasesProvider + */ + public function test_error_when_matching_fail($boundary, $value, $errorMessage) + { + $expander = new After($boundary); + $this->assertFalse($expander->match($value)); + $this->assertEquals($errorMessage, $expander->getError()); + } + + public static function invalidCasesProvider() + { + return [ + ['today', 'ipsum lorem', 'Value "ipsum lorem" is not a valid date.'], + ['2017-02-06T04:20:33', 'ipsum lorem', 'Value "ipsum lorem" is not a valid date.'], + ['today',5, 'After expander require "string", got "5".'], + ]; + } +} diff --git a/tests/Matcher/Pattern/Expander/BeforeTest.php b/tests/Matcher/Pattern/Expander/BeforeTest.php new file mode 100644 index 00000000..afb9b57b --- /dev/null +++ b/tests/Matcher/Pattern/Expander/BeforeTest.php @@ -0,0 +1,48 @@ +assertEquals($expectedResult, $expander->match($value)); + } + + public static function examplesProvider() + { + return [ + ['+ 2 day','today',true], + ['2018-02-06T04:20:33','2017-02-06T04:20:33',true], + ['2017-02-06T04:20:33','2018-02-06T04:20:33',false], + ]; + } + + /** + * @dataProvider invalidCasesProvider + */ + public function test_error_when_matching_fail($boundary, $value, $errorMessage) + { + $expander = new Before($boundary); + $this->assertFalse($expander->match($value)); + $this->assertEquals($errorMessage, $expander->getError()); + } + + public static function invalidCasesProvider() + { + return [ + ['today', 'ipsum lorem', 'Value "ipsum lorem" is not a valid date.'], + ['2017-02-06T04:20:33', 'ipsum lorem', 'Value "ipsum lorem" is not a valid date.'], + ['today',5, 'Before expander require "string", got "5".'], + ]; + } +} diff --git a/tests/MatcherTest.php b/tests/MatcherTest.php index 40ee2f40..449a1015 100644 --- a/tests/MatcherTest.php +++ b/tests/MatcherTest.php @@ -359,6 +359,10 @@ public static function expanderExamples() ['http://coduo.pl/', '@string@.isUrl()', true], ['lorem ipsum', '@string@.isUrl()', false], ['2014-08-19', '@string@.isDateTime()', true], + ['3014-08-19', '@string@.before("today")', false], + ['1014-08-19', '@string@.before("+ 1day")', true], + ['3014-08-19', '@string@.after("today")', true], + ['1014-08-19', '@string@.after("+ 1day")', false], [100, '@integer@.lowerThan(101).greaterThan(10)', true], ['', '@string@.isNotEmpty()', false], ['lorem ipsum', '@string@.isNotEmpty()', true],