Skip to content

Commit

Permalink
馃摝 NEW: Add Time validator class
Browse files Browse the repository at this point in the history
  • Loading branch information
elie29 committed Feb 20, 2019
1 parent ae1d10b commit 89b9883
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/Rule/TimeRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types = 1);

namespace Elie\Validator\Rule;

/**
* This class verifies that a value is a time valid format "hh:mm:ss" or "hh:mm".
* We add 0 to the left of the hour so 2:49 => 02:49 and 0 to the right of the
* minutes ans seconds so 3:4 => 03:40:00
*/
class TimeRule extends AbstractRule
{

public const TIME_REGEX = '/^([0-1]{1}[0-9]{1}|[2]{1}[0-3]{1}):[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}$/';

public function validate(): int
{
$run = parent::validate();

if ($run !== RuleInterface::CHECK) {
return $run;
}

if (! static::checkTime($this->value)) {
$this->error = "{$this->key}: {$this->value} is not a valid time";
return RuleInterface::ERROR;
}

return RuleInterface::VALID;
}

/**
* Check if a given time has the following format:
* hh:mm:ss or hh:mm
*
* @param string $time Time to be checked.
*
* @return bool
*/
public static function checkTime($time): bool
{
$tokens = explode(':', $time);

$count = count($tokens);
if ($count < 2 || $count > 3) {
// time must be hh:mm or hh:mm:ss
return false;
}

// seconds are optional
$second = ($count == 3) ? $tokens[2] : '0';

// We put time in hh:mm:ss format with padding
$time = str_pad($tokens[0], 2, '0', STR_PAD_LEFT) . ':'
. str_pad($tokens[1], 2, '0', STR_PAD_RIGHT) . ':'
. str_pad($second, 2, '0', STR_PAD_RIGHT);

// we test hh:mm:ss from 00:00:00 => 23:59:59
return !! preg_match(self::TIME_REGEX, $time);
}
}
56 changes: 56 additions & 0 deletions tests/Rule/TimeRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types = 1);

namespace Elie\Validator\Rule;

use PHPUnit\Framework\TestCase;

class TimeRuleTest extends TestCase
{

/**
* @dataProvider getTimeValueProvider
*/
public function testValidate($value, $expectedResult, $expectedError): void
{
$rule = new TimeRule('time', $value);

$res = $rule->validate();

assertThat($res, identicalTo($expectedResult));

assertThat($rule->getError(), identicalTo($expectedError));
}

public function getTimeValueProvider(): \Generator
{
yield 'Given value could be empty' => [
'', RuleInterface::VALID, ''
];

yield 'Given time 22:25 should be valid' => [
'22:25', RuleInterface::VALID, ''
];

yield 'Given time 22:25:38 should be valid' => [
'22:25:38', RuleInterface::VALID, ''
];

yield 'Given time 8:2:4 should be valid' => [
'8:2:4', RuleInterface::VALID, ''
];

yield 'Given time 25:2 should not be valid' => [
'25:2', RuleInterface::ERROR, 'time: 25:2 is not a valid time'
];

yield 'Given time 21 should not be valid' => [
'21', RuleInterface::ERROR, 'time: 21 is not a valid time'
];

yield 'Given time 20:2:3:6 should not be valid' => [
'20:2:3:6', RuleInterface::ERROR, 'time: 20:2:3:6 is not a valid time'
];
}
}

0 comments on commit 89b9883

Please sign in to comment.