Skip to content

Commit

Permalink
Fix After/Before expanders error message when date/time is equal to b…
Browse files Browse the repository at this point in the history
…oundary
  • Loading branch information
Stephane Leveugle committed Apr 23, 2024
1 parent 2d82377 commit 1dcd6bb
Show file tree
Hide file tree
Showing 9 changed files with 719 additions and 801 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"ext-filter": "*",
"ext-json": "*",
"ext-simplexml": "*",
"aeon-php/calendar": "^1.0",
"aeon-php/calendar": "^1.0.6",
"coduo/php-to-string": "^3",
"doctrine/lexer": "^3.0"
},
Expand Down
244 changes: 128 additions & 116 deletions composer.lock

Large diffs are not rendered by default.

121 changes: 8 additions & 113 deletions src/Matcher/Pattern/Expander/After.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,139 +5,34 @@
namespace Coduo\PHPMatcher\Matcher\Pattern\Expander;

use Aeon\Calendar\Gregorian\DateTime;
use Aeon\Calendar\Gregorian\Time;
use Coduo\PHPMatcher\Matcher\Pattern\PatternExpander;
use Coduo\ToString\StringConverter;

final class After implements PatternExpander
{
use BacktraceBehavior;
use DateTimeComparisonTrait;

/**
* @var string
*/
public const NAME = 'after';

private ?DateTime $boundaryDateTime;

private ?Time $boundaryTime;

private ?string $error;

public function __construct($boundary)
{
$this->error = null;
$this->boundaryTime = null;
$this->boundaryDateTime = null;

if (!\is_string($boundary)) {
$this->error = \sprintf('After expander require "string", got "%s".', new StringConverter($boundary));
}

try {
$this->boundaryDateTime = DateTime::fromString($boundary);
} catch (\Exception $exception) {
try {
$this->boundaryTime = Time::fromString($boundary);
} catch (\Exception $exception) {
throw new \InvalidArgumentException(\sprintf('Boundary value "%s" is not a valid date, date time or time.', new StringConverter($boundary)));
}
}
}

public static function is(string $name) : bool
{
return self::NAME === $name;
}

public function match($value) : bool
protected function handleComparison(string $value, DateTime $datetime) : bool
{
$this->backtrace->expanderEntrance(self::NAME, $value);

if (!\is_string($value)) {
$this->error = \sprintf('After expander require "string", got "%s".', new StringConverter($value));
if ($datetime->isBeforeOrEqualTo($this->boundary)) {
$this->error = \sprintf('Value "%s" is before or equal to "%s".', new StringConverter($value), new StringConverter($this->boundary));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}

if ($this->boundaryDateTime instanceof DateTime) {
return $this->compareDateTime($value);
}
$this->backtrace->expanderSucceed(self::NAME, $value);

return $this->compareTime($value);
return true;
}

public function getError() : ?string
protected static function getName() : string
{
return $this->error;
}

/**
* @param string $value
*
* @return bool
*/
private function compareDateTime(string $value) : bool
{
try {
$datetime = DateTime::fromString($value);

if ($datetime->isBefore($this->boundaryDateTime)) {
$this->error = \sprintf('Value "%s" is after "%s".', new StringConverter($value), new StringConverter($this->boundaryDateTime));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}

$result = $datetime->isAfter($this->boundaryDateTime);

if ($result) {
$this->backtrace->expanderSucceed(self::NAME, $value);
} else {
$this->backtrace->expanderFailed(self::NAME, $value, '');
}

return $result;
} catch (\Exception $e) {
$this->error = \sprintf('Value "%s" is not a valid date.', new StringConverter($value));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}
}

/**
* @param string $value
*
* @return bool
*/
private function compareTime(string $value) : bool
{
try {
$datetime = Time::fromString($value);

if ($datetime->isLessThan($this->boundaryTime)) {
$this->error = \sprintf('Value "%s" is after "%s".', new StringConverter($value), new StringConverter($this->boundaryTime));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}

$result = $datetime->isGreaterThan($this->boundaryTime);

if ($result) {
$this->backtrace->expanderSucceed(self::NAME, $value);
} else {
$this->backtrace->expanderFailed(self::NAME, $value, '');
}

return $result;
} catch (\Exception $e) {
$this->error = \sprintf('Value "%s" is not a valid time.', new StringConverter($value));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}
return self::NAME;
}
}
121 changes: 8 additions & 113 deletions src/Matcher/Pattern/Expander/Before.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,139 +5,34 @@
namespace Coduo\PHPMatcher\Matcher\Pattern\Expander;

use Aeon\Calendar\Gregorian\DateTime;
use Aeon\Calendar\Gregorian\Time;
use Coduo\PHPMatcher\Matcher\Pattern\PatternExpander;
use Coduo\ToString\StringConverter;

final class Before implements PatternExpander
{
use BacktraceBehavior;
use DateTimeComparisonTrait;

/**
* @var string
*/
public const NAME = 'before';

private ?DateTime $boundaryDateTime;

private ?Time $boundaryTime;

private ?string $error;

public function __construct(string $boundary)
{
$this->error = null;
$this->boundaryTime = null;
$this->boundaryDateTime = null;

if (!\is_string($boundary)) {
throw new \InvalidArgumentException(\sprintf('Before expander require "string", got "%s".', new StringConverter($boundary)));
}

try {
$this->boundaryDateTime = DateTime::fromString($boundary);
} catch (\Exception $exception) {
try {
$this->boundaryTime = Time::fromString($boundary);
} catch (\Exception $exception) {
throw new \InvalidArgumentException(\sprintf('Boundary value "%s" is not a valid date, date time or time.', new StringConverter($boundary)));
}
}
}

public static function is(string $name) : bool
{
return self::NAME === $name;
}

public function match($value) : bool
protected function handleComparison(string $value, DateTime $datetime) : bool
{
$this->backtrace->expanderEntrance(self::NAME, $value);

if (!\is_string($value)) {
$this->error = \sprintf('Before expander require "string", got "%s".', new StringConverter($value));
if ($datetime->isAfterOrEqualTo($this->boundary)) {
$this->error = \sprintf('Value "%s" is after or equal to "%s".', $value, new StringConverter($this->boundary));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}

if ($this->boundaryDateTime instanceof DateTime) {
return $this->compareDateTime($value);
}
$this->backtrace->expanderSucceed(self::NAME, $value);

return $this->compareTime($value);
return true;
}

public function getError() : ?string
protected static function getName() : string
{
return $this->error;
}

/**
* @param string $value
*
* @return bool
*/
private function compareDateTime(string $value) : bool
{
try {
$datetime = DateTime::fromString($value);

if ($datetime->isAfter($this->boundaryDateTime)) {
$this->error = \sprintf('Value "%s" is before "%s".', new StringConverter($value), new StringConverter($this->boundaryDateTime));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}

$result = $datetime->isBefore($this->boundaryDateTime);

if ($result) {
$this->backtrace->expanderSucceed(self::NAME, $value);
} else {
$this->backtrace->expanderFailed(self::NAME, $value, '');
}

return $result;
} catch (\Exception $e) {
$this->error = \sprintf('Value "%s" is not a valid date.', new StringConverter($value));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}
}

/**
* @param string $value
*
* @return bool
*/
private function compareTime(string $value) : bool
{
try {
$datetime = Time::fromString($value);

if ($datetime->isGreaterThan($this->boundaryTime)) {
$this->error = \sprintf('Value "%s" is before "%s".', new StringConverter($value), new StringConverter($this->boundaryTime));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}

$result = $datetime->isLessThan($this->boundaryTime);

if ($result) {
$this->backtrace->expanderSucceed(self::NAME, $value);
} else {
$this->backtrace->expanderFailed(self::NAME, $value, '');
}

return $result;
} catch (\Exception $e) {
$this->error = \sprintf('Value "%s" is not a valid time.', new StringConverter($value));
$this->backtrace->expanderFailed(self::NAME, $value, $this->error);

return false;
}
return self::NAME;
}
}
76 changes: 76 additions & 0 deletions src/Matcher/Pattern/Expander/DateTimeComparisonTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace Coduo\PHPMatcher\Matcher\Pattern\Expander;

use Aeon\Calendar\Gregorian\DateTime;
use Coduo\ToString\StringConverter;

trait DateTimeComparisonTrait
{
use BacktraceBehavior;

private readonly DateTime $boundary;

private ?string $error = null;

public function __construct(string $boundary)
{
if (!\is_string($boundary)) {
throw new \InvalidArgumentException(\sprintf('Before expander require "string", got "%s".', new StringConverter($boundary)));
}

try {
$this->boundary = DateTime::fromString($boundary);
} catch (\Exception $exception) {
throw new \InvalidArgumentException(\sprintf('Boundary value "%s" is not a valid date, date time or time.', new StringConverter($boundary)));
}
}

public static function is(string $name) : bool
{
return static::getName() === $name;
}

public function match($value) : bool
{
$this->backtrace->expanderEntrance(static::getName(), $value);

if (!\is_string($value)) {
$this->error = \sprintf('%s expander require "string", got "%s".', static::getName(), new StringConverter($value));
$this->backtrace->expanderFailed(static::getName(), $value, $this->error);

return false;
}

return $this->compare($value);
}

public function getError() : ?string
{
return $this->error;
}

abstract protected static function getName() : string;

/**
* @param string $value raw value
* @param DateTime $datetime value converted in DateTime object
*/
abstract protected function handleComparison(string $value, DateTime $datetime) : bool;

private function compare(string $value) : bool
{
try {
$datetime = DateTime::fromString($value);
} catch (\Exception $e) {
$this->error = \sprintf('Value "%s" is not a valid date, date time or time.', new StringConverter($value));
$this->backtrace->expanderFailed(static::getName(), $value, $this->error);

return false;
}

return $this->handleComparison($value, $datetime);
}
}
Loading

0 comments on commit 1dcd6bb

Please sign in to comment.