Skip to content

Commit

Permalink
Add assertions for xs:NMTOKEN and xs:NMTOKENS
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Oct 28, 2024
1 parent 384be05 commit cf94658
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/Assert.php
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@
* @method static void nullOrThrows(Closure|null $expression, string $class, string $message = '', string $exception = '')
* @method static void allThrows(Closure[] $expression, string $class, string $message = '', string $exception = '')
*
* @method static void validNMToken(mixed $value, string $message = '', string $exception = '')
* @method static void validNMTokens(mixed $value, string $message = '', string $exception = '')
* @method static void validDuration(mixed $value, string $message = '', string $exception = '')
* @method static void stringPlausibleBase64(mixed $value, string $message = '', string $exception = '')
* @method static void validDateTime(mixed $value, string $message = '', string $exception = '')
Expand All @@ -317,6 +319,8 @@
* @method static void validURL(mixed $value, string $message = '', string $exception = '')
* @method static void validNCName(mixed $value, string $message = '', string $exception = '')
* @method static void validQName(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidNMToken(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidNMTokens(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidDuration(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrStringPlausibleBase64(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidDateTime(mixed $value, string $message = '', string $exception = '')
Expand All @@ -326,6 +330,8 @@
* @method static void nullOrValidURL(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidNCName(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidQName(mixed $value, string $message = '', string $exception = '')
* @method static void allValidNMToken(mixed $value, string $message = '', string $exception = '')
* @method static void allValidNMTokens(mixed $value, string $message = '', string $exception = '')
* @method static void allValidDuration(mixed $value, string $message = '', string $exception = '')
* @method static void allStringPlausibleBase64(mixed $value, string $message = '', string $exception = '')
* @method static void allValidDateTime(mixed $value, string $message = '', string $exception = '')
Expand Down
36 changes: 36 additions & 0 deletions src/CustomAssertionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
*/
trait CustomAssertionTrait
{
/** @var string */
private static string $nmtoken_regex = '/^[\w.:-]+$/u';

/** @var string */
private static string $nmtokens_regex = '/^([\w.:-]+)([\s][\w.:-]+)*$/u';

/** @var string */
private static string $datetime_regex = '/-?[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])))T([0-1][0-9]|2[0-4]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9])(\.[0-999])?((\+|-)([0-1][0-9]|2[0-4]):(0[0-9]|[1-5][0-9])|Z)?/i';

Expand Down Expand Up @@ -49,6 +55,36 @@ trait CustomAssertionTrait
***********************************************************************************/


/**
* @param string $value
* @param string $message
*/
private static function validNMToken(string $value, string $message = ''): void
{
if (filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$nmtoken_regex]]) === false) {
throw new InvalidArgumentException(sprintf(
$message ?: '\'%s\' is not a valid xs:NMTOKEN',
$value,
));
}
}


/**
* @param string $value
* @param string $message
*/
private static function validNMTokens(string $value, string $message = ''): void
{
if (filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$nmtokens_regex]]) === false) {
throw new InvalidArgumentException(sprintf(
$message ?: '\'%s\' is not a valid xs:NMTOKENS',
$value,
));
}
}


/**
* @param string $value
* @param string $message
Expand Down
54 changes: 54 additions & 0 deletions tests/Assert/NMTokenTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\Assert;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Assert\AssertionFailedException;

/**
* Class \SimpleSAML\Assert\NMTokenTest
*
* @package simplesamlphp/assert
*/
#[CoversClass(Assert::class)]
final class NMTokenTest extends TestCase
{
/**
* @param boolean $shouldPass
* @param string $nmtoken
*/
#[DataProvider('provideNMToken')]
public function testValidToken(bool $shouldPass, string $nmtoken): void
{
try {
Assert::validNMToken($nmtoken);
$this->assertTrue($shouldPass);
} catch (AssertionFailedException $e) {
$this->assertFalse($shouldPass);
}
}


/**
* @return array<int, array{0: bool, 1: string}>
*/
public static function provideNMToken(): array
{
return [
[true, 'Snoopy'],
[true, 'CMS'],
[true, 'fööbár'],
[true, '1950-10-04'],
[true, '0836217462'],
// Spaces are forbidden
[false, 'foo bar'],
// Commas are forbidden
[false, 'foo,bar'],
];
}
}
55 changes: 55 additions & 0 deletions tests/Assert/NMTokensTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\Assert;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Assert\AssertionFailedException;

/**
* Class \SimpleSAML\Assert\NMTokensTest
*
* @package simplesamlphp/assert
*/
#[CoversClass(Assert::class)]
final class NMTokensTest extends TestCase
{
/**
* @param boolean $shouldPass
* @param string $nmtokens
*/
#[DataProvider('provideNMTokens')]
public function testValidTokens(bool $shouldPass, string $nmtokens): void
{
try {
Assert::validNMTokens($nmtokens);
$this->assertTrue($shouldPass);
} catch (AssertionFailedException $e) {
$this->assertFalse($shouldPass);
}
}


/**
* @return array<int, array{0: bool, 1: string}>
*/
public static function provideNMTokens(): array
{
return [
[true, 'Snoopy'],
[true, 'CMS'],
[true, 'fööbár'],
[true, '1950-10-04'],
[true, '0836217462 0836217463'],
[true, 'foo bar'],
// Quotes are forbidden
[false, 'foo "bar" baz'],
// Commas are forbidden
[false, 'foo,bar'],
];
}
}

0 comments on commit cf94658

Please sign in to comment.