Skip to content

Commit

Permalink
Create assertion and type-class for xs:double
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jan 14, 2025
1 parent b48628b commit 0c10520
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Assert/Assert.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* @method static void validDateTime(mixed $value, string $message = '', string $exception = '')
* @method static void validDay(mixed $value, string $message = '', string $exception = '')
* @method static void validDecimal(mixed $value, string $message = '', string $exception = '')
* @method static void validDouble(mixed $value, string $message = '', string $exception = '')
* @method static void validDuration(mixed $value, string $message = '', string $exception = '')
* @method static void validEntity(mixed $value, string $message = '', string $exception = '')
* @method static void validEntities(mixed $value, string $message = '', string $exception = '')
Expand Down Expand Up @@ -53,6 +54,7 @@
* @method static void nullOrValidDateTime(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidDay(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidDecimal(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidDouble(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidDuration(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidEntity(mixed $value, string $message = '', string $exception = '')
* @method static void nullOrValidEntities(mixed $value, string $message = '', string $exception = '')
Expand Down Expand Up @@ -89,6 +91,7 @@
* @method static void allValidDateTime(mixed $value, string $message = '', string $exception = '')
* @method static void allValidDay(mixed $value, string $message = '', string $exception = '')
* @method static void allValidDecimal(mixed $value, string $message = '', string $exception = '')
* @method static void allValidDouble(mixed $value, string $message = '', string $exception = '')
* @method static void allValidDuration(mixed $value, string $message = '', string $exception = '')
* @method static void allValidEntity(mixed $value, string $message = '', string $exception = '')
* @method static void allValidEntities(mixed $value, string $message = '', string $exception = '')
Expand Down Expand Up @@ -128,6 +131,7 @@ class Assert extends BaseAssert
use DateTimeTrait;
use DayTrait;
use DecimalTrait;
use DoubleTrait;
use DurationTrait;
use HexBinaryTrait;
use EntitiesTrait;
Expand Down
30 changes: 30 additions & 0 deletions src/Assert/DoubleTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XML\Assert;

use InvalidArgumentException;

/**
* @package simplesamlphp/xml-common
*/
trait DoubleTrait
{
/** @var string */
private static string $double_regex = '/^(([+-]?([0-9]+[.][0-9]*|[.][0-9]+)([e][+-]?[0-9]+)?)|NaN|[-]?FIN)$/D';

/**
* @param string $value
* @param string $message
*/
protected static function validDouble(string $value, string $message = ''): void
{
parent::regex(
$value,
self::$double_regex,
$message ?: '%s is not a valid xs:double',
InvalidArgumentException::class,
);
}
}
38 changes: 38 additions & 0 deletions src/Type/DoubleValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\XML\Type;

use SimpleSAML\XML\Assert\Assert;
use SimpleSAML\XML\Exception\SchemaViolationException;

/**
* @package simplesaml/xml-common
*/
class DoubleValue extends AbstractValueType
{
/**
* Sanitize the value.
*
* @param string $value The unsanitized value
* @return string
*/
protected function sanitizeValue(string $value): string
{
return str_replace(["\f", "\r", "\n", "\t", "\v", ' '], '', $value);
}


/**
* Validate the value.
*
* @param string $value
* @throws \SimpleSAML\XML\Exception\SchemaViolationException on failure
* @return void
*/
protected function validateValue(string $value): void
{
Assert::validDouble($this->sanitizeValue($value), SchemaViolationException::class);
}
}
58 changes: 58 additions & 0 deletions tests/Assert/DoubleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\XML\Assert;

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

/**
* Class \SimpleSAML\Test\XML\Assert\DoubleTest
*
* @package simplesamlphp/xml-common
*/
#[CoversClass(Assert::class)]
final class DoubleTest extends TestCase
{
/**
* @param boolean $shouldPass
* @param string $double
*/
#[DataProvider('provideDouble')]
public function testValidDouble(bool $shouldPass, string $double): void
{
try {
Assert::validDouble($double);
$this->assertTrue($shouldPass);
} catch (AssertionFailedException $e) {
$this->assertFalse($shouldPass);
}
}


/**
* @return array<string, array{0: bool, 1: string}>
*/
public static function provideDouble(): array
{
return [
'empty' => [false, ''],
'valid positive signed' => [true, '+123.456'],
'valid negative signed' => [true, '-123.456'],
'valid non-signed' => [true, '123.456'],
'valid leading zeros' => [true, '-0123.456'],
'valid zero' => [true, '0.0'],
'valid NaN' => [true, 'NaN'],
'case-sensitive NaN' => [false, 'NAN'],
'valid negative FIN' => [true, '-FIN'],
'valid FIN' => [true, 'FIN'],
'invalid +FIN' => [false, '+FIN'],
'invalid with space' => [false, '1 23.0'],
'invalid without fractional' => [false, '123'],
];
}
}
58 changes: 58 additions & 0 deletions tests/Type/DoubleValueTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\XML\Type;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Type\DoubleValue;

/**
* Class \SimpleSAML\Test\Type\DoubleValueTest
*
* @package simplesamlphp/xml-common
*/
#[CoversClass(DoubleValue::class)]
final class DoubleValueTest extends TestCase
{
/**
* @param boolean $shouldPass
* @param string $double
*/
#[DataProvider('provideDouble')]
public function testDouble(bool $shouldPass, string $double): void
{
try {
DoubleValue::fromString($double);
$this->assertTrue($shouldPass);
} catch (SchemaViolationException $e) {
$this->assertFalse($shouldPass);
}
}


/**
* @return array<string, array{0: bool, 1: string}>
*/
public static function provideDouble(): array
{
return [
'empty' => [false, ''],
'valid positive signed' => [true, '+123.456'],
'valid negative signed' => [true, '-123.456'],
'valid non-signed' => [true, '123.456'],
'valid leading zeros' => [true, '-0123.456'],
'valid zero' => [true, '0.0'],
'valid NaN' => [true, 'NaN'],
'case-sensitive NaN' => [false, 'NAN'],
'valid negative FIN' => [true, '-FIN'],
'valid FIN' => [true, 'FIN'],
'invalid +FIN' => [false, '+FIN'],
'valid with whitespace collapse' => [true, ' 1 234.456 '],
'invalid without fractional' => [false, '123'],
];
}
}

0 comments on commit 0c10520

Please sign in to comment.