Skip to content

Commit 0653346

Browse files
committed
Create assertion and type-class for xs:date
1 parent 6dc992e commit 0653346

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed

src/Assert/DateTrait.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\XML\Assert;
6+
7+
use InvalidArgumentException;
8+
9+
/**
10+
* @package simplesamlphp/xml-common
11+
*/
12+
trait DateTrait
13+
{
14+
/**
15+
* The ·lexical space· of date consists of finite-length sequences of characters of the form:
16+
* '-'? yyyy '-' mm '-' dd zzzzzz?
17+
*
18+
* where the date and optional timezone are represented exactly the same way as they are for dateTime.
19+
* The first moment of the interval is that represented by:
20+
* '-' yyyy '-' mm '-' dd 'T00:00:00' zzzzzz?
21+
*
22+
* and the least upper bound of the interval is the timeline point represented (noncanonically) by:
23+
* '-' yyyy '-' mm '-' dd 'T24:00:00' zzzzzz?.
24+
*
25+
* @var string
26+
*/
27+
private static string $date_regex = '/^-?([1-9][0-9]*|[0-9]{4})-(((0(1|3|5|7|8)|1(0|2))-(0[1-9]|(1|2)[0-9]|3[0-1]))|((0(4|6|9)|11)-(0[1-9]|(1|2)[0-9]|30))|(02-(0[1-9]|(1|2)[0-9])))((\+|-)([0-1][0-9]|2[0-4]):(0[0-9]|[1-5][0-9])|Z)?$/Di';
28+
29+
30+
/**
31+
* @param string $value
32+
* @param string $message
33+
*/
34+
protected static function validDate(string $value, string $message = ''): void
35+
{
36+
parent::regex(
37+
$value,
38+
self::$date_regex,
39+
$message ?: '%s is not a valid xs:date',
40+
InvalidArgumentException::class,
41+
);
42+
}
43+
}

src/Type/DateValue.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\XML\Type;
6+
7+
use SimpleSAML\XML\Assert\Assert;
8+
use SimpleSAML\XML\Exception\SchemaViolationException;
9+
10+
/**
11+
* @package simplesaml/xml-common
12+
*/
13+
class DateValue extends AbstractValueType
14+
{
15+
/**
16+
* Validate the value.
17+
*
18+
* @param string $value
19+
* @throws \SimpleSAML\XML\Exception\SchemaViolationException on failure
20+
* @return void
21+
*/
22+
protected function validateValue(string $value): void
23+
{
24+
Assert::validDate($value, SchemaViolationException::class);
25+
}
26+
}

tests/Assert/DateTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Test\XML\Assert;
6+
7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use PHPUnit\Framework\TestCase;
10+
use SimpleSAML\Assert\AssertionFailedException;
11+
use SimpleSAML\XML\Assert\Assert;
12+
13+
/**
14+
* Class \SimpleSAML\Test\XML\Assert\DateTest
15+
*
16+
* @package simplesamlphp/xml-common
17+
*/
18+
#[CoversClass(Assert::class)]
19+
final class DateTest extends TestCase
20+
{
21+
/**
22+
* @param boolean $shouldPass
23+
* @param string $date
24+
*/
25+
#[DataProvider('provideDate')]
26+
public function testValidDate(bool $shouldPass, string $date): void
27+
{
28+
try {
29+
Assert::validDate($date);
30+
$this->assertTrue($shouldPass);
31+
} catch (AssertionFailedException $e) {
32+
$this->assertFalse($shouldPass);
33+
}
34+
}
35+
36+
37+
/**
38+
* @return array<string, array{0: bool, 1: string}>
39+
*/
40+
public static function provideDate(): array
41+
{
42+
return [
43+
'valid' => [true, '2001-10-26'],
44+
'valid numeric timezone' => [true, '2001-10-26+02:00'],
45+
'valid Zulu timezone' => [true, '2001-10-26Z'],
46+
'valid 00:00 timezone' => [true, '2001-10-26+00:00'],
47+
'2001 BC' => [true, '-2001-10-26'],
48+
'2000 BC' => [true, '-20000-04-01'],
49+
'missing part' => [false, '2001-10'],
50+
'day out of range' => [false, '2001-10-32'],
51+
'month out of range' => [false, '2001-13-26+02:00'],
52+
'century part missing' => [false, '01-10-26'],
53+
];
54+
}
55+
}

tests/Type/DateValueTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Test\XML\Type;
6+
7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use PHPUnit\Framework\TestCase;
10+
use SimpleSAML\XML\Exception\SchemaViolationException;
11+
use SimpleSAML\XML\Type\DateValue;
12+
13+
/**
14+
* Class \SimpleSAML\Test\Type\DateValueTest
15+
*
16+
* @package simplesamlphp/xml-common
17+
*/
18+
#[CoversClass(DateValue::class)]
19+
final class DateValueTest extends TestCase
20+
{
21+
/**
22+
* @param boolean $shouldPass
23+
* @param string $date
24+
*/
25+
#[DataProvider('provideDate')]
26+
public function testDate(bool $shouldPass, string $date): void
27+
{
28+
try {
29+
DateValue::fromString($date);
30+
$this->assertTrue($shouldPass);
31+
} catch (SchemaViolationException $e) {
32+
$this->assertFalse($shouldPass);
33+
}
34+
}
35+
36+
37+
/**
38+
* @return array<string, array{0: bool, 1: string}>
39+
*/
40+
public static function provideDate(): array
41+
{
42+
return [
43+
'valid' => [true, '2001-10-26'],
44+
'valid numeric timezone' => [true, '2001-10-26+02:00'],
45+
'valid Zulu timezone' => [true, '2001-10-26Z'],
46+
'valid 00:00 timezone' => [true, '2001-10-26+00:00'],
47+
'2001 BC' => [true, '-2001-10-26'],
48+
'2000 BC' => [true, '-20000-04-01'],
49+
'missing part' => [false, '2001-10'],
50+
'day out of range' => [false, '2001-10-32'],
51+
'month out of range' => [false, '2001-13-26+02:00'],
52+
'century part missing' => [false, '01-10-26'],
53+
];
54+
}
55+
}

0 commit comments

Comments
 (0)