Skip to content

Commit 0c10520

Browse files
committed
Create assertion and type-class for xs:double
1 parent b48628b commit 0c10520

File tree

5 files changed

+188
-0
lines changed

5 files changed

+188
-0
lines changed

src/Assert/Assert.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* @method static void validDateTime(mixed $value, string $message = '', string $exception = '')
1818
* @method static void validDay(mixed $value, string $message = '', string $exception = '')
1919
* @method static void validDecimal(mixed $value, string $message = '', string $exception = '')
20+
* @method static void validDouble(mixed $value, string $message = '', string $exception = '')
2021
* @method static void validDuration(mixed $value, string $message = '', string $exception = '')
2122
* @method static void validEntity(mixed $value, string $message = '', string $exception = '')
2223
* @method static void validEntities(mixed $value, string $message = '', string $exception = '')
@@ -53,6 +54,7 @@
5354
* @method static void nullOrValidDateTime(mixed $value, string $message = '', string $exception = '')
5455
* @method static void nullOrValidDay(mixed $value, string $message = '', string $exception = '')
5556
* @method static void nullOrValidDecimal(mixed $value, string $message = '', string $exception = '')
57+
* @method static void nullOrValidDouble(mixed $value, string $message = '', string $exception = '')
5658
* @method static void nullOrValidDuration(mixed $value, string $message = '', string $exception = '')
5759
* @method static void nullOrValidEntity(mixed $value, string $message = '', string $exception = '')
5860
* @method static void nullOrValidEntities(mixed $value, string $message = '', string $exception = '')
@@ -89,6 +91,7 @@
8991
* @method static void allValidDateTime(mixed $value, string $message = '', string $exception = '')
9092
* @method static void allValidDay(mixed $value, string $message = '', string $exception = '')
9193
* @method static void allValidDecimal(mixed $value, string $message = '', string $exception = '')
94+
* @method static void allValidDouble(mixed $value, string $message = '', string $exception = '')
9295
* @method static void allValidDuration(mixed $value, string $message = '', string $exception = '')
9396
* @method static void allValidEntity(mixed $value, string $message = '', string $exception = '')
9497
* @method static void allValidEntities(mixed $value, string $message = '', string $exception = '')
@@ -128,6 +131,7 @@ class Assert extends BaseAssert
128131
use DateTimeTrait;
129132
use DayTrait;
130133
use DecimalTrait;
134+
use DoubleTrait;
131135
use DurationTrait;
132136
use HexBinaryTrait;
133137
use EntitiesTrait;

src/Assert/DoubleTrait.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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 DoubleTrait
13+
{
14+
/** @var string */
15+
private static string $double_regex = '/^(([+-]?([0-9]+[.][0-9]*|[.][0-9]+)([e][+-]?[0-9]+)?)|NaN|[-]?FIN)$/D';
16+
17+
/**
18+
* @param string $value
19+
* @param string $message
20+
*/
21+
protected static function validDouble(string $value, string $message = ''): void
22+
{
23+
parent::regex(
24+
$value,
25+
self::$double_regex,
26+
$message ?: '%s is not a valid xs:double',
27+
InvalidArgumentException::class,
28+
);
29+
}
30+
}

src/Type/DoubleValue.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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 DoubleValue extends AbstractValueType
14+
{
15+
/**
16+
* Sanitize the value.
17+
*
18+
* @param string $value The unsanitized value
19+
* @return string
20+
*/
21+
protected function sanitizeValue(string $value): string
22+
{
23+
return str_replace(["\f", "\r", "\n", "\t", "\v", ' '], '', $value);
24+
}
25+
26+
27+
/**
28+
* Validate the value.
29+
*
30+
* @param string $value
31+
* @throws \SimpleSAML\XML\Exception\SchemaViolationException on failure
32+
* @return void
33+
*/
34+
protected function validateValue(string $value): void
35+
{
36+
Assert::validDouble($this->sanitizeValue($value), SchemaViolationException::class);
37+
}
38+
}

tests/Assert/DoubleTest.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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\DoubleTest
15+
*
16+
* @package simplesamlphp/xml-common
17+
*/
18+
#[CoversClass(Assert::class)]
19+
final class DoubleTest extends TestCase
20+
{
21+
/**
22+
* @param boolean $shouldPass
23+
* @param string $double
24+
*/
25+
#[DataProvider('provideDouble')]
26+
public function testValidDouble(bool $shouldPass, string $double): void
27+
{
28+
try {
29+
Assert::validDouble($double);
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 provideDouble(): array
41+
{
42+
return [
43+
'empty' => [false, ''],
44+
'valid positive signed' => [true, '+123.456'],
45+
'valid negative signed' => [true, '-123.456'],
46+
'valid non-signed' => [true, '123.456'],
47+
'valid leading zeros' => [true, '-0123.456'],
48+
'valid zero' => [true, '0.0'],
49+
'valid NaN' => [true, 'NaN'],
50+
'case-sensitive NaN' => [false, 'NAN'],
51+
'valid negative FIN' => [true, '-FIN'],
52+
'valid FIN' => [true, 'FIN'],
53+
'invalid +FIN' => [false, '+FIN'],
54+
'invalid with space' => [false, '1 23.0'],
55+
'invalid without fractional' => [false, '123'],
56+
];
57+
}
58+
}

tests/Type/DoubleValueTest.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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\DoubleValue;
12+
13+
/**
14+
* Class \SimpleSAML\Test\Type\DoubleValueTest
15+
*
16+
* @package simplesamlphp/xml-common
17+
*/
18+
#[CoversClass(DoubleValue::class)]
19+
final class DoubleValueTest extends TestCase
20+
{
21+
/**
22+
* @param boolean $shouldPass
23+
* @param string $double
24+
*/
25+
#[DataProvider('provideDouble')]
26+
public function testDouble(bool $shouldPass, string $double): void
27+
{
28+
try {
29+
DoubleValue::fromString($double);
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 provideDouble(): array
41+
{
42+
return [
43+
'empty' => [false, ''],
44+
'valid positive signed' => [true, '+123.456'],
45+
'valid negative signed' => [true, '-123.456'],
46+
'valid non-signed' => [true, '123.456'],
47+
'valid leading zeros' => [true, '-0123.456'],
48+
'valid zero' => [true, '0.0'],
49+
'valid NaN' => [true, 'NaN'],
50+
'case-sensitive NaN' => [false, 'NAN'],
51+
'valid negative FIN' => [true, '-FIN'],
52+
'valid FIN' => [true, 'FIN'],
53+
'invalid +FIN' => [false, '+FIN'],
54+
'valid with whitespace collapse' => [true, ' 1 234.456 '],
55+
'invalid without fractional' => [false, '123'],
56+
];
57+
}
58+
}

0 commit comments

Comments
 (0)