From e536adfda808c4ce3d9e68c9836c89ae512929c4 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 00:10:21 +0200 Subject: [PATCH 01/83] Refactor Undefined types: add null handling and clean up API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Introduce `fromNull` factory and `toNull` conversion across Undefined implementations and tests. - Remove deprecated array factory methods (`fromArray`, `tryFromArray`) and related abstract/interface definitions. - Update `UndefinedTypeInterface` and `UndefinedTypeAbstract` signatures to return `PrimitiveTypeAbstract|static` for `tryFrom*` methods. - Adjust exception messages to use consistent “Undefined type” wording. - Change `jsonSerialize` to return `null` instead of throwing. - Update unit tests for UndefinedStandard, Alias Undefined, and related classes to reflect new behavior and remove array cases. - Modify OptionalFailTest expectations for updated exception messages. --- .../Undefined/UndefinedTypeAbstract.php | 28 +-- .../Undefined/UndefinedTypeInterface.php | 23 +-- src/Undefined/UndefinedStandard.php | 171 +++++++++++++----- .../Primitive/Undefined/UndefinedTypeTest.php | 20 ++ tests/Unit/Undefined/Alias/UndefinedTest.php | 47 +++-- .../Unit/Undefined/UndefinedStandardTest.php | 66 +++++-- .../Unit/Usage/Composite/OptionalFailTest.php | 4 +- 7 files changed, 250 insertions(+), 109 deletions(-) diff --git a/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php b/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php index 523999cd..91cd82c8 100755 --- a/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php +++ b/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php @@ -29,8 +29,6 @@ { abstract public static function create(): static; - abstract public static function fromArray(array $value): static; - abstract public static function fromBool(bool $value): static; abstract public static function fromDecimal(string $value): static; @@ -39,12 +37,9 @@ abstract public static function fromFloat(float $value): static; abstract public static function fromInt(int $value): static; - abstract public static function fromString(string $value): static; + abstract public static function fromNull(null $value): static; - /** - * @throws UndefinedTypeException - */ - abstract public function toArray(): never; + abstract public static function fromString(string $value): static; /** * @throws UndefinedTypeException @@ -66,45 +61,42 @@ abstract public function toFloat(): never; */ abstract public function toInt(): never; + abstract public function toNull(): null; + /** * @throws UndefinedTypeException */ abstract public function toString(): string; - abstract public static function tryFromArray( - array $value, - PrimitiveTypeAbstract $default = new Undefined(), - ): static; - abstract public static function tryFromBool( bool $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; abstract public static function tryFromDecimal( string $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; abstract public static function tryFromFloat( float $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; abstract public static function tryFromInt( int $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; abstract public static function tryFromMixed( mixed $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; abstract public static function tryFromString( string $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; /** * @throws UndefinedTypeException diff --git a/src/Base/Primitive/Undefined/UndefinedTypeInterface.php b/src/Base/Primitive/Undefined/UndefinedTypeInterface.php index 646a2cd5..0446c2b9 100755 --- a/src/Base/Primitive/Undefined/UndefinedTypeInterface.php +++ b/src/Base/Primitive/Undefined/UndefinedTypeInterface.php @@ -25,8 +25,6 @@ interface UndefinedTypeInterface { public static function create(): static; - public static function fromArray(array $value): static; - public static function fromBool(bool $value): static; public static function fromDecimal(string $value): static; @@ -35,6 +33,8 @@ public static function fromFloat(float $value): static; public static function fromInt(int $value): static; + public static function fromNull(null $value): static; + public static function fromString(string $value): static; public function isTypeOf(string ...$classNames): bool; @@ -64,45 +64,42 @@ public function toFloat(): never; */ public function toInt(): never; + public function toNull(): null; + /** * @throws UndefinedTypeException */ public function toString(): string; - public static function tryFromArray( - array $value, - PrimitiveTypeAbstract $default = new Undefined(), - ): static; - public static function tryFromBool( bool $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; public static function tryFromDecimal( string $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; public static function tryFromFloat( float $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; public static function tryFromInt( int $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; public static function tryFromMixed( mixed $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; public static function tryFromString( string $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static; + ): PrimitiveTypeAbstract|static; /** * @throws UndefinedTypeException diff --git a/src/Undefined/UndefinedStandard.php b/src/Undefined/UndefinedStandard.php index 25a7b804..9008c759 100755 --- a/src/Undefined/UndefinedStandard.php +++ b/src/Undefined/UndefinedStandard.php @@ -4,11 +4,15 @@ namespace PhpTypedValues\Undefined; +use Exception; use PhpTypedValues\Base\Primitive\PrimitiveTypeAbstract; use PhpTypedValues\Base\Primitive\Undefined\UndefinedTypeAbstract; +use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Exception\Undefined\UndefinedTypeException; use PhpTypedValues\Undefined\Alias\Undefined; +use function is_null; + /** * Base implementation for a special "UndefinedStandard" typed value. * @@ -33,50 +37,60 @@ public static function create(): static /** * @psalm-pure + * + * @throws UndefinedTypeException */ - public static function fromArray(array $value): static + public static function fromBool(bool $value): static { - return new static(); + throw new UndefinedTypeException('Undefined type cannot be created from boolean'); } /** * @psalm-pure + * + * @throws UndefinedTypeException */ - public static function fromBool(bool $value): static + public static function fromDecimal(string $value): static { - return new static(); + throw new UndefinedTypeException('Undefined type cannot be created from decimal'); } /** * @psalm-pure + * + * @throws UndefinedTypeException */ - public static function fromDecimal(string $value): static + public static function fromFloat(float $value): static { - return new static(); + throw new UndefinedTypeException('Undefined type cannot be created from float'); } /** * @psalm-pure + * + * @throws UndefinedTypeException */ - public static function fromFloat(float $value): static + public static function fromInt(int $value): static { - return new static(); + throw new UndefinedTypeException('Undefined type cannot be created from integer'); } /** * @psalm-pure */ - public static function fromInt(int $value): static + public static function fromNull(null $value): static { return new static(); } /** * @psalm-pure + * + * @throws UndefinedTypeException */ public static function fromString(string $value): static { - return new static(); + throw new UndefinedTypeException('Undefined type cannot be created from string'); } public function isEmpty(): bool @@ -103,12 +117,9 @@ public function isUndefined(): bool return true; } - /** - * @throws UndefinedTypeException - */ - public function jsonSerialize(): never + public function jsonSerialize(): null { - throw new UndefinedTypeException('UndefinedType cannot be serialized for Json.'); + return $this->toNull(); } /** @@ -116,7 +127,7 @@ public function jsonSerialize(): never */ public function toArray(): never { - throw new UndefinedTypeException('UndefinedType cannot be converted to array.'); + throw new UndefinedTypeException('Undefined type cannot be converted to array'); } /** @@ -124,7 +135,7 @@ public function toArray(): never */ public function toBool(): never { - throw new UndefinedTypeException('UndefinedType cannot be converted to boolean.'); + throw new UndefinedTypeException('Undefined type cannot be converted to boolean'); } /** @@ -132,7 +143,7 @@ public function toBool(): never */ public function toDecimal(): string { - throw new UndefinedTypeException('UndefinedType cannot be converted to string.'); + throw new UndefinedTypeException('Undefined type cannot be converted to decimal'); } /** @@ -140,7 +151,7 @@ public function toDecimal(): string */ public function toFloat(): never { - throw new UndefinedTypeException('UndefinedType cannot be converted to float.'); + throw new UndefinedTypeException('Undefined type cannot be converted to float'); } /** @@ -148,85 +159,155 @@ public function toFloat(): never */ public function toInt(): never { - throw new UndefinedTypeException('UndefinedType cannot be converted to integer.'); + throw new UndefinedTypeException('Undefined type cannot be converted to integer'); } - /** - * @throws UndefinedTypeException - */ - public function toString(): string + public function toNull(): null { - throw new UndefinedTypeException('UndefinedType cannot be converted to string.'); + return null; } /** - * @psalm-pure + * @throws UndefinedTypeException */ - public static function tryFromArray( - array $value, - PrimitiveTypeAbstract $default = new Undefined(), - ): static { - return static::fromArray($value); + public function toString(): string + { + throw new UndefinedTypeException('Undefined type cannot be converted to string'); } /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + * * @psalm-pure */ public static function tryFromBool( bool $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static { - return static::fromBool($value); + ): PrimitiveTypeAbstract|static { + try { + /** @var static */ + return static::fromBool($value); + } catch (Exception) { + /** @var T */ + return $default; + } } /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + * * @psalm-pure */ public static function tryFromDecimal( string $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static { - return static::fromString($value); + ): PrimitiveTypeAbstract|static { + try { + /** @var static */ + return static::fromDecimal($value); + } catch (Exception) { + /** @var T */ + return $default; + } } /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + * * @psalm-pure */ public static function tryFromFloat( float $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static { - return static::fromFloat($value); + ): PrimitiveTypeAbstract|static { + try { + /** @var static */ + return static::fromFloat($value); + } catch (Exception) { + /** @var T */ + return $default; + } } /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + * * @psalm-pure */ public static function tryFromInt( int $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static { - return static::fromInt($value); + ): PrimitiveTypeAbstract|static { + try { + /** @var static */ + return static::fromInt($value); + } catch (Exception) { + /** @var T */ + return $default; + } } /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + * * @psalm-pure */ public static function tryFromMixed( mixed $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static { - return new static(); + ): PrimitiveTypeAbstract|static { + try { + /** @var static */ + return match (true) { + is_null($value) => static::fromNull($value), + default => throw new TypeException('Value cannot be casted to undefined type'), + }; + } catch (Exception) { + /** @var T */ + return $default; + } } /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + * * @psalm-pure */ public static function tryFromString( string $value, PrimitiveTypeAbstract $default = new Undefined(), - ): static { - return static::fromString($value); + ): PrimitiveTypeAbstract|static { + try { + /** @var static */ + return static::fromString($value); + } catch (Exception) { + /** @var T */ + return $default; + } } /** @@ -234,7 +315,7 @@ public static function tryFromString( */ public function value(): string { - throw new UndefinedTypeException('UndefinedType has no value.'); + throw new UndefinedTypeException('Undefined type has no value'); } /** @@ -242,6 +323,6 @@ public function value(): string */ public function __toString(): string { - throw new UndefinedTypeException('UndefinedType cannot be converted to string.'); + throw new UndefinedTypeException('Undefined type cannot be converted to string'); } } diff --git a/tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php b/tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php index c5d451d5..6ba67347 100755 --- a/tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php +++ b/tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php @@ -51,6 +51,11 @@ public static function fromInt(int $value): static return new static(); } + public static function fromNull(null $value): static + { + return new static(); + } + public static function fromString(string $value): static { return new static(); @@ -101,6 +106,11 @@ public function toInt(): never throw new UndefinedTypeException('Mock'); } + public function toNull(): null + { + return null; + } + public function toString(): string { throw new UndefinedTypeException('Mock: toString'); @@ -182,6 +192,11 @@ public static function fromInt(int $value): static return new static(); } + public static function fromNull(null $value): static + { + return new static(); + } + public static function fromString(string $value): static { return new static(); @@ -232,6 +247,11 @@ public function toInt(): never throw new UndefinedTypeException('Mock'); } + public function toNull(): null + { + return null; + } + public function toString(): string { return 'success'; diff --git a/tests/Unit/Undefined/Alias/UndefinedTest.php b/tests/Unit/Undefined/Alias/UndefinedTest.php index d64f4bf3..9346814a 100755 --- a/tests/Unit/Undefined/Alias/UndefinedTest.php +++ b/tests/Unit/Undefined/Alias/UndefinedTest.php @@ -3,6 +3,7 @@ declare(strict_types=1); use PhpTypedValues\Exception\Undefined\UndefinedTypeException; +use PhpTypedValues\String\StringStandard; use PhpTypedValues\Undefined\Alias\Undefined; covers(Undefined::class); @@ -14,23 +15,20 @@ expect($u)->toBeInstanceOf(Undefined::class); }); - it('creates instance via fromString factory', function (): void { - $u = Undefined::fromString('anything'); - expect($u)->toBeInstanceOf(Undefined::class); + it('throws via fromString factory', function (): void { + expect(fn() => Undefined::fromString('anything')) + ->toThrow(UndefinedTypeException::class, 'Undefined type cannot be created from string'); }); it('tryFromMixed always returns itself', function (): void { $fromString = Undefined::tryFromMixed('hello'); $fromInt = Undefined::tryFromMixed(123); - $fromArray = Undefined::tryFromMixed([]); $fromNull = Undefined::tryFromMixed(null); expect($fromString) ->toBeInstanceOf(Undefined::class) ->and($fromInt) ->toBeInstanceOf(Undefined::class) - ->and($fromArray) - ->toBeInstanceOf(Undefined::class) ->and($fromNull) ->toBeInstanceOf(Undefined::class); }); @@ -46,7 +44,6 @@ })->with([ 'tryFromString' => ['tryFromString', 'hello'], 'tryFromInt' => ['tryFromInt', 123], - 'tryFromArray' => ['tryFromArray', []], 'tryFromFloat' => ['tryFromFloat', 1.1], 'tryFromBool' => ['tryFromBool', true], ]); @@ -56,6 +53,25 @@ expect($v)->toBeInstanceOf(Undefined::class); }); + + it('tryFrom"Any" methods return default value on failure', function (string $method, mixed $input): void { + $default = StringStandard::fromString('default'); + $result = Undefined::$method($input, $default); + + expect($result)->toBe($default); + })->with([ + 'tryFromString' => ['tryFromString', 'hello'], + 'tryFromInt' => ['tryFromInt', 123], + 'tryFromFloat' => ['tryFromFloat', 1.1], + 'tryFromBool' => ['tryFromBool', true], + ]); + + it('tryFromMixed returns default value on failure', function (): void { + $default = StringStandard::fromString('default'); + $result = Undefined::tryFromMixed('hello', $default); + + expect($result)->toBe($default); + }); }); describe('Conversions (Failure Cases)', function () { @@ -64,12 +80,12 @@ $expect = expect(fn() => $u->{$method}()); $message = match ($method) { - 'toString', '__toString' => 'UndefinedType cannot be converted to string.', - 'toInt' => 'UndefinedType cannot be converted to integer.', - 'toFloat' => 'UndefinedType cannot be converted to float.', - 'toArray' => 'UndefinedType cannot be converted to array.', - 'value' => 'UndefinedType has no value.', - 'jsonSerialize' => 'UndefinedType cannot be serialized for Json.', + 'toString' => 'Undefined type cannot be converted to string', + '__toString' => 'Undefined type cannot be converted to string', + 'toInt' => 'Undefined type cannot be converted to integer', + 'toFloat' => 'Undefined type cannot be converted to float', + 'toArray' => 'Undefined type cannot be converted to array', + 'value' => 'Undefined type has no value', default => throw new RuntimeException("Unknown method: {$method}"), }; @@ -81,14 +97,13 @@ 'toArray', 'value', '__toString', - 'jsonSerialize', ]); }); describe('Information', function () { it('isEmpty returns true', function (): void { $u1 = Undefined::create(); - $u2 = Undefined::fromString('ignored'); + $u2 = Undefined::create(); expect($u1->isEmpty())->toBeTrue() ->and($u2->isEmpty())->toBeTrue(); @@ -96,7 +111,7 @@ it('isUndefined returns true', function (): void { $u1 = Undefined::create(); - $u2 = Undefined::fromString('ignored'); + $u2 = Undefined::create(); expect($u1->isUndefined())->toBeTrue() ->and($u2->isUndefined())->toBeTrue(); diff --git a/tests/Unit/Undefined/UndefinedStandardTest.php b/tests/Unit/Undefined/UndefinedStandardTest.php index 2c45307f..0028c0cb 100755 --- a/tests/Unit/Undefined/UndefinedStandardTest.php +++ b/tests/Unit/Undefined/UndefinedStandardTest.php @@ -3,6 +3,7 @@ declare(strict_types=1); use PhpTypedValues\Exception\Undefined\UndefinedTypeException; +use PhpTypedValues\String\StringStandard; use PhpTypedValues\Undefined\UndefinedStandard; covers(UndefinedStandard::class); @@ -15,15 +16,20 @@ }); it('creates instance via fromString factory', function (): void { - $u = UndefinedStandard::fromString('anything'); - expect($u)->toBeInstanceOf(UndefinedStandard::class); + expect(fn() => UndefinedStandard::fromString('anything')) + ->toThrow(UndefinedTypeException::class, 'Undefined type cannot be created from string'); }); - it('creates instance via fromDecimal factory', function (): void { - $u = UndefinedStandard::fromDecimal('1.23'); + it('creates instance via fromNull factory', function (): void { + $u = UndefinedStandard::fromNull(null); expect($u)->toBeInstanceOf(UndefinedStandard::class); }); + it('throws via fromDecimal factory', function (): void { + expect(fn() => UndefinedStandard::fromDecimal('1.23')) + ->toThrow(UndefinedTypeException::class, 'Undefined type cannot be created from decimal'); + }); + it('tryFromMixed always returns itself', function (): void { $fromString = UndefinedStandard::tryFromMixed('hello'); $fromInt = UndefinedStandard::tryFromMixed(123); @@ -55,7 +61,6 @@ 'tryFromString' => ['tryFromString', 'hello'], 'tryFromInt' => ['tryFromInt', 123], 'tryFromDecimal' => ['tryFromDecimal', '1.23'], - 'tryFromArray' => ['tryFromArray', []], 'tryFromFloat' => ['tryFromFloat', 1.1], 'tryFromBool' => ['tryFromBool', true], ]); @@ -65,6 +70,38 @@ expect($v)->toBeInstanceOf(UndefinedStandard::class); }); + + it('tryFrom"Any" methods return default value on failure', function (string $method, mixed $input): void { + $default = StringStandard::fromString('default'); + $result = UndefinedStandard::$method($input, $default); + + expect($result)->toBe($default); + })->with([ + 'tryFromString' => ['tryFromString', 'hello'], + 'tryFromInt' => ['tryFromInt', 123], + 'tryFromDecimal' => ['tryFromDecimal', '1.23'], + 'tryFromFloat' => ['tryFromFloat', 1.1], + 'tryFromBool' => ['tryFromBool', true], + ]); + + it('tryFromMixed returns default value on failure', function (): void { + $default = StringStandard::fromString('default'); + $result = UndefinedStandard::tryFromMixed('hello', $default); + + expect($result)->toBe($default); + }); + }); + + describe('Conversions (Success Cases)', function () { + it('toNull returns null', function (): void { + $u = UndefinedStandard::create(); + expect($u->toNull())->toBeNull(); + }); + + it('jsonSerialize returns null', function (): void { + $u = UndefinedStandard::create(); + expect($u->jsonSerialize())->toBeNull(); + }); }); describe('Conversions (Failure Cases)', function () { @@ -73,13 +110,13 @@ $expect = expect(fn() => $u->{$method}()); $message = match ($method) { - 'toString', '__toString' => 'UndefinedType cannot be converted to string.', - 'toDecimal' => 'UndefinedType cannot be converted to string.', - 'toInt' => 'UndefinedType cannot be converted to integer.', - 'toFloat' => 'UndefinedType cannot be converted to float.', - 'toArray' => 'UndefinedType cannot be converted to array.', - 'value' => 'UndefinedType has no value.', - 'jsonSerialize' => 'UndefinedType cannot be serialized for Json.', + 'toString' => 'Undefined type cannot be converted to string', + '__toString' => 'Undefined type cannot be converted to string', + 'toDecimal' => 'Undefined type cannot be converted to decimal', + 'toInt' => 'Undefined type cannot be converted to integer', + 'toFloat' => 'Undefined type cannot be converted to float', + 'toArray' => 'Undefined type cannot be converted to array', + 'value' => 'Undefined type has no value', default => throw new RuntimeException("Unknown method: {$method}"), }; @@ -92,14 +129,13 @@ 'toArray', 'value', '__toString', - 'jsonSerialize', ]); }); describe('Information', function () { it('isEmpty returns true', function (): void { $u1 = UndefinedStandard::create(); - $u2 = UndefinedStandard::fromString('ignored'); + $u2 = UndefinedStandard::create(); expect($u1->isEmpty())->toBeTrue() ->and($u2->isEmpty())->toBeTrue(); @@ -107,7 +143,7 @@ it('isUndefined returns true', function (): void { $u1 = UndefinedStandard::create(); - $u2 = UndefinedStandard::fromString('ignored'); + $u2 = UndefinedStandard::create(); expect($u1->isUndefined())->toBeTrue() ->and($u2->isUndefined())->toBeTrue(); diff --git a/tests/Unit/Usage/Composite/OptionalFailTest.php b/tests/Unit/Usage/Composite/OptionalFailTest.php index c33f9017..4306ac74 100755 --- a/tests/Unit/Usage/Composite/OptionalFailTest.php +++ b/tests/Unit/Usage/Composite/OptionalFailTest.php @@ -162,13 +162,13 @@ public function jsonSerialize(): array it('jsonSerialize fails when firstName is Undefined (late fail)', function () { $vo = OptionalFailTest::fromScalars(id: 1, firstName: '', height: 10.0); expect(fn() => $vo->jsonSerialize()) - ->toThrow(UndefinedTypeException::class, 'UndefinedType cannot be converted to string.'); + ->toThrow(UndefinedTypeException::class, 'Undefined type cannot be converted to string'); }); it('jsonSerialize fails when height is Undefined (late fail)', function () { $vo = OptionalFailTest::fromScalars(id: 1, firstName: 'Name', height: null); expect(fn() => $vo->jsonSerialize()) - ->toThrow(UndefinedTypeException::class, 'UndefinedType cannot be converted to string.'); + ->toThrow(UndefinedTypeException::class, 'Undefined type cannot be converted to string'); }); }); }); From ba82f3a9a256146bbc9d425e1e91c117ee0455f2 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 00:10:41 +0200 Subject: [PATCH 02/83] Reorder PHP version badges and tidy README sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move version badges after the **Install** heading and group them by major version. - Add an explicit “Install” heading and separate version badge blocks. - Update the Undefined description to include a reference link. - Adjust the “Other usage examples” heading formatting. --- README.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 73d8c67c..570639fc 100755 --- a/README.md +++ b/README.md @@ -15,34 +15,26 @@ Code quality: ![psalm](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/georgii-web/75977b7515de20d7382f6855d44a1d97/raw/psalm.json) ![cs-fixer](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/georgii-web/75977b7515de20d7382f6855d44a1d97/raw/cs_fixer.json) -PHP supported version: - -![Version 3.x](https://img.shields.io/badge/Version-3.x-777BB4) -![PHP >=8.4](https://img.shields.io/badge/PHP->=8.4-8892BF?logo=php) - -![Version 2.x](https://img.shields.io/badge/Version-2.x-777BB4) -![PHP >=8.2 <8.4](https://img.shields.io/badge/PHP->=8.2--<8.4-8892BF?logo=php) - -![Version 1.x](https://img.shields.io/badge/Version-1.x-777BB4) -![PHP >=7.4 <8.2](https://img.shields.io/badge/PHP->=7.4--<8.2-8892BF?logo=php) - --- ### Install -- Use V3 for PHP >=8.4: +![Version 3.x](https://img.shields.io/badge/Version-3.x-777BB4) +![PHP >=8.4](https://img.shields.io/badge/PHP->=8.4-8892BF?logo=php) ```bash composer require georgii-web/php-typed-values:^3 ``` -- Use V2 for PHP >=8.2 & <8.4: +![Version 2.x](https://img.shields.io/badge/Version-2.x-777BB4) +![PHP >=8.2 <8.4](https://img.shields.io/badge/PHP->=8.2--<8.4-8892BF?logo=php) ```bash composer require georgii-web/php-typed-values:^2 ``` -- Use V1 for PHP >=7.4 & <8.2: +![Version 1.x](https://img.shields.io/badge/Version-1.x-777BB4) +![PHP >=7.4 <8.2](https://img.shields.io/badge/PHP->=7.4--<8.2-8892BF?logo=php) ```bash composer require georgii-web/php-typed-values:^1 @@ -100,9 +92,11 @@ final readonly class Profile #### Undefined -Prefer using the `Undefined` type over `null` to maintain consistency and improve type safety within the codebase. +Prefer using the `Undefined` type over `null` to maintain consistency and improve type safety within the codebase [null-is-evil](https://sidburn.github.io/blog/2016/03/20/null-is-evil). + +#### Other usage examples -Other usage examples [docs/USAGE.md](docs/USAGE.md) +[docs/USAGE.md](docs/USAGE.md) ### Key features From c914a86efa3a5378d651ff2dd188a88482e1e2f4 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 00:17:42 +0200 Subject: [PATCH 03/83] Change Undefined toDecimal return type to never - Update `toDecimal` signatures in `UndefinedTypeAbstract`, `UndefinedTypeInterface`, and `UndefinedStandard` to return `never` since the method always throws. --- src/Base/Primitive/Undefined/UndefinedTypeAbstract.php | 2 +- src/Base/Primitive/Undefined/UndefinedTypeInterface.php | 2 +- src/Undefined/UndefinedStandard.php | 2 +- tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php b/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php index 91cd82c8..1020f52b 100755 --- a/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php +++ b/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php @@ -49,7 +49,7 @@ abstract public function toBool(): never; /** * @throws UndefinedTypeException */ - abstract public function toDecimal(): string; + abstract public function toDecimal(): never; /** * @throws UndefinedTypeException diff --git a/src/Base/Primitive/Undefined/UndefinedTypeInterface.php b/src/Base/Primitive/Undefined/UndefinedTypeInterface.php index 0446c2b9..3e51184b 100755 --- a/src/Base/Primitive/Undefined/UndefinedTypeInterface.php +++ b/src/Base/Primitive/Undefined/UndefinedTypeInterface.php @@ -52,7 +52,7 @@ public function toBool(): never; /** * @throws UndefinedTypeException */ - public function toDecimal(): string; + public function toDecimal(): never; /** * @throws UndefinedTypeException diff --git a/src/Undefined/UndefinedStandard.php b/src/Undefined/UndefinedStandard.php index 9008c759..522d5e80 100755 --- a/src/Undefined/UndefinedStandard.php +++ b/src/Undefined/UndefinedStandard.php @@ -141,7 +141,7 @@ public function toBool(): never /** * @throws UndefinedTypeException */ - public function toDecimal(): string + public function toDecimal(): never { throw new UndefinedTypeException('Undefined type cannot be converted to decimal'); } diff --git a/tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php b/tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php index 6ba67347..b79eb37a 100755 --- a/tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php +++ b/tests/Unit/Base/Primitive/Undefined/UndefinedTypeTest.php @@ -91,7 +91,7 @@ public function toBool(): never throw new UndefinedTypeException('Mock'); } - public function toDecimal(): string + public function toDecimal(): never { throw new UndefinedTypeException('Mock'); } @@ -232,7 +232,7 @@ public function toBool(): never throw new UndefinedTypeException('Mock'); } - public function toDecimal(): string + public function toDecimal(): never { throw new UndefinedTypeException('Mock'); } From b9d3eb25a33e365dabc115325ecfd0b2a3e469df Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:08:28 +0200 Subject: [PATCH 04/83] Refactor BoolStandard: add null handling and exception - Introduce `fromNull` factory method that always throws `BoolTypeException`. - Add `toNull` conversion method that always throws `BoolTypeException`. - Import `BoolTypeException` in `BoolStandard`. - Extend unit tests to assert both methods throw the expected exception. --- src/Bool/BoolStandard.php | 17 +++++++++++++++++ tests/Unit/Bool/BoolStandardTest.php | 8 ++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Bool/BoolStandard.php b/src/Bool/BoolStandard.php index 764defac..27dfeaf7 100755 --- a/src/Bool/BoolStandard.php +++ b/src/Bool/BoolStandard.php @@ -7,6 +7,7 @@ use Exception; use PhpTypedValues\Base\Primitive\Bool\BoolTypeAbstract; use PhpTypedValues\Base\Primitive\PrimitiveTypeAbstract; +use PhpTypedValues\Exception\Bool\BoolTypeException; use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\Integer\IntegerTypeException; @@ -81,6 +82,14 @@ public static function fromInt(int $value): static return new static(static::intToBool($value)); } + /** + * @throws BoolTypeException + */ + public static function fromNull(null $value): never + { + throw new BoolTypeException('Boolean type cannot be created from null'); + } + /** * @psalm-pure * @@ -140,6 +149,14 @@ public function toInt(): int return static::boolToInt($this->value()); } + /** + * @throws BoolTypeException + */ + public static function toNull(): never + { + throw new BoolTypeException('Boolean type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Bool/BoolStandardTest.php b/tests/Unit/Bool/BoolStandardTest.php index afa6547b..4fd65c32 100755 --- a/tests/Unit/Bool/BoolStandardTest.php +++ b/tests/Unit/Bool/BoolStandardTest.php @@ -5,6 +5,7 @@ namespace PhpTypedValues\Tests\Unit\Bool; use PhpTypedValues\Bool\BoolStandard; +use PhpTypedValues\Exception\Bool\BoolTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\Integer\IntegerTypeException; use PhpTypedValues\Exception\String\StringTypeException; @@ -88,6 +89,13 @@ [true, '1.0'], [false, '0.0'], ]); + it('fromNull throws BoolTypeException', function (): void { + expect(fn() => BoolStandard::fromNull(null))->toThrow(BoolTypeException::class, 'Boolean type cannot be created from null'); + }); + + it('toNull throws BoolTypeException', function (): void { + expect(fn() => (new BoolStandard(true))->toNull())->toThrow(BoolTypeException::class, 'Boolean type cannot be converted to null'); + }); }); describe('BoolStandard - from* Factory Methods', function (): void { From f726c513737d721a708a18653f4281f086b59093 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:08:33 +0200 Subject: [PATCH 05/83] Add null handling to BoolSwitch: fromNull and toNull throw SwitchBoolTypeException Introduce `fromNull` factory method and `toNull` conversion that always throw `SwitchBoolTypeException`. Extend unit tests to assert both methods raise the expected exception. --- src/Bool/Specific/BoolSwitch.php | 16 ++++++++++++++++ tests/Unit/Bool/Specific/BoolSwitchTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Bool/Specific/BoolSwitch.php b/src/Bool/Specific/BoolSwitch.php index 37402baf..b22ee49f 100755 --- a/src/Bool/Specific/BoolSwitch.php +++ b/src/Bool/Specific/BoolSwitch.php @@ -93,6 +93,14 @@ public static function fromLabel(string $label): static return new static($value); } + /** + * @throws SwitchBoolTypeException + */ + public static function fromNull(null $value): never + { + throw new SwitchBoolTypeException('Value cannot be null'); + } + /** * @psalm-pure * @@ -160,6 +168,14 @@ public function toLabel(): string return $this->value() ? 'on' : 'off'; } + /** + * @throws SwitchBoolTypeException + */ + public static function toNull(): never + { + throw new SwitchBoolTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Bool/Specific/BoolSwitchTest.php b/tests/Unit/Bool/Specific/BoolSwitchTest.php index f2783589..fb06fa57 100755 --- a/tests/Unit/Bool/Specific/BoolSwitchTest.php +++ b/tests/Unit/Bool/Specific/BoolSwitchTest.php @@ -161,6 +161,14 @@ ['TRUE'], ]); + it('fromNull throws SwitchBoolTypeException', function (): void { + expect(fn() => BoolSwitch::fromNull(null))->toThrow(SwitchBoolTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws SwitchBoolTypeException', function (): void { + expect(fn() => (new BoolSwitch(true))->toNull())->toThrow(SwitchBoolTypeException::class, 'Value cannot be null'); + }); + it('fromLabel creates instance from valid labels', function (string $input, bool $expected): void { $bool = BoolSwitch::fromLabel($input); expect($bool->value())->toBe($expected); From 90cf2e20084704df3b6ce62e349dcf2ae1515b12 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:08:43 +0200 Subject: [PATCH 06/83] Add @throws UndefinedTypeException annotations and generic templates to Undefined factories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document that `fromBool`, `fromDecimal`, `fromFloat`, `fromInt`, `fromString` and `__toString` in `UndefinedTypeAbstract` now declare they may throw `UndefinedTypeException`. Add template‑based PHPDoc for `tryFromBool`, `tryFromDecimal`, `tryFromFloat`, `tryFromInt`, `tryFromMixed` and `tryFromString` in `UndefinedTypeInterface`, specifying the `$default` parameter type and the combined return type. --- .../Undefined/UndefinedTypeAbstract.php | 18 ++++++++ .../Undefined/UndefinedTypeInterface.php | 42 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php b/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php index 1020f52b..0ee47d56 100755 --- a/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php +++ b/src/Base/Primitive/Undefined/UndefinedTypeAbstract.php @@ -29,16 +29,31 @@ { abstract public static function create(): static; + /** + * @throws UndefinedTypeException + */ abstract public static function fromBool(bool $value): static; + /** + * @throws UndefinedTypeException + */ abstract public static function fromDecimal(string $value): static; + /** + * @throws UndefinedTypeException + */ abstract public static function fromFloat(float $value): static; + /** + * @throws UndefinedTypeException + */ abstract public static function fromInt(int $value): static; abstract public static function fromNull(null $value): static; + /** + * @throws UndefinedTypeException + */ abstract public static function fromString(string $value): static; /** @@ -103,6 +118,9 @@ abstract public static function tryFromString( */ abstract public function value(): string; + /** + * @throws UndefinedTypeException + */ public function __toString(): string { return $this->toString(); diff --git a/src/Base/Primitive/Undefined/UndefinedTypeInterface.php b/src/Base/Primitive/Undefined/UndefinedTypeInterface.php index 3e51184b..b9709ea2 100755 --- a/src/Base/Primitive/Undefined/UndefinedTypeInterface.php +++ b/src/Base/Primitive/Undefined/UndefinedTypeInterface.php @@ -71,31 +71,73 @@ public function toNull(): null; */ public function toString(): string; + /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + */ public static function tryFromBool( bool $value, PrimitiveTypeAbstract $default = new Undefined(), ): PrimitiveTypeAbstract|static; + /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + */ public static function tryFromDecimal( string $value, PrimitiveTypeAbstract $default = new Undefined(), ): PrimitiveTypeAbstract|static; + /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + */ public static function tryFromFloat( float $value, PrimitiveTypeAbstract $default = new Undefined(), ): PrimitiveTypeAbstract|static; + /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + */ public static function tryFromInt( int $value, PrimitiveTypeAbstract $default = new Undefined(), ): PrimitiveTypeAbstract|static; + /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + */ public static function tryFromMixed( mixed $value, PrimitiveTypeAbstract $default = new Undefined(), ): PrimitiveTypeAbstract|static; + /** + * @template T of PrimitiveTypeAbstract + * + * @param T $default + * + * @return static|T + */ public static function tryFromString( string $value, PrimitiveTypeAbstract $default = new Undefined(), From 0c1b0917bc2c2ef94925bb66f189eab23a40c4ed Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:08:48 +0200 Subject: [PATCH 07/83] Add null handling to TrueStandard: fromNull and toNull throw TrueBoolTypeException Introduce `fromNull` factory method and `toNull` conversion that always throw `TrueBoolTypeException`. Extend unit tests to assert both methods raise the expected exception. --- src/Bool/TrueStandard.php | 16 ++++++++++++++++ tests/Unit/Bool/TrueStandardTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Bool/TrueStandard.php b/src/Bool/TrueStandard.php index bc01689b..6b4d8aaf 100755 --- a/src/Bool/TrueStandard.php +++ b/src/Bool/TrueStandard.php @@ -96,6 +96,14 @@ public static function fromInt(int $value): static return new static(static::intToBool($value)); } + /** + * @throws TrueBoolTypeException + */ + public static function fromNull(null $value): never + { + throw new TrueBoolTypeException('Value cannot be null'); + } + /** * @psalm-pure * @@ -156,6 +164,14 @@ public function toInt(): int return static::boolToInt($this->value()); } + /** + * @throws TrueBoolTypeException + */ + public static function toNull(): never + { + throw new TrueBoolTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Bool/TrueStandardTest.php b/tests/Unit/Bool/TrueStandardTest.php index 9f1e08f5..0d6e3ca3 100755 --- a/tests/Unit/Bool/TrueStandardTest.php +++ b/tests/Unit/Bool/TrueStandardTest.php @@ -82,6 +82,14 @@ public function __toString(): string ->and($badI)->toBeInstanceOf(Undefined::class); }); + it('fromNull throws TrueBoolTypeException', function (): void { + expect(fn() => TrueStandard::fromNull(null))->toThrow(TrueBoolTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws TrueBoolTypeException', function (): void { + expect(fn() => (new TrueStandard(true))->toNull())->toThrow(TrueBoolTypeException::class, 'Value cannot be null'); + }); + it('jsonSerialize returns bool', function (): void { // Check that tryFromString returns proper type $valid = TrueStandard::tryFromString('true'); From cd9f0204bec82147418e173cabbd0a674da0f2a0 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:09:03 +0200 Subject: [PATCH 08/83] Add null handling to FalseStandard: fromNull and toNull throw FalseBoolTypeException Introduce `fromNull` factory and `toNull` conversion methods that always throw `FalseBoolTypeException`, and add unit tests to assert the expected exceptions. --- src/Base/Primitive/PrimitiveTypeInterface.php | 1 - src/Bool/FalseStandard.php | 16 ++++++++++++++++ tests/Unit/Bool/FalseStandardTest.php | 8 ++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Base/Primitive/PrimitiveTypeInterface.php b/src/Base/Primitive/PrimitiveTypeInterface.php index c720f5fc..89d7c2e2 100755 --- a/src/Base/Primitive/PrimitiveTypeInterface.php +++ b/src/Base/Primitive/PrimitiveTypeInterface.php @@ -24,7 +24,6 @@ */ interface PrimitiveTypeInterface extends TypeInterface, JsonSerializable { - // todo add all methods converters /** * Returns true if the Object value is empty. */ diff --git a/src/Bool/FalseStandard.php b/src/Bool/FalseStandard.php index f3c82606..8907ec1a 100755 --- a/src/Bool/FalseStandard.php +++ b/src/Bool/FalseStandard.php @@ -96,6 +96,14 @@ public static function fromInt(int $value): static return new static(static::intToBool($value)); } + /** + * @throws FalseBoolTypeException + */ + public static function fromNull(null $value): never + { + throw new FalseBoolTypeException('Value cannot be null'); + } + /** * @psalm-pure * @@ -156,6 +164,14 @@ public function toInt(): int return static::boolToInt($this->value()); } + /** + * @throws FalseBoolTypeException + */ + public static function toNull(): never + { + throw new FalseBoolTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Bool/FalseStandardTest.php b/tests/Unit/Bool/FalseStandardTest.php index db344bb3..1c404305 100755 --- a/tests/Unit/Bool/FalseStandardTest.php +++ b/tests/Unit/Bool/FalseStandardTest.php @@ -82,6 +82,14 @@ public function __toString(): string ->and($badI)->toBeInstanceOf(Undefined::class); }); + it('fromNull throws FalseBoolTypeException', function (): void { + expect(fn() => FalseStandard::fromNull(null))->toThrow(FalseBoolTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws FalseBoolTypeException', function (): void { + expect(fn() => (new FalseStandard(false))->toNull())->toThrow(FalseBoolTypeException::class, 'Value cannot be null'); + }); + it('jsonSerialize returns bool', function (): void { // Check that tryFromString returns proper type $valid = FalseStandard::tryFromString('false'); From cad236f819b471e4115e0675642f955a3bdf66af Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:09:24 +0200 Subject: [PATCH 09/83] Add null handling to BoolTypeAbstract and BoolTypeInterface Introduce abstract `fromNull` and `toNull` methods that always throw an Exception, and implement them in the unit tests to verify the expected exception behavior. --- composer.json | 4 ++-- src/Base/Primitive/Bool/BoolTypeAbstract.php | 4 ++++ src/Base/Primitive/Bool/BoolTypeInterface.php | 4 ++++ .../Unit/Base/Primitive/Bool/BoolTypeAbstractTest.php | 10 ++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 962266d0..39ad919c 100755 --- a/composer.json +++ b/composer.json @@ -68,6 +68,7 @@ "echo \"Coverage\" && ./vendor/bin/pest --coverage --min=100 --parallel" ], "mutate": [ + "echo \"Undefined\" && ./vendor/bin/pest tests/Unit/Undefined --mutate --covered-only --parallel --min=100", "echo \"String\" && ./vendor/bin/pest tests/Unit/String --mutate --covered-only --parallel --min=100", "echo \"Integer\" && ./vendor/bin/pest tests/Unit/Integer --mutate --covered-only --parallel --min=100", "echo \"DateTime\" && ./vendor/bin/pest tests/Unit/DateTime --mutate --covered-only --parallel --min=100", @@ -75,8 +76,7 @@ "echo \"Float\" && ./vendor/bin/pest tests/Unit/Float --mutate --covered-only --parallel --min=100", "echo \"Base\" && ./vendor/bin/pest tests/Unit/Base --mutate --covered-only --parallel --min=100", "echo \"Array\" && ./vendor/bin/pest tests/Unit/ArrayType --mutate --covered-only --parallel --min=100", - "echo \"Bool\" && ./vendor/bin/pest tests/Unit/Bool --mutate --covered-only --parallel --min=100", - "echo \"Undefined\" && ./vendor/bin/pest tests/Unit/Undefined --mutate --covered-only --parallel --min=100" + "echo \"Bool\" && ./vendor/bin/pest tests/Unit/Bool --mutate --covered-only --parallel --min=100" ] }, "config": { diff --git a/src/Base/Primitive/Bool/BoolTypeAbstract.php b/src/Base/Primitive/Bool/BoolTypeAbstract.php index ee6704ae..cc61265b 100755 --- a/src/Base/Primitive/Bool/BoolTypeAbstract.php +++ b/src/Base/Primitive/Bool/BoolTypeAbstract.php @@ -34,6 +34,8 @@ abstract public static function fromFloat(float $value): static; abstract public static function fromInt(int $value): static; + abstract public static function fromNull(null $value): never; + abstract public static function fromString(string $value): static; abstract public function isTypeOf(string ...$classNames): bool; @@ -46,6 +48,8 @@ abstract public function toFloat(): float; abstract public function toInt(): int; + abstract public static function toNull(): never; + abstract public function toString(): string; /** diff --git a/src/Base/Primitive/Bool/BoolTypeInterface.php b/src/Base/Primitive/Bool/BoolTypeInterface.php index b65fcbba..b371ff8c 100755 --- a/src/Base/Primitive/Bool/BoolTypeInterface.php +++ b/src/Base/Primitive/Bool/BoolTypeInterface.php @@ -30,6 +30,8 @@ public static function fromFloat(float $value): static; public static function fromInt(int $value): static; + public static function fromNull(null $value): never; + public static function fromString(string $value): static; public function isTypeOf(string ...$classNames): bool; @@ -42,6 +44,8 @@ public function toFloat(): float; public function toInt(): int; + public static function toNull(): never; + public function toString(): string; /** diff --git a/tests/Unit/Base/Primitive/Bool/BoolTypeAbstractTest.php b/tests/Unit/Base/Primitive/Bool/BoolTypeAbstractTest.php index ea82f851..a3e510dc 100755 --- a/tests/Unit/Base/Primitive/Bool/BoolTypeAbstractTest.php +++ b/tests/Unit/Base/Primitive/Bool/BoolTypeAbstractTest.php @@ -56,6 +56,11 @@ public static function fromInt(int $value): static return new static(static::intToBool($value)); } + public static function fromNull(null $value): never + { + throw new Exception('Value cannot be null'); + } + public static function fromString(string $value): static { return new static(static::stringToBool($value)); @@ -107,6 +112,11 @@ public function toInt(): int return static::boolToInt($this->val); } + public static function toNull(): never + { + throw new Exception('Value cannot be null'); + } + public function toString(): string { return static::boolToString($this->val); From 7fd01ddca1653502229a95757c68b0717ea12053 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:09:29 +0200 Subject: [PATCH 10/83] Add null handling to BoolToggle: fromNull and toNull throw ToggleBoolTypeException Implement static `fromNull` and instance `toNull` methods that always throw `ToggleBoolTypeException` and add unit tests verifying the expected exceptions. --- src/Bool/Specific/BoolToggle.php | 16 ++++++++++++++++ tests/Unit/Bool/Specific/BoolToggleTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Bool/Specific/BoolToggle.php b/src/Bool/Specific/BoolToggle.php index b50468bd..871d924d 100755 --- a/src/Bool/Specific/BoolToggle.php +++ b/src/Bool/Specific/BoolToggle.php @@ -93,6 +93,14 @@ public static function fromLabel(string $label): static return new static($value); } + /** + * @throws ToggleBoolTypeException + */ + public static function fromNull(null $value): never + { + throw new ToggleBoolTypeException('Value cannot be null'); + } + /** * @psalm-pure * @@ -160,6 +168,14 @@ public function toLabel(): string return $this->value() ? 'yes' : 'no'; } + /** + * @throws ToggleBoolTypeException + */ + public static function toNull(): never + { + throw new ToggleBoolTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Bool/Specific/BoolToggleTest.php b/tests/Unit/Bool/Specific/BoolToggleTest.php index f1f93e61..be92a30f 100755 --- a/tests/Unit/Bool/Specific/BoolToggleTest.php +++ b/tests/Unit/Bool/Specific/BoolToggleTest.php @@ -161,6 +161,14 @@ ['TRUE'], ]); + it('fromNull throws ToggleBoolTypeException', function (): void { + expect(fn() => BoolToggle::fromNull(null))->toThrow(ToggleBoolTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws ToggleBoolTypeException', function (): void { + expect(fn() => (new BoolToggle(true))->toNull())->toThrow(ToggleBoolTypeException::class, 'Value cannot be null'); + }); + it('fromLabel creates instance from valid labels', function (string $input, bool $expected): void { $bool = BoolToggle::fromLabel($input); expect($bool->value())->toBe($expected); From 143d6c45d1c2058420ba5758489f8d37033067cf Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:19:24 +0200 Subject: [PATCH 11/83] Add null handling to DecimalMoney: fromNull and toNull throw MoneyDecimalTypeException Introduce static `fromNull` and instance `toNull` methods that always throw `MoneyDecimalTypeException` and add unit tests verifying the expected exceptions. --- src/Decimal/Specific/DecimalMoney.php | 16 ++++++++++++++++ tests/Unit/Decimal/Specific/DecimalMoneyTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Decimal/Specific/DecimalMoney.php b/src/Decimal/Specific/DecimalMoney.php index 4d27542d..16ffdb04 100755 --- a/src/Decimal/Specific/DecimalMoney.php +++ b/src/Decimal/Specific/DecimalMoney.php @@ -119,6 +119,14 @@ public static function fromInt(int $value): static )); } + /** + * @throws MoneyDecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new MoneyDecimalTypeException('Value cannot be null'); + } + /** * @throws MoneyDecimalTypeException * @throws DecimalTypeException @@ -198,6 +206,14 @@ public function toInt(): int ); } + /** + * @throws MoneyDecimalTypeException + */ + public function toNull(): never + { + throw new MoneyDecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/Specific/DecimalMoneyTest.php b/tests/Unit/Decimal/Specific/DecimalMoneyTest.php index 2411fa34..055463f7 100755 --- a/tests/Unit/Decimal/Specific/DecimalMoneyTest.php +++ b/tests/Unit/Decimal/Specific/DecimalMoneyTest.php @@ -82,6 +82,14 @@ expect(DecimalMoney::fromString('1.10')->jsonSerialize())->toBeString(); }); + it('fromNull throws MoneyDecimalTypeException', function (): void { + expect(fn() => DecimalMoney::fromNull(null))->toThrow(MoneyDecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws MoneyDecimalTypeException', function (): void { + expect(fn() => (new DecimalMoney('1.00'))->toNull())->toThrow(MoneyDecimalTypeException::class, 'Value cannot be null'); + }); + it('__toString returns the original decimal string', function (): void { $d = new DecimalMoney('3.14'); expect((string) $d)->toBe('3.14') From f7e020586b813668892926074a3d4bd203174d04 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:19:30 +0200 Subject: [PATCH 12/83] Add null handling to DecimalNegative: fromNull and toNull throw NegativeDecimalTypeException Introduce static `fromNull` and instance `toNull` methods that always throw `NegativeDecimalTypeException` and add unit tests verifying the expected exceptions. --- src/Decimal/DecimalNegative.php | 16 ++++++++++++++++ tests/Unit/Decimal/DecimalNegativeTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Decimal/DecimalNegative.php b/src/Decimal/DecimalNegative.php index 06b8706b..988fc874 100755 --- a/src/Decimal/DecimalNegative.php +++ b/src/Decimal/DecimalNegative.php @@ -108,6 +108,14 @@ public static function fromInt(int $value): static return new static(static::intToDecimal($value)); } + /** + * @throws NegativeDecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new NegativeDecimalTypeException('Value cannot be null'); + } + /** * @throws NegativeDecimalTypeException * @throws DecimalTypeException @@ -181,6 +189,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws NegativeDecimalTypeException + */ + public function toNull(): never + { + throw new NegativeDecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/DecimalNegativeTest.php b/tests/Unit/Decimal/DecimalNegativeTest.php index 6d13b668..85a440a8 100755 --- a/tests/Unit/Decimal/DecimalNegativeTest.php +++ b/tests/Unit/Decimal/DecimalNegativeTest.php @@ -81,6 +81,14 @@ expect(DecimalNegative::fromString('-1.1')->jsonSerialize())->toBeString(); }); + it('fromNull throws NegativeDecimalTypeException', function (): void { + expect(fn() => DecimalNegative::fromNull(null))->toThrow(NegativeDecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws NegativeDecimalTypeException', function (): void { + expect(fn() => (new DecimalNegative('-1.0'))->toNull())->toThrow(NegativeDecimalTypeException::class, 'Value cannot be null'); + }); + it('__toString returns the original decimal string', function (): void { $d = new DecimalNegative('-3.14'); expect((string) $d)->toBe('-3.14') From a8a6b05830c18de2b1ba3c4b8d882b64f53842fb Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:19:34 +0200 Subject: [PATCH 13/83] Add null handling to DecimalNonNegative: fromNull and toNull throw NonNegativeDecimalTypeException Introduce static `fromNull` and instance `toNull` methods that always throw `NonNegativeDecimalTypeException` and add corresponding unit tests to verify the exception behavior. --- src/Decimal/DecimalNonNegative.php | 16 ++++++++++++++++ tests/Unit/Decimal/DecimalNonNegativeTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Decimal/DecimalNonNegative.php b/src/Decimal/DecimalNonNegative.php index ccccbb50..d3edfc85 100755 --- a/src/Decimal/DecimalNonNegative.php +++ b/src/Decimal/DecimalNonNegative.php @@ -108,6 +108,14 @@ public static function fromInt(int $value): static return new static(static::intToDecimal($value)); } + /** + * @throws NonNegativeDecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new NonNegativeDecimalTypeException('Value cannot be null'); + } + /** * @throws NonNegativeDecimalTypeException * @throws DecimalTypeException @@ -181,6 +189,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws NonNegativeDecimalTypeException + */ + public function toNull(): never + { + throw new NonNegativeDecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/DecimalNonNegativeTest.php b/tests/Unit/Decimal/DecimalNonNegativeTest.php index 7a5dd2e9..52087658 100755 --- a/tests/Unit/Decimal/DecimalNonNegativeTest.php +++ b/tests/Unit/Decimal/DecimalNonNegativeTest.php @@ -80,6 +80,14 @@ expect(DecimalNonNegative::fromString('1.1')->jsonSerialize())->toBeString(); }); + it('fromNull throws NonNegativeDecimalTypeException', function (): void { + expect(fn() => DecimalNonNegative::fromNull(null))->toThrow(NonNegativeDecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws NonNegativeDecimalTypeException', function (): void { + expect(fn() => (new DecimalNonNegative('0.0'))->toNull())->toThrow(NonNegativeDecimalTypeException::class, 'Value cannot be null'); + }); + it('__toString returns the original decimal string', function (): void { $d = new DecimalNonNegative('3.14'); expect((string) $d)->toBe('3.14') From ecfaab2c6ab47f0c31e99a11db9828cc94ff56a3 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:19:40 +0200 Subject: [PATCH 14/83] Add null handling to DecimalNonPositive: fromNull and toNull throw NonPositiveDecimalTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `NonPositiveDecimalTypeException` and added unit tests to verify the exception behavior. --- src/Decimal/DecimalNonPositive.php | 16 ++++++++++++++++ tests/Unit/Decimal/DecimalNonPositiveTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Decimal/DecimalNonPositive.php b/src/Decimal/DecimalNonPositive.php index 4a45881d..29404429 100755 --- a/src/Decimal/DecimalNonPositive.php +++ b/src/Decimal/DecimalNonPositive.php @@ -99,6 +99,14 @@ public static function fromInt(int $value): static return new static(static::intToDecimal($value)); } + /** + * @throws NonPositiveDecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new NonPositiveDecimalTypeException('Value cannot be null'); + } + /** * @throws NonPositiveDecimalTypeException * @throws DecimalTypeException @@ -172,6 +180,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws NonPositiveDecimalTypeException + */ + public function toNull(): never + { + throw new NonPositiveDecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/DecimalNonPositiveTest.php b/tests/Unit/Decimal/DecimalNonPositiveTest.php index fc859a91..bfa2a211 100755 --- a/tests/Unit/Decimal/DecimalNonPositiveTest.php +++ b/tests/Unit/Decimal/DecimalNonPositiveTest.php @@ -69,6 +69,14 @@ expect(DecimalNonPositive::fromString('-1.1')->jsonSerialize())->toBeString(); }); + it('fromNull throws NonPositiveDecimalTypeException', function (): void { + expect(fn() => DecimalNonPositive::fromNull(null))->toThrow(NonPositiveDecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws NonPositiveDecimalTypeException', function (): void { + expect(fn() => (new DecimalNonPositive('-1.0'))->toNull())->toThrow(NonPositiveDecimalTypeException::class, 'Value cannot be null'); + }); + it('__toString returns the original decimal string', function (): void { $d = new DecimalNonPositive('-3.14'); expect((string) $d)->toBe('-3.14') From fd824ab0b629516a33bd909b0b00f4433a5b4073 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:19:45 +0200 Subject: [PATCH 15/83] Add null handling to DecimalNonZero: fromNull and toNull throw NonZeroDecimalTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `NonZeroDecimalTypeException` and added unit tests to verify the exception behavior. --- src/Decimal/DecimalNonZero.php | 16 ++++++++++++++++ tests/Unit/Decimal/DecimalNonZeroTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Decimal/DecimalNonZero.php b/src/Decimal/DecimalNonZero.php index f40553f7..7444120c 100755 --- a/src/Decimal/DecimalNonZero.php +++ b/src/Decimal/DecimalNonZero.php @@ -98,6 +98,14 @@ public static function fromInt(int $value): static return new static(static::intToDecimal($value)); } + /** + * @throws NonZeroDecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new NonZeroDecimalTypeException('Value cannot be null'); + } + /** * @throws NonZeroDecimalTypeException * @throws DecimalTypeException @@ -171,6 +179,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws NonZeroDecimalTypeException + */ + public function toNull(): never + { + throw new NonZeroDecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/DecimalNonZeroTest.php b/tests/Unit/Decimal/DecimalNonZeroTest.php index 6d40e107..688e7c9c 100755 --- a/tests/Unit/Decimal/DecimalNonZeroTest.php +++ b/tests/Unit/Decimal/DecimalNonZeroTest.php @@ -63,6 +63,14 @@ expect(DecimalNonZero::fromString('1.1')->jsonSerialize())->toBeString(); }); + it('fromNull throws NonZeroDecimalTypeException', function (): void { + expect(fn() => DecimalNonZero::fromNull(null))->toThrow(NonZeroDecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws NonZeroDecimalTypeException', function (): void { + expect(fn() => (new DecimalNonZero('1.0'))->toNull())->toThrow(NonZeroDecimalTypeException::class, 'Value cannot be null'); + }); + it('__toString returns the original decimal string', function (): void { $d = new DecimalNonZero('3.14'); expect((string) $d)->toBe('3.14') From 64bf753b8d18e9e867db24662077a020961e4137 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:19:51 +0200 Subject: [PATCH 16/83] Add null handling to DecimalPercent: fromNull and toNull throw PercentDecimalTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `PercentDecimalTypeException` and added unit tests to verify the exception behavior. --- src/Decimal/Specific/DecimalPercent.php | 16 ++++++++++++++++ .../Unit/Decimal/Specific/DecimalPercentTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Decimal/Specific/DecimalPercent.php b/src/Decimal/Specific/DecimalPercent.php index 76f6077c..86ef484f 100755 --- a/src/Decimal/Specific/DecimalPercent.php +++ b/src/Decimal/Specific/DecimalPercent.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static(static::intToDecimal($value)); } + /** + * @throws PercentDecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new PercentDecimalTypeException('Value cannot be null'); + } + /** * @throws PercentDecimalTypeException * @throws DecimalTypeException @@ -168,6 +176,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws PercentDecimalTypeException + */ + public function toNull(): never + { + throw new PercentDecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/Specific/DecimalPercentTest.php b/tests/Unit/Decimal/Specific/DecimalPercentTest.php index 74d0d468..112d922c 100755 --- a/tests/Unit/Decimal/Specific/DecimalPercentTest.php +++ b/tests/Unit/Decimal/Specific/DecimalPercentTest.php @@ -58,6 +58,14 @@ expect(DecimalPercent::fromString('1.1')->jsonSerialize())->toBeString(); }); + it('fromNull throws PercentDecimalTypeException', function (): void { + expect(fn() => DecimalPercent::fromNull(null))->toThrow(PercentDecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws PercentDecimalTypeException', function (): void { + expect(fn() => (new DecimalPercent('1.0'))->toNull())->toThrow(PercentDecimalTypeException::class, 'Value cannot be null'); + }); + it('__toString returns original string', function (): void { $d = new DecimalPercent('3.14'); expect((string) $d)->toBe('3.14'); From fb1fd68a4c03ec39013c27d0bc7453e67b7c8d3f Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:19:56 +0200 Subject: [PATCH 17/83] Add null handling to DecimalPositive: fromNull and toNull throw PositiveDecimalTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `PositiveDecimalTypeException` and added unit tests to verify the exception behavior. --- src/Decimal/DecimalPositive.php | 16 ++++++++++++++++ tests/Unit/Decimal/DecimalPositiveTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Decimal/DecimalPositive.php b/src/Decimal/DecimalPositive.php index 64444e04..0ba593fe 100755 --- a/src/Decimal/DecimalPositive.php +++ b/src/Decimal/DecimalPositive.php @@ -108,6 +108,14 @@ public static function fromInt(int $value): static return new static(static::intToDecimal($value)); } + /** + * @throws PositiveDecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new PositiveDecimalTypeException('Value cannot be null'); + } + /** * @throws PositiveDecimalTypeException * @throws DecimalTypeException @@ -181,6 +189,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws PositiveDecimalTypeException + */ + public function toNull(): never + { + throw new PositiveDecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/DecimalPositiveTest.php b/tests/Unit/Decimal/DecimalPositiveTest.php index 3c76ec92..15e6ac52 100755 --- a/tests/Unit/Decimal/DecimalPositiveTest.php +++ b/tests/Unit/Decimal/DecimalPositiveTest.php @@ -79,6 +79,14 @@ expect(DecimalPositive::fromString('1.1')->jsonSerialize())->toBeString(); }); + it('fromNull throws PositiveDecimalTypeException', function (): void { + expect(fn() => DecimalPositive::fromNull(null))->toThrow(PositiveDecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws PositiveDecimalTypeException', function (): void { + expect(fn() => (new DecimalPositive('1.0'))->toNull())->toThrow(PositiveDecimalTypeException::class, 'Value cannot be null'); + }); + it('__toString returns the original decimal string', function (): void { $d = new DecimalPositive('3.14'); expect((string) $d)->toBe('3.14') From 834167e23027284bfff8b493dede5affbd04ad28 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:20:03 +0200 Subject: [PATCH 18/83] Add null handling to DecimalProbability: fromNull and toNull throw ProbabilityDecimalTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `ProbabilityDecimalTypeException` and added unit tests to verify the exception behavior. --- src/Decimal/Specific/DecimalProbability.php | 21 ++++++++++++++----- .../Specific/DecimalProbabilityTest.php | 8 +++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Decimal/Specific/DecimalProbability.php b/src/Decimal/Specific/DecimalProbability.php index bdd363df..686ffb49 100755 --- a/src/Decimal/Specific/DecimalProbability.php +++ b/src/Decimal/Specific/DecimalProbability.php @@ -36,7 +36,6 @@ /** * @throws ProbabilityDecimalTypeException * @throws DecimalTypeException - * @throws StringTypeException */ public function __construct(string $value) { @@ -53,7 +52,6 @@ public function __construct(string $value) /** * @throws ProbabilityDecimalTypeException * @throws DecimalTypeException - * @throws StringTypeException * * @psalm-pure */ @@ -65,7 +63,6 @@ public static function fromBool(bool $value): static /** * @throws ProbabilityDecimalTypeException * @throws DecimalTypeException - * @throws StringTypeException * * @psalm-pure */ @@ -90,7 +87,6 @@ public static function fromFloat(float $value): static /** * @throws ProbabilityDecimalTypeException * @throws DecimalTypeException - * @throws StringTypeException * * @psalm-pure */ @@ -99,10 +95,17 @@ public static function fromInt(int $value): static return new static(static::intToDecimal($value)); } + /** + * @throws ProbabilityDecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new ProbabilityDecimalTypeException('Value cannot be null'); + } + /** * @throws ProbabilityDecimalTypeException * @throws DecimalTypeException - * @throws StringTypeException * * @psalm-pure */ @@ -173,6 +176,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws ProbabilityDecimalTypeException + */ + public function toNull(): never + { + throw new ProbabilityDecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/Specific/DecimalProbabilityTest.php b/tests/Unit/Decimal/Specific/DecimalProbabilityTest.php index bcf9f6b9..95aabc6a 100755 --- a/tests/Unit/Decimal/Specific/DecimalProbabilityTest.php +++ b/tests/Unit/Decimal/Specific/DecimalProbabilityTest.php @@ -60,6 +60,14 @@ expect(DecimalProbability::fromString('0.1')->jsonSerialize())->toBeString(); }); + it('fromNull throws ProbabilityDecimalTypeException', function (): void { + expect(fn() => DecimalProbability::fromNull(null))->toThrow(ProbabilityDecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws ProbabilityDecimalTypeException', function (): void { + expect(fn() => (new DecimalProbability('0.5'))->toNull())->toThrow(ProbabilityDecimalTypeException::class, 'Value cannot be null'); + }); + it('__toString returns original string', function (): void { $d = new DecimalProbability('0.314'); expect((string) $d)->toBe('0.314'); From ec583ae44dbe1339ac7015f82aab5055e7f028cd Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:20:08 +0200 Subject: [PATCH 19/83] Add null handling to DecimalStandard: fromNull and toNull throw DecimalTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `DecimalTypeException` and added unit tests to verify the exception behavior. --- src/Decimal/DecimalStandard.php | 16 ++++++++++++++++ tests/Unit/Decimal/DecimalStandardTest.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Decimal/DecimalStandard.php b/src/Decimal/DecimalStandard.php index f91fe983..00eba18a 100755 --- a/src/Decimal/DecimalStandard.php +++ b/src/Decimal/DecimalStandard.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static(static::intToDecimal($value)); } + /** + * @throws DecimalTypeException + */ + public static function fromNull(null $value): never + { + throw new DecimalTypeException('Value cannot be null'); + } + /** * @throws DecimalTypeException * @@ -167,6 +175,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws DecimalTypeException + */ + public function toNull(): never + { + throw new DecimalTypeException('Value cannot be null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Decimal/DecimalStandardTest.php b/tests/Unit/Decimal/DecimalStandardTest.php index b5faf20a..3be502ef 100755 --- a/tests/Unit/Decimal/DecimalStandardTest.php +++ b/tests/Unit/Decimal/DecimalStandardTest.php @@ -188,6 +188,14 @@ public function __toString(): string ->and(DecimalStandard::fromBool(false)->toString())->toBe('0.0'); }); + it('fromNull throws DecimalTypeException', function (): void { + expect(fn() => DecimalStandard::fromNull(null))->toThrow(DecimalTypeException::class, 'Value cannot be null'); + }); + + it('toNull throws DecimalTypeException', function (): void { + expect(fn() => (new DecimalStandard('1.0'))->toNull())->toThrow(DecimalTypeException::class, 'Value cannot be null'); + }); + it('cast int > decimal', function (): void { expect(DecimalStandard::fromInt(0)->toString())->toBe('0.0') ->and(DecimalStandard::fromInt(99999999999999999)->toString())->toBe('99999999999999999.0') From 1f21a3fce4c4f2c0858d519b0492b06d29cc5640 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:20:31 +0200 Subject: [PATCH 20/83] Add abstract null handling to DecimalTypeAbstract Declare `fromNull` and `toNull` as abstract methods in the base class and add corresponding test implementations that throw an exception for null values. --- src/Base/Primitive/Decimal/DecimalTypeAbstract.php | 4 ++++ src/Base/Primitive/Decimal/DecimalTypeInterface.php | 4 ++++ .../Base/Primitive/Decimal/DecimalTypeAbstractTest.php | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/Base/Primitive/Decimal/DecimalTypeAbstract.php b/src/Base/Primitive/Decimal/DecimalTypeAbstract.php index 09d7884e..3233e6d4 100755 --- a/src/Base/Primitive/Decimal/DecimalTypeAbstract.php +++ b/src/Base/Primitive/Decimal/DecimalTypeAbstract.php @@ -37,6 +37,8 @@ abstract public static function fromFloat(float $value): static; abstract public static function fromInt(int $value): static; + abstract public static function fromNull(null $value): never; + abstract public static function fromString(string $value): static; abstract public function isTypeOf(string ...$classNames): bool; @@ -76,6 +78,8 @@ abstract public function toFloat(): float; abstract public function toInt(): int; + abstract public function toNull(): never; + abstract public function toString(): string; /** diff --git a/src/Base/Primitive/Decimal/DecimalTypeInterface.php b/src/Base/Primitive/Decimal/DecimalTypeInterface.php index 3c66a038..7400fd52 100755 --- a/src/Base/Primitive/Decimal/DecimalTypeInterface.php +++ b/src/Base/Primitive/Decimal/DecimalTypeInterface.php @@ -29,6 +29,8 @@ public static function fromFloat(float $value): static; public static function fromInt(int $value): static; + public static function fromNull(null $value): never; + public static function fromString(string $value): static; public function isTypeOf(string ...$classNames): bool; @@ -41,6 +43,8 @@ public function toFloat(): float; public function toInt(): int; + public function toNull(): never; + public function toString(): string; /** diff --git a/tests/Unit/Base/Primitive/Decimal/DecimalTypeAbstractTest.php b/tests/Unit/Base/Primitive/Decimal/DecimalTypeAbstractTest.php index 6bb87528..8468f21e 100755 --- a/tests/Unit/Base/Primitive/Decimal/DecimalTypeAbstractTest.php +++ b/tests/Unit/Base/Primitive/Decimal/DecimalTypeAbstractTest.php @@ -85,6 +85,11 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + public static function fromNull(null $value): never + { + throw new Exception('Value cannot be null'); + } + public static function fromString(string $value): static { return new static($value); @@ -145,6 +150,11 @@ public function toInt(): int return static::stringToInt($this->value()); } + public function toNull(): never + { + throw new Exception('Value cannot be null'); + } + public function toString(): string { return $this->value(); From a9c2020ece4c996c1703ca660f5c4505730a4fad Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:28:16 +0200 Subject: [PATCH 21/83] Add null handling to FloatNegative: fromNull and toNull throw NegativeFloatTypeException Implemented static `fromNull` and instance `toNull` methods that always throw NegativeFloatTypeException and added corresponding unit tests. --- src/Float/FloatNegative.php | 16 ++++++++++++++++ tests/Unit/Float/FloatNegativeTest.php | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Float/FloatNegative.php b/src/Float/FloatNegative.php index c6dd14ad..2c619fc3 100755 --- a/src/Float/FloatNegative.php +++ b/src/Float/FloatNegative.php @@ -103,6 +103,14 @@ public static function fromInt(int $value): static return new static(parent::intToFloat($value)); } + /** + * @throws NegativeFloatTypeException + */ + public static function fromNull(null $value): never + { + throw new NegativeFloatTypeException('Float type cannot be created from null'); + } + /** * @throws NegativeFloatTypeException * @throws StringTypeException @@ -171,6 +179,14 @@ public function toInt(): int return static::floatToInt($this->value); } + /** + * @throws NegativeFloatTypeException + */ + public static function toNull(): never + { + throw new NegativeFloatTypeException('Float type cannot be converted to null'); + } + /** * @return non-empty-string * diff --git a/tests/Unit/Float/FloatNegativeTest.php b/tests/Unit/Float/FloatNegativeTest.php index 9c04b1de..19d6896d 100755 --- a/tests/Unit/Float/FloatNegativeTest.php +++ b/tests/Unit/Float/FloatNegativeTest.php @@ -92,6 +92,12 @@ ]); }); + describe('fromNull', function () { + it('throws exception on creation from null', function () { + expect(fn() => FloatNegative::fromNull(null))->toThrow(NegativeFloatTypeException::class, 'Float type cannot be created from null'); + }); + }); + describe('tryFromFloat', function () { it('returns instance or default value', function (float $input, mixed $expected) { $result = FloatNegative::tryFromFloat($input); @@ -361,5 +367,9 @@ public function __toString(): string it('converts to float', function () { expect(FloatNegative::fromFloat(-1.0)->toFloat())->toBe(-1.0); }); + + it('throws when converting to null', function () { + expect(fn() => FloatNegative::toNull())->toThrow(NegativeFloatTypeException::class, 'Float type cannot be converted to null'); + }); }); }); From cdd15990050108df78a2ef2bee2ba377df9fb273 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:28:22 +0200 Subject: [PATCH 22/83] Add null handling to FloatNonNegative: fromNull and toNull throw NonNegativeFloatTypeException Implemented static `fromNull` and instance `toNull` methods that always throw NonNegativeFloatTypeException and added corresponding unit tests. --- src/Float/FloatNonNegative.php | 16 ++++++++++++++++ tests/Unit/Float/FloatNonNegativeTest.php | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Float/FloatNonNegative.php b/src/Float/FloatNonNegative.php index 86c4415a..a4f9f8d3 100755 --- a/src/Float/FloatNonNegative.php +++ b/src/Float/FloatNonNegative.php @@ -103,6 +103,14 @@ public static function fromInt(int $value): static return new static(parent::intToFloat($value)); } + /** + * @throws NonNegativeFloatTypeException + */ + public static function fromNull(null $value): never + { + throw new NonNegativeFloatTypeException('Float type cannot be created from null'); + } + /** * @throws NonNegativeFloatTypeException * @throws StringTypeException @@ -171,6 +179,14 @@ public function toInt(): int return static::floatToInt($this->value); } + /** + * @throws NonNegativeFloatTypeException + */ + public static function toNull(): never + { + throw new NonNegativeFloatTypeException('Float type cannot be converted to null'); + } + /** * @return non-empty-string * diff --git a/tests/Unit/Float/FloatNonNegativeTest.php b/tests/Unit/Float/FloatNonNegativeTest.php index 6e9de802..c34d88cf 100755 --- a/tests/Unit/Float/FloatNonNegativeTest.php +++ b/tests/Unit/Float/FloatNonNegativeTest.php @@ -92,6 +92,12 @@ ]); }); + describe('fromNull', function () { + it('throws exception on creation from null', function () { + expect(fn() => FloatNonNegative::fromNull(null))->toThrow(NonNegativeFloatTypeException::class, 'Float type cannot be created from null'); + }); + }); + describe('tryFromFloat', function () { it('returns instance or default value', function (float $input, mixed $expected) { $result = FloatNonNegative::tryFromFloat($input); @@ -336,5 +342,9 @@ public function __toString(): string it('converts to float', function () { expect(FloatNonNegative::fromFloat(1.0)->toFloat())->toBe(1.0); }); + + it('throws when converting to null', function () { + expect(fn() => FloatNonNegative::toNull())->toThrow(NonNegativeFloatTypeException::class, 'Float type cannot be converted to null'); + }); }); }); From 4636249a70e92e35831db740633c1dbac3cad130 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:28:28 +0200 Subject: [PATCH 23/83] Add null handling to FloatNonPositive: fromNull and toNull throw NonPositiveFloatTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `NonPositiveFloatTypeException` and added unit tests to verify the exception behavior. --- src/Float/FloatNonPositive.php | 16 ++++++++++++++++ tests/Unit/Float/FloatNonPositiveTest.php | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/src/Float/FloatNonPositive.php b/src/Float/FloatNonPositive.php index 40fcaea5..226202ed 100755 --- a/src/Float/FloatNonPositive.php +++ b/src/Float/FloatNonPositive.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static(parent::intToFloat($value)); } + /** + * @throws NonPositiveFloatTypeException + */ + public static function fromNull(null $value): never + { + throw new NonPositiveFloatTypeException('Float type cannot be created from null'); + } + /** * @throws NonPositiveFloatTypeException * @throws StringTypeException @@ -162,6 +170,14 @@ public function toInt(): int return static::floatToInt($this->value); } + /** + * @throws NonPositiveFloatTypeException + */ + public static function toNull(): never + { + throw new NonPositiveFloatTypeException('Float type cannot be converted to null'); + } + /** * @return non-empty-string * diff --git a/tests/Unit/Float/FloatNonPositiveTest.php b/tests/Unit/Float/FloatNonPositiveTest.php index 1ed7677a..f3e9aef4 100755 --- a/tests/Unit/Float/FloatNonPositiveTest.php +++ b/tests/Unit/Float/FloatNonPositiveTest.php @@ -41,6 +41,11 @@ '-INF' => [-INF], ]); + it('throws on fromNull and toNull', function () { + expect(fn() => FloatNonPositive::fromNull(null))->toThrow(NonPositiveFloatTypeException::class, 'Float type cannot be created from null') + ->and(fn() => FloatNonPositive::toNull())->toThrow(NonPositiveFloatTypeException::class, 'Float type cannot be converted to null'); + }); + it('creates from mixed types', function () { expect(FloatNonPositive::fromDecimal('-1.5')->value())->toBe(-1.5) ->and(FloatNonPositive::fromFloat(-2.5)->value())->toBe(-2.5) From 4b581e63fbcbd2c61bcda74ae402d225e1970e95 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:28:33 +0200 Subject: [PATCH 24/83] Add null handling to FloatNonZero: fromNull and toNull throw NonZeroFloatTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `NonZeroFloatTypeException` and added a unit test to verify the exception behavior. --- src/Float/FloatNonZero.php | 16 ++++++++++++++++ tests/Unit/Float/FloatNonZeroTest.php | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/src/Float/FloatNonZero.php b/src/Float/FloatNonZero.php index 951bda69..7c1e331d 100755 --- a/src/Float/FloatNonZero.php +++ b/src/Float/FloatNonZero.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static(parent::intToFloat($value)); } + /** + * @throws NonZeroFloatTypeException + */ + public static function fromNull(null $value): never + { + throw new NonZeroFloatTypeException('Float type cannot be created from null'); + } + /** * @throws NonZeroFloatTypeException * @throws StringTypeException @@ -162,6 +170,14 @@ public function toInt(): int return static::floatToInt($this->value); } + /** + * @throws NonZeroFloatTypeException + */ + public static function toNull(): never + { + throw new NonZeroFloatTypeException('Float type cannot be converted to null'); + } + /** * @return non-empty-string * diff --git a/tests/Unit/Float/FloatNonZeroTest.php b/tests/Unit/Float/FloatNonZeroTest.php index ab590de7..ff785ab9 100755 --- a/tests/Unit/Float/FloatNonZeroTest.php +++ b/tests/Unit/Float/FloatNonZeroTest.php @@ -41,6 +41,11 @@ 'NAN' => [NAN], ]); + it('throws on fromNull and toNull', function () { + expect(fn() => FloatNonZero::fromNull(null))->toThrow(NonZeroFloatTypeException::class, 'Float type cannot be created from null') + ->and(fn() => FloatNonZero::toNull())->toThrow(NonZeroFloatTypeException::class, 'Float type cannot be converted to null'); + }); + it('creates from mixed types', function () { expect(FloatNonZero::fromBool(true)->value())->toBe(1.0) ->and(FloatNonZero::fromDecimal('1.5')->value())->toBe(1.5) From b427efc42377556270277ac1a0ad4cd9b1566aa9 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:28:39 +0200 Subject: [PATCH 25/83] Add null handling to FloatPercent: fromNull and toNull throw PercentFloatTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `PercentFloatTypeException`, and added a unit test to verify the exception behavior. --- src/Float/Specific/FloatPercent.php | 16 ++++++++++++++++ tests/Unit/Float/Specific/FloatPercentTest.php | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/src/Float/Specific/FloatPercent.php b/src/Float/Specific/FloatPercent.php index e5325e0c..9c80d10e 100755 --- a/src/Float/Specific/FloatPercent.php +++ b/src/Float/Specific/FloatPercent.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static(parent::intToFloat($value)); } + /** + * @throws PercentFloatTypeException + */ + public static function fromNull(null $value): never + { + throw new PercentFloatTypeException('Float type cannot be created from null'); + } + /** * @throws PercentFloatTypeException * @throws StringTypeException @@ -162,6 +170,14 @@ public function toInt(): int return static::floatToInt($this->value); } + /** + * @throws PercentFloatTypeException + */ + public static function toNull(): never + { + throw new PercentFloatTypeException('Float type cannot be converted to null'); + } + /** * @return non-empty-string * diff --git a/tests/Unit/Float/Specific/FloatPercentTest.php b/tests/Unit/Float/Specific/FloatPercentTest.php index f8077283..cde5063a 100755 --- a/tests/Unit/Float/Specific/FloatPercentTest.php +++ b/tests/Unit/Float/Specific/FloatPercentTest.php @@ -42,6 +42,11 @@ 'NAN' => [NAN], ]); + it('throws on fromNull and toNull', function () { + expect(fn() => FloatPercent::fromNull(null))->toThrow(PercentFloatTypeException::class, 'Float type cannot be created from null') + ->and(fn() => FloatPercent::toNull())->toThrow(PercentFloatTypeException::class, 'Float type cannot be converted to null'); + }); + it('creates from mixed types', function () { expect(FloatPercent::fromBool(true)->value())->toBe(1.0) ->and(FloatPercent::fromDecimal('1.5')->value())->toBe(1.5) From d95d444db5eeec422a5051e7c4e444c1686ece3e Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:28:45 +0200 Subject: [PATCH 26/83] Add null handling to FloatPositive: fromNull and toNull throw PositiveFloatTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `PositiveFloatTypeException`, and added unit tests to verify the exception behavior. --- src/Float/FloatPositive.php | 16 ++++++++++++++++ tests/Unit/Float/FloatPositiveTest.php | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Float/FloatPositive.php b/src/Float/FloatPositive.php index c70d2cdb..72eee9eb 100755 --- a/src/Float/FloatPositive.php +++ b/src/Float/FloatPositive.php @@ -103,6 +103,14 @@ public static function fromInt(int $value): static return new static(parent::intToFloat($value)); } + /** + * @throws PositiveFloatTypeException + */ + public static function fromNull(null $value): never + { + throw new PositiveFloatTypeException('Float type cannot be created from null'); + } + /** * @throws PositiveFloatTypeException * @throws StringTypeException @@ -171,6 +179,14 @@ public function toInt(): int return static::floatToInt($this->value); } + /** + * @throws PositiveFloatTypeException + */ + public static function toNull(): never + { + throw new PositiveFloatTypeException('Float type cannot be converted to null'); + } + /** * @return non-empty-string * diff --git a/tests/Unit/Float/FloatPositiveTest.php b/tests/Unit/Float/FloatPositiveTest.php index beec6426..9a9b89eb 100755 --- a/tests/Unit/Float/FloatPositiveTest.php +++ b/tests/Unit/Float/FloatPositiveTest.php @@ -119,6 +119,12 @@ ]); }); + describe('fromNull', function () { + it('throws exception on creation from null', function () { + expect(fn() => FloatPositive::fromNull(null))->toThrow(PositiveFloatTypeException::class, 'Float type cannot be created from null'); + }); + }); + describe('tryFromInt', function () { it('returns instance or default value', function (int $input, mixed $expected) { $result = FloatPositive::tryFromInt($input); @@ -325,5 +331,9 @@ public function __toString(): string it('converts to float', function () { expect(FloatPositive::fromFloat(1.0)->toFloat())->toBe(1.0); }); + + it('throws when converting to null', function () { + expect(fn() => FloatPositive::toNull())->toThrow(PositiveFloatTypeException::class, 'Float type cannot be converted to null'); + }); }); }); From 7ccae3afe009e76dffed5d81a8dfc9ad8d142ca0 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:28:50 +0200 Subject: [PATCH 27/83] Add null handling to FloatProbability: fromNull and toNull throw ProbabilityFloatTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `ProbabilityFloatTypeException` and added unit tests to verify the exception behavior. --- src/Float/Specific/FloatProbability.php | 16 ++++++++++++++++ .../Unit/Float/Specific/FloatProbabilityTest.php | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/src/Float/Specific/FloatProbability.php b/src/Float/Specific/FloatProbability.php index 32f4f18f..3f526846 100755 --- a/src/Float/Specific/FloatProbability.php +++ b/src/Float/Specific/FloatProbability.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static(parent::intToFloat($value)); } + /** + * @throws ProbabilityFloatTypeException + */ + public static function fromNull(null $value): never + { + throw new ProbabilityFloatTypeException('Float type cannot be created from null'); + } + /** * @throws ProbabilityFloatTypeException * @throws StringTypeException @@ -162,6 +170,14 @@ public function toInt(): int return static::floatToInt($this->value); } + /** + * @throws ProbabilityFloatTypeException + */ + public static function toNull(): never + { + throw new ProbabilityFloatTypeException('Float type cannot be converted to null'); + } + /** * @return non-empty-string * diff --git a/tests/Unit/Float/Specific/FloatProbabilityTest.php b/tests/Unit/Float/Specific/FloatProbabilityTest.php index 7a5987eb..92b8eafa 100755 --- a/tests/Unit/Float/Specific/FloatProbabilityTest.php +++ b/tests/Unit/Float/Specific/FloatProbabilityTest.php @@ -42,6 +42,11 @@ 'NAN' => [NAN], ]); + it('throws on fromNull and toNull', function () { + expect(fn() => FloatProbability::fromNull(null))->toThrow(ProbabilityFloatTypeException::class, 'Float type cannot be created from null') + ->and(fn() => FloatProbability::toNull())->toThrow(ProbabilityFloatTypeException::class, 'Float type cannot be converted to null'); + }); + it('creates from mixed types', function () { expect(FloatProbability::fromBool(true)->value())->toBe(1.0) ->and(FloatProbability::fromDecimal('0.5')->value())->toBe(0.5) From 413c9032cd0049cde1f85049194c41a205b7af60 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:28:54 +0200 Subject: [PATCH 28/83] Add null handling to FloatStandard: fromNull and toNull throw FloatTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `FloatTypeException` and added unit tests to verify the exception behavior. --- src/Float/FloatStandard.php | 16 ++++++++++++++++ tests/Unit/Float/FloatStandardTest.php | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Float/FloatStandard.php b/src/Float/FloatStandard.php index 0c44644b..6d637145 100755 --- a/src/Float/FloatStandard.php +++ b/src/Float/FloatStandard.php @@ -97,6 +97,14 @@ public static function fromInt(int $value): static return new static(parent::intToFloat($value)); } + /** + * @throws FloatTypeException + */ + public static function fromNull(null $value): never + { + throw new FloatTypeException('Float type cannot be created from null'); + } + /** * @throws FloatTypeException * @throws StringTypeException @@ -165,6 +173,14 @@ public function toInt(): int return static::floatToInt($this->value); } + /** + * @throws FloatTypeException + */ + public static function toNull(): never + { + throw new FloatTypeException('Float type cannot be converted to null'); + } + /** * @return non-empty-string * diff --git a/tests/Unit/Float/FloatStandardTest.php b/tests/Unit/Float/FloatStandardTest.php index 4b30f4ba..538638ba 100755 --- a/tests/Unit/Float/FloatStandardTest.php +++ b/tests/Unit/Float/FloatStandardTest.php @@ -99,6 +99,12 @@ ]); }); + describe('fromNull', function () { + it('throws exception on creation from null', function () { + expect(fn() => FloatStandard::fromNull(null))->toThrow(FloatTypeException::class, 'Float type cannot be created from null'); + }); + }); + describe('tryFromFloat', function () { it('returns instance or default value', function (float $input, mixed $expected) { $result = FloatStandard::tryFromFloat($input); @@ -394,6 +400,10 @@ public function __toString(): string it('converts to float', function () { expect(FloatStandard::fromFloat(1.0)->toFloat())->toBe(1.0); }); + + it('throws when converting to null', function () { + expect(fn() => FloatStandard::toNull())->toThrow(FloatTypeException::class, 'Float type cannot be converted to null'); + }); }); }); From d7445a8550df6510ca3e490ba7d52e562cf9da3b Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:29:14 +0200 Subject: [PATCH 29/83] Add abstract null handling to FloatTypeAbstract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare `fromNull(null)` and `toNull()` as abstract methods in the interface and abstract class, and provide test implementations that always throw `FloatTypeException`. --- src/Base/Primitive/Float/FloatTypeAbstract.php | 4 ++++ src/Base/Primitive/Float/FloatTypeInterface.php | 4 ++++ .../Base/Primitive/Float/FloatTypeAbstractTest.php | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/Base/Primitive/Float/FloatTypeAbstract.php b/src/Base/Primitive/Float/FloatTypeAbstract.php index c391a9d8..d837ae99 100755 --- a/src/Base/Primitive/Float/FloatTypeAbstract.php +++ b/src/Base/Primitive/Float/FloatTypeAbstract.php @@ -34,6 +34,8 @@ abstract public static function fromFloat(float $value): static; abstract public static function fromInt(int $value): static; + abstract public static function fromNull(null $value): never; + abstract public static function fromString(string $value): static; abstract public function toBool(): bool; @@ -44,6 +46,8 @@ abstract public function toFloat(): float; abstract public function toInt(): int; + abstract public static function toNull(): never; + abstract public function toString(): string; /** diff --git a/src/Base/Primitive/Float/FloatTypeInterface.php b/src/Base/Primitive/Float/FloatTypeInterface.php index 53df1ccd..127da438 100755 --- a/src/Base/Primitive/Float/FloatTypeInterface.php +++ b/src/Base/Primitive/Float/FloatTypeInterface.php @@ -29,6 +29,8 @@ public static function fromFloat(float $value): static; public static function fromInt(int $value): static; + public static function fromNull(null $value): never; + public static function fromString(string $value): static; public function isTypeOf(string ...$classNames): bool; @@ -41,6 +43,8 @@ public function toFloat(): float; public function toInt(): int; + public static function toNull(): never; + public function toString(): string; /** diff --git a/tests/Unit/Base/Primitive/Float/FloatTypeAbstractTest.php b/tests/Unit/Base/Primitive/Float/FloatTypeAbstractTest.php index 5789470d..66ace255 100755 --- a/tests/Unit/Base/Primitive/Float/FloatTypeAbstractTest.php +++ b/tests/Unit/Base/Primitive/Float/FloatTypeAbstractTest.php @@ -55,6 +55,11 @@ public static function fromInt(int $value): static return new static(static::intToFloat($value)); } + public static function fromNull(null $value): never + { + throw new FloatTypeException('Float type cannot be created from null'); + } + public static function fromString(string $value): static { return new static(static::stringToFloat($value)); @@ -106,6 +111,11 @@ public function toInt(): int return static::floatToInt($this->val); } + public static function toNull(): never + { + throw new FloatTypeException('Float type cannot be converted to null'); + } + public function toString(): string { return static::floatToString($this->val); From 27fa1e9d35fc2dd1e1f8c18b3c79a183574eb631 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:36:58 +0200 Subject: [PATCH 30/83] Add @throws FloatTypeException to Float type methods Update docblocks of `fromDecimal` and conversion methods in all Float classes (Positive, NonNegative, NonPositive, Negative, NonZero, FloatPercent, FloatProbability) to include `@throws FloatTypeException`. --- src/Float/FloatNegative.php | 2 ++ src/Float/FloatNonNegative.php | 2 ++ src/Float/FloatNonPositive.php | 2 ++ src/Float/FloatNonZero.php | 2 ++ src/Float/FloatPositive.php | 2 ++ src/Float/Specific/FloatPercent.php | 2 ++ src/Float/Specific/FloatProbability.php | 2 ++ 7 files changed, 14 insertions(+) diff --git a/src/Float/FloatNegative.php b/src/Float/FloatNegative.php index 2c619fc3..86e8470b 100755 --- a/src/Float/FloatNegative.php +++ b/src/Float/FloatNegative.php @@ -76,6 +76,7 @@ public static function fromBool(bool $value): static * @throws DecimalTypeException * @throws NegativeFloatTypeException * @throws StringTypeException + * @throws FloatTypeException */ public static function fromDecimal(string $value): static { @@ -114,6 +115,7 @@ public static function fromNull(null $value): never /** * @throws NegativeFloatTypeException * @throws StringTypeException + * @throws FloatTypeException * * @psalm-pure */ diff --git a/src/Float/FloatNonNegative.php b/src/Float/FloatNonNegative.php index a4f9f8d3..c164151c 100755 --- a/src/Float/FloatNonNegative.php +++ b/src/Float/FloatNonNegative.php @@ -76,6 +76,7 @@ public static function fromBool(bool $value): static * @throws DecimalTypeException * @throws NonNegativeFloatTypeException * @throws StringTypeException + * @throws FloatTypeException */ public static function fromDecimal(string $value): static { @@ -114,6 +115,7 @@ public static function fromNull(null $value): never /** * @throws NonNegativeFloatTypeException * @throws StringTypeException + * @throws FloatTypeException * * @psalm-pure */ diff --git a/src/Float/FloatNonPositive.php b/src/Float/FloatNonPositive.php index 226202ed..3e325c31 100755 --- a/src/Float/FloatNonPositive.php +++ b/src/Float/FloatNonPositive.php @@ -67,6 +67,7 @@ public static function fromBool(bool $value): static * @throws DecimalTypeException * @throws NonPositiveFloatTypeException * @throws StringTypeException + * @throws FloatTypeException */ public static function fromDecimal(string $value): static { @@ -105,6 +106,7 @@ public static function fromNull(null $value): never /** * @throws NonPositiveFloatTypeException * @throws StringTypeException + * @throws FloatTypeException * * @psalm-pure */ diff --git a/src/Float/FloatNonZero.php b/src/Float/FloatNonZero.php index 7c1e331d..9ce57859 100755 --- a/src/Float/FloatNonZero.php +++ b/src/Float/FloatNonZero.php @@ -67,6 +67,7 @@ public static function fromBool(bool $value): static * @throws DecimalTypeException * @throws NonZeroFloatTypeException * @throws StringTypeException + * @throws FloatTypeException */ public static function fromDecimal(string $value): static { @@ -105,6 +106,7 @@ public static function fromNull(null $value): never /** * @throws NonZeroFloatTypeException * @throws StringTypeException + * @throws FloatTypeException * * @psalm-pure */ diff --git a/src/Float/FloatPositive.php b/src/Float/FloatPositive.php index 72eee9eb..ba9ed223 100755 --- a/src/Float/FloatPositive.php +++ b/src/Float/FloatPositive.php @@ -76,6 +76,7 @@ public static function fromBool(bool $value): static * @throws DecimalTypeException * @throws PositiveFloatTypeException * @throws StringTypeException + * @throws FloatTypeException */ public static function fromDecimal(string $value): static { @@ -114,6 +115,7 @@ public static function fromNull(null $value): never /** * @throws PositiveFloatTypeException * @throws StringTypeException + * @throws FloatTypeException * * @psalm-pure */ diff --git a/src/Float/Specific/FloatPercent.php b/src/Float/Specific/FloatPercent.php index 9c80d10e..fe8ca022 100755 --- a/src/Float/Specific/FloatPercent.php +++ b/src/Float/Specific/FloatPercent.php @@ -67,6 +67,7 @@ public static function fromBool(bool $value): static * @throws DecimalTypeException * @throws PercentFloatTypeException * @throws StringTypeException + * @throws FloatTypeException */ public static function fromDecimal(string $value): static { @@ -105,6 +106,7 @@ public static function fromNull(null $value): never /** * @throws PercentFloatTypeException * @throws StringTypeException + * @throws FloatTypeException * * @psalm-pure */ diff --git a/src/Float/Specific/FloatProbability.php b/src/Float/Specific/FloatProbability.php index 3f526846..bad5a6cb 100755 --- a/src/Float/Specific/FloatProbability.php +++ b/src/Float/Specific/FloatProbability.php @@ -67,6 +67,7 @@ public static function fromBool(bool $value): static * @throws DecimalTypeException * @throws ProbabilityFloatTypeException * @throws StringTypeException + * @throws FloatTypeException */ public static function fromDecimal(string $value): static { @@ -105,6 +106,7 @@ public static function fromNull(null $value): never /** * @throws ProbabilityFloatTypeException * @throws StringTypeException + * @throws FloatTypeException * * @psalm-pure */ From a3a10bed74d726c91342777928ec81eb662496db Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:46:08 +0200 Subject: [PATCH 31/83] Add null handling to IntegerAge: fromNull and toNull throw AgeIntegerTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `AgeIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerAge.php | 16 ++++++++++++++++ tests/Unit/Integer/Specific/IntegerAgeTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerAge.php b/src/Integer/Specific/IntegerAge.php index 1d702d6f..9900b099 100755 --- a/src/Integer/Specific/IntegerAge.php +++ b/src/Integer/Specific/IntegerAge.php @@ -98,6 +98,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws AgeIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new AgeIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws AgeIntegerTypeException @@ -161,6 +169,14 @@ public function toInt(): int return $this->value; } + /** + * @throws AgeIntegerTypeException + */ + public static function toNull(): never + { + throw new AgeIntegerTypeException('Integer type cannot be converted to null'); + } + public function toString(): string { return (string) $this->value(); diff --git a/tests/Unit/Integer/Specific/IntegerAgeTest.php b/tests/Unit/Integer/Specific/IntegerAgeTest.php index 4170410d..5e1d7c2b 100755 --- a/tests/Unit/Integer/Specific/IntegerAgeTest.php +++ b/tests/Unit/Integer/Specific/IntegerAgeTest.php @@ -302,4 +302,16 @@ public function __toString(): string ->and($age->isTypeOf('NonExistentClass', IntegerAge::class))->toBeTrue(); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerAge::fromNull(null)) + ->toThrow(AgeIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerAge::toNull()) + ->toThrow(AgeIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 959f09b20649a7c1ebe02e9561f98e7ca6947c8c Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:46:13 +0200 Subject: [PATCH 32/83] Add null handling to IntegerBig: fromNull and toNull throw BigIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `BigIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/MariaDb/IntegerBig.php | 16 ++++++++++++++++ tests/Unit/Integer/MariaDb/IntegerBigTest.php | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Integer/MariaDb/IntegerBig.php b/src/Integer/MariaDb/IntegerBig.php index 4d647499..89f934cb 100755 --- a/src/Integer/MariaDb/IntegerBig.php +++ b/src/Integer/MariaDb/IntegerBig.php @@ -91,6 +91,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws BigIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new BigIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws BigIntegerTypeException @@ -157,6 +165,14 @@ public function toInt(): int return $this->value; } + /** + * @throws BigIntegerTypeException + */ + public static function toNull(): never + { + throw new BigIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerBigTest.php b/tests/Unit/Integer/MariaDb/IntegerBigTest.php index 3f9be4ec..7d82244a 100755 --- a/tests/Unit/Integer/MariaDb/IntegerBigTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerBigTest.php @@ -10,6 +10,7 @@ use Exception; use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; +use PhpTypedValues\Exception\Integer\BigIntegerTypeException; use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Integer\MariaDb\IntegerBig; use PhpTypedValues\Undefined\Alias\Undefined; @@ -413,4 +414,16 @@ public static function fromString(string $value): static expect(IntegerBigTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerBig::fromNull(null)) + ->toThrow(BigIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerBig::toNull()) + ->toThrow(BigIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From c4ecfac1e3f17140e6d71d659b432e04251df0f8 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:46:18 +0200 Subject: [PATCH 33/83] Add null handling to IntegerBigUnsigned: fromNull and toNull throw UnsignedBigIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `UnsignedBigIntegerTypeException`. --- src/Integer/MariaDb/IntegerBigUnsigned.php | 16 ++++++++++++++++ .../Integer/MariaDb/IntegerBigUnsignedTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/MariaDb/IntegerBigUnsigned.php b/src/Integer/MariaDb/IntegerBigUnsigned.php index 695a5ce4..3ea5cdce 100755 --- a/src/Integer/MariaDb/IntegerBigUnsigned.php +++ b/src/Integer/MariaDb/IntegerBigUnsigned.php @@ -98,6 +98,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws UnsignedBigIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new UnsignedBigIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws UnsignedBigIntegerTypeException @@ -170,6 +178,14 @@ public function toInt(): int return $this->value; } + /** + * @throws UnsignedBigIntegerTypeException + */ + public static function toNull(): never + { + throw new UnsignedBigIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerBigUnsignedTest.php b/tests/Unit/Integer/MariaDb/IntegerBigUnsignedTest.php index d1baab36..bbc91e80 100755 --- a/tests/Unit/Integer/MariaDb/IntegerBigUnsignedTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerBigUnsignedTest.php @@ -318,4 +318,16 @@ public static function fromString(string $value): static expect(IntegerBigUnsignedTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerBigUnsigned::fromNull(null)) + ->toThrow(UnsignedBigIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerBigUnsigned::toNull()) + ->toThrow(UnsignedBigIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 0f234ba2175eedb19ee6d2390d2092d6bd2933a1 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:46:37 +0200 Subject: [PATCH 34/83] Add null handling to IntegerDayOfMonth: fromNull and toNull throw DayOfMonthIntegerTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `DayOfMonthIntegerTypeException`. --- src/Integer/Specific/IntegerDayOfMonth.php | 16 ++++++++++++++++ .../Integer/Specific/IntegerDayOfMonthTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerDayOfMonth.php b/src/Integer/Specific/IntegerDayOfMonth.php index 5dea40f0..9c541bcb 100755 --- a/src/Integer/Specific/IntegerDayOfMonth.php +++ b/src/Integer/Specific/IntegerDayOfMonth.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws DayOfMonthIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new DayOfMonthIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws DayOfMonthIntegerTypeException @@ -157,6 +165,14 @@ public function toInt(): int return $this->value; } + /** + * @throws DayOfMonthIntegerTypeException + */ + public static function toNull(): never + { + throw new DayOfMonthIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerDayOfMonthTest.php b/tests/Unit/Integer/Specific/IntegerDayOfMonthTest.php index 53e08e84..767965a3 100755 --- a/tests/Unit/Integer/Specific/IntegerDayOfMonthTest.php +++ b/tests/Unit/Integer/Specific/IntegerDayOfMonthTest.php @@ -399,4 +399,16 @@ public function __toString(): string expect($result)->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerDayOfMonth::fromNull(null)) + ->toThrow(DayOfMonthIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerDayOfMonth::toNull()) + ->toThrow(DayOfMonthIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From ad15b64b5ca39533dacd0fa18246e6257a7f5398 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:46:48 +0200 Subject: [PATCH 35/83] Add null handling to IntegerHour: fromNull and toNull throw HourIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `HourIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerHour.php | 16 ++++++++++++++++ tests/Unit/Integer/Specific/IntegerHourTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerHour.php b/src/Integer/Specific/IntegerHour.php index 990c8746..68cfc1ac 100755 --- a/src/Integer/Specific/IntegerHour.php +++ b/src/Integer/Specific/IntegerHour.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws HourIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new HourIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws HourIntegerTypeException @@ -157,6 +165,14 @@ public function toInt(): int return $this->value; } + /** + * @throws HourIntegerTypeException + */ + public static function toNull(): never + { + throw new HourIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerHourTest.php b/tests/Unit/Integer/Specific/IntegerHourTest.php index efd82150..8279f6e6 100755 --- a/tests/Unit/Integer/Specific/IntegerHourTest.php +++ b/tests/Unit/Integer/Specific/IntegerHourTest.php @@ -428,4 +428,16 @@ public function __toString(): string expect($result)->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerHour::fromNull(null)) + ->toThrow(HourIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerHour::toNull()) + ->toThrow(HourIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From e99d84fc14275fc6a40d683a643cd3c27a1150dd Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:46:54 +0200 Subject: [PATCH 36/83] Add null handling to IntegerHttpStatusCode: fromNull and toNull throw HttpStatusCodeIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `HttpStatusCodeIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerHttpStatusCode.php | 16 ++++++++++++++++ .../Specific/IntegerHttpStatusCodeTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerHttpStatusCode.php b/src/Integer/Specific/IntegerHttpStatusCode.php index 0270523d..efc7bebd 100755 --- a/src/Integer/Specific/IntegerHttpStatusCode.php +++ b/src/Integer/Specific/IntegerHttpStatusCode.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws HttpStatusCodeIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new HttpStatusCodeIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws HttpStatusCodeIntegerTypeException @@ -157,6 +165,14 @@ public function toInt(): int return $this->value; } + /** + * @throws HttpStatusCodeIntegerTypeException + */ + public static function toNull(): never + { + throw new HttpStatusCodeIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerHttpStatusCodeTest.php b/tests/Unit/Integer/Specific/IntegerHttpStatusCodeTest.php index f545821c..a4dfbda8 100755 --- a/tests/Unit/Integer/Specific/IntegerHttpStatusCodeTest.php +++ b/tests/Unit/Integer/Specific/IntegerHttpStatusCodeTest.php @@ -321,4 +321,16 @@ public function __toString(): string expect($v2->value())->toBe($original); })->with([100, 200, 599]); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerHttpStatusCode::fromNull(null)) + ->toThrow(HttpStatusCodeIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerHttpStatusCode::toNull()) + ->toThrow(HttpStatusCodeIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 54d24c08350d6e3b595a09bfbe2317340da2d64f Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:47:14 +0200 Subject: [PATCH 37/83] Add null handling to IntegerMedium: fromNull and toNull throw MediumIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `MediumIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/MariaDb/IntegerMedium.php | 16 ++++++++++++++++ tests/Unit/Integer/MariaDb/IntegerMediumTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/MariaDb/IntegerMedium.php b/src/Integer/MariaDb/IntegerMedium.php index fae218b7..3bd1636e 100755 --- a/src/Integer/MariaDb/IntegerMedium.php +++ b/src/Integer/MariaDb/IntegerMedium.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws MediumIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new MediumIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws MediumIntegerTypeException @@ -167,6 +175,14 @@ public function toInt(): int return $this->value; } + /** + * @throws MediumIntegerTypeException + */ + public static function toNull(): never + { + throw new MediumIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerMediumTest.php b/tests/Unit/Integer/MariaDb/IntegerMediumTest.php index 80305a3f..5bdbcd79 100755 --- a/tests/Unit/Integer/MariaDb/IntegerMediumTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerMediumTest.php @@ -385,4 +385,16 @@ public static function fromString(string $value): static expect(IntegerMediumTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerMedium::fromNull(null)) + ->toThrow(MediumIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerMedium::toNull()) + ->toThrow(MediumIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 689e67d2ab5b06a51dbac4289a6da3a0e0df9745 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:47:19 +0200 Subject: [PATCH 38/83] Add null handling to IntegerMediumUnsigned: fromNull and toNull throw UnsignedMediumIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `UnsignedMediumIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/MariaDb/IntegerMediumUnsigned.php | 16 ++++++++++++++++ .../MariaDb/IntegerMediumUnsignedTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/MariaDb/IntegerMediumUnsigned.php b/src/Integer/MariaDb/IntegerMediumUnsigned.php index b5540623..023d0c23 100755 --- a/src/Integer/MariaDb/IntegerMediumUnsigned.php +++ b/src/Integer/MariaDb/IntegerMediumUnsigned.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws UnsignedMediumIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new UnsignedMediumIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws UnsignedMediumIntegerTypeException @@ -167,6 +175,14 @@ public function toInt(): int return $this->value; } + /** + * @throws UnsignedMediumIntegerTypeException + */ + public static function toNull(): never + { + throw new UnsignedMediumIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerMediumUnsignedTest.php b/tests/Unit/Integer/MariaDb/IntegerMediumUnsignedTest.php index 9cfdeb97..e886e0fc 100755 --- a/tests/Unit/Integer/MariaDb/IntegerMediumUnsignedTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerMediumUnsignedTest.php @@ -366,4 +366,16 @@ public static function fromString(string $value): static expect(IntegerMediumUnsignedTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerMediumUnsigned::fromNull(null)) + ->toThrow(UnsignedMediumIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerMediumUnsigned::toNull()) + ->toThrow(UnsignedMediumIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 6142bd0421b92b050d0ecb029f9000561e3c2180 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:47:24 +0200 Subject: [PATCH 39/83] Add null handling to IntegerMinute: fromNull and toNull throw MinuteIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `MinuteIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerMinute.php | 16 ++++++++++++++++ .../Unit/Integer/Specific/IntegerMinuteTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerMinute.php b/src/Integer/Specific/IntegerMinute.php index 6508a643..c4e4a032 100755 --- a/src/Integer/Specific/IntegerMinute.php +++ b/src/Integer/Specific/IntegerMinute.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws MinuteIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new MinuteIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws MinuteIntegerTypeException @@ -157,6 +165,14 @@ public function toInt(): int return $this->value; } + /** + * @throws MinuteIntegerTypeException + */ + public static function toNull(): never + { + throw new MinuteIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerMinuteTest.php b/tests/Unit/Integer/Specific/IntegerMinuteTest.php index e2656128..aca3f3f9 100755 --- a/tests/Unit/Integer/Specific/IntegerMinuteTest.php +++ b/tests/Unit/Integer/Specific/IntegerMinuteTest.php @@ -428,4 +428,16 @@ public function __toString(): string expect($result)->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerMinute::fromNull(null)) + ->toThrow(MinuteIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerMinute::toNull()) + ->toThrow(MinuteIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From bdb3a54ccbd3d4c97f51d1cf6eb8ac3e1914ad2b Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:47:29 +0200 Subject: [PATCH 40/83] Add null handling to IntegerMonth: fromNull and toNull throw MonthIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `MonthIntegerTypeException`. --- src/Integer/Specific/IntegerMonth.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Integer/Specific/IntegerMonth.php b/src/Integer/Specific/IntegerMonth.php index a86eeb08..c9eaa2fd 100755 --- a/src/Integer/Specific/IntegerMonth.php +++ b/src/Integer/Specific/IntegerMonth.php @@ -125,6 +125,14 @@ public static function fromLabel(string $label): static return new static($value); } + /** + * @throws MonthIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new MonthIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws MonthIntegerTypeException @@ -209,6 +217,14 @@ public function toLabel(): string }; } + /** + * @throws MonthIntegerTypeException + */ + public static function toNull(): never + { + throw new MonthIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ From 8277fa421c63c2334b9d271821d8f548b52743a5 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:47:33 +0200 Subject: [PATCH 41/83] Add null handling tests for IntegerMonth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verify that IntegerMonth::fromNull and IntegerMonth::toNull both throw MonthIntegerTypeException. --- tests/Unit/Integer/Specific/IntegerMonthTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/Unit/Integer/Specific/IntegerMonthTest.php b/tests/Unit/Integer/Specific/IntegerMonthTest.php index 2fc31a31..cbe38e48 100755 --- a/tests/Unit/Integer/Specific/IntegerMonthTest.php +++ b/tests/Unit/Integer/Specific/IntegerMonthTest.php @@ -501,4 +501,16 @@ public function __toString(): string expect($result)->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerMonth::fromNull(null)) + ->toThrow(MonthIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerMonth::toNull()) + ->toThrow(MonthIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 71497d98407ba04552084253eefa22a217e18e32 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:47:56 +0200 Subject: [PATCH 42/83] Add null handling to IntegerNegative: fromNull and toNull throw NegativeIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `NegativeIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/IntegerNegative.php | 16 ++++++++++++++++ tests/Unit/Integer/IntegerNegativeTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/IntegerNegative.php b/src/Integer/IntegerNegative.php index b3c7968b..ec32d7db 100755 --- a/src/Integer/IntegerNegative.php +++ b/src/Integer/IntegerNegative.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws NegativeIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new NegativeIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws NegativeIntegerTypeException @@ -161,6 +169,14 @@ public function toInt(): int return $this->value; } + /** + * @throws NegativeIntegerTypeException + */ + public static function toNull(): never + { + throw new NegativeIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/IntegerNegativeTest.php b/tests/Unit/Integer/IntegerNegativeTest.php index ffd53ad1..b75080d6 100755 --- a/tests/Unit/Integer/IntegerNegativeTest.php +++ b/tests/Unit/Integer/IntegerNegativeTest.php @@ -276,4 +276,16 @@ public function __toString(): string expect($v2->toString())->toBe($original); })->with(['-1', '-42', (string) \PHP_INT_MIN]); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerNegative::fromNull(null)) + ->toThrow(NegativeIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerNegative::toNull()) + ->toThrow(NegativeIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 384c070ef05d2429afd6f522e6c9d4507bb70029 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:48:01 +0200 Subject: [PATCH 43/83] Add null handling to IntegerNonNegative: fromNull and toNull throw NonNegativeIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `NonNegativeIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/IntegerNonNegative.php | 16 ++++++++++++++++ tests/Unit/Integer/IntegerNonNegativeTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/IntegerNonNegative.php b/src/Integer/IntegerNonNegative.php index dc0bc851..dbb3c944 100755 --- a/src/Integer/IntegerNonNegative.php +++ b/src/Integer/IntegerNonNegative.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws NonNegativeIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new NonNegativeIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws NonNegativeIntegerTypeException @@ -161,6 +169,14 @@ public function toInt(): int return $this->value; } + /** + * @throws NonNegativeIntegerTypeException + */ + public static function toNull(): never + { + throw new NonNegativeIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/IntegerNonNegativeTest.php b/tests/Unit/Integer/IntegerNonNegativeTest.php index 9c3a101d..9f59dc4e 100755 --- a/tests/Unit/Integer/IntegerNonNegativeTest.php +++ b/tests/Unit/Integer/IntegerNonNegativeTest.php @@ -350,4 +350,16 @@ public function __toString(): string expect($v2->toString())->toBe($original); })->with(['0', '42', (string) PHP_INT_MAX]); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerNonNegative::fromNull(null)) + ->toThrow(NonNegativeIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerNonNegative::toNull()) + ->toThrow(NonNegativeIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 3c8738a0012e43b31c6da001c5e8808c48294cf5 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:48:11 +0200 Subject: [PATCH 44/83] Add null handling to IntegerNonPositive: fromNull and toNull throw NonPositiveIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `NonPositiveIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/IntegerNonPositive.php | 16 ++++++++++++++++ tests/Unit/Integer/IntegerNonPositiveTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/IntegerNonPositive.php b/src/Integer/IntegerNonPositive.php index 765dcf7b..f156ca91 100755 --- a/src/Integer/IntegerNonPositive.php +++ b/src/Integer/IntegerNonPositive.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws NonPositiveIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new NonPositiveIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws NonPositiveIntegerTypeException @@ -154,6 +162,14 @@ public function toInt(): int return $this->value; } + /** + * @throws NonPositiveIntegerTypeException + */ + public static function toNull(): never + { + throw new NonPositiveIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/IntegerNonPositiveTest.php b/tests/Unit/Integer/IntegerNonPositiveTest.php index 865829d2..f2a515d0 100755 --- a/tests/Unit/Integer/IntegerNonPositiveTest.php +++ b/tests/Unit/Integer/IntegerNonPositiveTest.php @@ -343,4 +343,16 @@ public function __toString(): string expect($v2->toString())->toBe($original); })->with(['0', '-42', (string) PHP_INT_MIN]); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerNonPositive::fromNull(null)) + ->toThrow(NonPositiveIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerNonPositive::toNull()) + ->toThrow(NonPositiveIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 1f8b3df2b8ae0266cd8fa931da3689187f4c8848 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:48:27 +0200 Subject: [PATCH 45/83] Add null handling to IntegerNonZero: fromNull and toNull throw NonZeroIntegerTypeException Implemented static `fromNull` and static `toNull` methods that always throw `NonZeroIntegerTypeException`. --- src/Integer/IntegerNonZero.php | 16 ++++++++++++++++ tests/Unit/Integer/IntegerNonZeroTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/IntegerNonZero.php b/src/Integer/IntegerNonZero.php index 4d38cdaa..cf4986e1 100755 --- a/src/Integer/IntegerNonZero.php +++ b/src/Integer/IntegerNonZero.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws NonZeroIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new NonZeroIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws NonZeroIntegerTypeException @@ -154,6 +162,14 @@ public function toInt(): int return $this->value; } + /** + * @throws NonZeroIntegerTypeException + */ + public static function toNull(): never + { + throw new NonZeroIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/IntegerNonZeroTest.php b/tests/Unit/Integer/IntegerNonZeroTest.php index d15e517d..90ba1a82 100755 --- a/tests/Unit/Integer/IntegerNonZeroTest.php +++ b/tests/Unit/Integer/IntegerNonZeroTest.php @@ -340,4 +340,16 @@ public function __toString(): string expect($v2->toString())->toBe($original); })->with(['42', '-42', (string) PHP_INT_MAX]); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerNonZero::fromNull(null)) + ->toThrow(NonZeroIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerNonZero::toNull()) + ->toThrow(NonZeroIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From b111c0d0784338ccfa234de471207b109815ac3e Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:48:33 +0200 Subject: [PATCH 46/83] Add null handling to IntegerNormal: fromNull and toNull throw NormalIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `NormalIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/MariaDb/IntegerNormal.php | 16 ++++++++++++++++ tests/Unit/Integer/MariaDb/IntegerNormalTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/MariaDb/IntegerNormal.php b/src/Integer/MariaDb/IntegerNormal.php index 05ee82cf..f166cb8d 100755 --- a/src/Integer/MariaDb/IntegerNormal.php +++ b/src/Integer/MariaDb/IntegerNormal.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws NormalIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new NormalIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws NormalIntegerTypeException @@ -167,6 +175,14 @@ public function toInt(): int return $this->value; } + /** + * @throws NormalIntegerTypeException + */ + public static function toNull(): never + { + throw new NormalIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerNormalTest.php b/tests/Unit/Integer/MariaDb/IntegerNormalTest.php index c0ba8e22..3c2fd6f5 100755 --- a/tests/Unit/Integer/MariaDb/IntegerNormalTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerNormalTest.php @@ -348,4 +348,16 @@ public static function fromString(string $value): static expect(IntegerNormalTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerNormal::fromNull(null)) + ->toThrow(NormalIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerNormal::toNull()) + ->toThrow(NormalIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 191f6eacd8fd9f3bf3fe45b8f00ffcb1f562a529 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:48:40 +0200 Subject: [PATCH 47/83] Add null handling to IntegerNormalUnsigned: fromNull and toNull throw UnsignedNormalIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `UnsignedNormalIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/MariaDb/IntegerNormalUnsigned.php | 16 ++++++++++++++++ .../MariaDb/IntegerNormalUnsignedTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/MariaDb/IntegerNormalUnsigned.php b/src/Integer/MariaDb/IntegerNormalUnsigned.php index 19e5d5e4..1e225e71 100755 --- a/src/Integer/MariaDb/IntegerNormalUnsigned.php +++ b/src/Integer/MariaDb/IntegerNormalUnsigned.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws UnsignedNormalIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new UnsignedNormalIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws UnsignedNormalIntegerTypeException @@ -167,6 +175,14 @@ public function toInt(): int return $this->value; } + /** + * @throws UnsignedNormalIntegerTypeException + */ + public static function toNull(): never + { + throw new UnsignedNormalIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerNormalUnsignedTest.php b/tests/Unit/Integer/MariaDb/IntegerNormalUnsignedTest.php index 087fe173..7cdaf95e 100755 --- a/tests/Unit/Integer/MariaDb/IntegerNormalUnsignedTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerNormalUnsignedTest.php @@ -364,4 +364,16 @@ public static function fromString(string $value): static expect(IntegerNormalUnsignedTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerNormalUnsigned::fromNull(null)) + ->toThrow(UnsignedNormalIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerNormalUnsigned::toNull()) + ->toThrow(UnsignedNormalIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 4b93580c35fdc22b58da09853443a30334ea11c5 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:48:44 +0200 Subject: [PATCH 48/83] Add null handling to IntegerPercent: fromNull and toNull throw PercentIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `PercentIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerPercent.php | 16 ++++++++++++++++ .../Unit/Integer/Specific/IntegerPercentTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerPercent.php b/src/Integer/Specific/IntegerPercent.php index 66d54735..a1750580 100755 --- a/src/Integer/Specific/IntegerPercent.php +++ b/src/Integer/Specific/IntegerPercent.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws PercentIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new PercentIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws PercentIntegerTypeException @@ -164,6 +172,14 @@ public function toInt(): int return $this->value; } + /** + * @throws PercentIntegerTypeException + */ + public static function toNull(): never + { + throw new PercentIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerPercentTest.php b/tests/Unit/Integer/Specific/IntegerPercentTest.php index 9ed379ca..ebead15d 100755 --- a/tests/Unit/Integer/Specific/IntegerPercentTest.php +++ b/tests/Unit/Integer/Specific/IntegerPercentTest.php @@ -373,4 +373,16 @@ public function __construct(int $value) 'above max' => [101], ]); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerPercent::fromNull(null)) + ->toThrow(PercentIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerPercent::toNull()) + ->toThrow(PercentIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From e1c130db68bf8bb499796313fdcf5bc8c1a0a162 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:01 +0200 Subject: [PATCH 49/83] Add null handling to IntegerPort: fromNull and toNull throw PortIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `PortIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerPort.php | 16 ++++++++++++++++ tests/Unit/Integer/Specific/IntegerPortTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerPort.php b/src/Integer/Specific/IntegerPort.php index bd0c3ff5..b505f889 100755 --- a/src/Integer/Specific/IntegerPort.php +++ b/src/Integer/Specific/IntegerPort.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws PortIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new PortIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws PortIntegerTypeException @@ -157,6 +165,14 @@ public function toInt(): int return $this->value; } + /** + * @throws PortIntegerTypeException + */ + public static function toNull(): never + { + throw new PortIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerPortTest.php b/tests/Unit/Integer/Specific/IntegerPortTest.php index c7e6db45..ef41879f 100755 --- a/tests/Unit/Integer/Specific/IntegerPortTest.php +++ b/tests/Unit/Integer/Specific/IntegerPortTest.php @@ -344,4 +344,16 @@ public function __toString(): string expect($v2->value())->toBe($original); })->with([0, 80, 65535]); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerPort::fromNull(null)) + ->toThrow(PortIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerPort::toNull()) + ->toThrow(PortIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 4b6db3e1af2df2e19dda78984dc017fefa956202 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:09 +0200 Subject: [PATCH 50/83] Add null handling to IntegerPositive: fromNull and toNull throw PositiveIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `PositiveIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/IntegerPositive.php | 16 ++++++++++++++++ tests/Unit/Integer/IntegerPositiveTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/IntegerPositive.php b/src/Integer/IntegerPositive.php index 729a0c7e..0ff536d5 100755 --- a/src/Integer/IntegerPositive.php +++ b/src/Integer/IntegerPositive.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws PositiveIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new PositiveIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws PositiveIntegerTypeException @@ -161,6 +169,14 @@ public function toInt(): int return $this->value; } + /** + * @throws PositiveIntegerTypeException + */ + public static function toNull(): never + { + throw new PositiveIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/IntegerPositiveTest.php b/tests/Unit/Integer/IntegerPositiveTest.php index 5d40e317..723a2e76 100755 --- a/tests/Unit/Integer/IntegerPositiveTest.php +++ b/tests/Unit/Integer/IntegerPositiveTest.php @@ -294,4 +294,16 @@ public function __toString(): string ->and($v->isTypeOf('NotClass'))->toBeFalse(); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerPositive::fromNull(null)) + ->toThrow(IntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerPositive::toNull()) + ->toThrow(IntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 4b35943a138ebc6944e19fe70cbccdbfe3421bf0 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:14 +0200 Subject: [PATCH 51/83] Add null handling to IntegerSecond: fromNull and toNull throw SecondIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `SecondIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerSecond.php | 16 ++++++++++++++++ .../Unit/Integer/Specific/IntegerSecondTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerSecond.php b/src/Integer/Specific/IntegerSecond.php index 0682ad67..89a73198 100755 --- a/src/Integer/Specific/IntegerSecond.php +++ b/src/Integer/Specific/IntegerSecond.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws SecondIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new SecondIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws SecondIntegerTypeException @@ -157,6 +165,14 @@ public function toInt(): int return $this->value; } + /** + * @throws SecondIntegerTypeException + */ + public static function toNull(): never + { + throw new SecondIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerSecondTest.php b/tests/Unit/Integer/Specific/IntegerSecondTest.php index 55de07f7..a990a2ec 100755 --- a/tests/Unit/Integer/Specific/IntegerSecondTest.php +++ b/tests/Unit/Integer/Specific/IntegerSecondTest.php @@ -428,4 +428,16 @@ public function __toString(): string expect($result)->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerSecond::fromNull(null)) + ->toThrow(SecondIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerSecond::toNull()) + ->toThrow(SecondIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 5bc38fe17dec173efe77ee29fa216bef485708cd Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:24 +0200 Subject: [PATCH 52/83] Add null handling to IntegerSmall: fromNull and toNull throw SmallIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `SmallIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/MariaDb/IntegerSmall.php | 16 ++++++++++++++++ tests/Unit/Integer/MariaDb/IntegerSmallTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/MariaDb/IntegerSmall.php b/src/Integer/MariaDb/IntegerSmall.php index 911b17bb..01e9db9c 100755 --- a/src/Integer/MariaDb/IntegerSmall.php +++ b/src/Integer/MariaDb/IntegerSmall.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws SmallIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new SmallIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws SmallIntegerTypeException @@ -167,6 +175,14 @@ public function toInt(): int return $this->value; } + /** + * @throws SmallIntegerTypeException + */ + public static function toNull(): never + { + throw new SmallIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerSmallTest.php b/tests/Unit/Integer/MariaDb/IntegerSmallTest.php index 4e686ec7..207f5388 100755 --- a/tests/Unit/Integer/MariaDb/IntegerSmallTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerSmallTest.php @@ -494,4 +494,16 @@ public static function fromString(string $value): static expect(IntegerSmallTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerSmall::fromNull(null)) + ->toThrow(SmallIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerSmall::toNull()) + ->toThrow(SmallIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 4e88097a2ec5f8ab370676b6d239d68188d30096 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:28 +0200 Subject: [PATCH 53/83] Add null handling to IntegerSmallUnsigned: fromNull and toNull throw UnsignedSmallIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `UnsignedSmallIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/MariaDb/IntegerSmallUnsigned.php | 16 ++++++++++++++++ .../Integer/MariaDb/IntegerSmallUnsignedTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/MariaDb/IntegerSmallUnsigned.php b/src/Integer/MariaDb/IntegerSmallUnsigned.php index d61f46fb..9bbc57fe 100755 --- a/src/Integer/MariaDb/IntegerSmallUnsigned.php +++ b/src/Integer/MariaDb/IntegerSmallUnsigned.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws UnsignedSmallIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new UnsignedSmallIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws UnsignedSmallIntegerTypeException @@ -167,6 +175,14 @@ public function toInt(): int return $this->value; } + /** + * @throws UnsignedSmallIntegerTypeException + */ + public static function toNull(): never + { + throw new UnsignedSmallIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerSmallUnsignedTest.php b/tests/Unit/Integer/MariaDb/IntegerSmallUnsignedTest.php index d0dddb9a..d27683a1 100755 --- a/tests/Unit/Integer/MariaDb/IntegerSmallUnsignedTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerSmallUnsignedTest.php @@ -377,4 +377,16 @@ public static function fromString(string $value): static expect(IntegerSmallUnsignedTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerSmallUnsigned::fromNull(null)) + ->toThrow(UnsignedSmallIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerSmallUnsigned::toNull()) + ->toThrow(UnsignedSmallIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 606be36538dcbffc2441d0654ad5fb64778008b3 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:34 +0200 Subject: [PATCH 54/83] Add null handling to IntegerStandard: fromNull and toNull throw IntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `IntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/IntegerStandard.php | 16 ++++++++++++++++ tests/Unit/Integer/IntegerStandardTest.php | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/Integer/IntegerStandard.php b/src/Integer/IntegerStandard.php index 807e11e3..cf14d2b0 100755 --- a/src/Integer/IntegerStandard.php +++ b/src/Integer/IntegerStandard.php @@ -79,6 +79,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws IntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new IntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @@ -138,6 +146,14 @@ public function toInt(): int return $this->value; } + /** + * @throws IntegerTypeException + */ + public static function toNull(): never + { + throw new IntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/IntegerStandardTest.php b/tests/Unit/Integer/IntegerStandardTest.php index 64a22b8d..f27988ec 100755 --- a/tests/Unit/Integer/IntegerStandardTest.php +++ b/tests/Unit/Integer/IntegerStandardTest.php @@ -266,6 +266,16 @@ public function __toString(): string expect((new IntegerStandard(0))->isUndefined())->toBeFalse(); }); + it('throws exception on fromNull', function () { + expect(fn() => IntegerStandard::fromNull(null)) + ->toThrow(IntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerStandard::toNull()) + ->toThrow(IntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + it('checks type correctly', function () { $v = new IntegerStandard(42); expect($v->isTypeOf(IntegerStandard::class))->toBeTrue() @@ -273,4 +283,16 @@ public function __toString(): string ->and($v->isTypeOf('NotClass'))->toBeFalse(); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerStandard::fromNull(null)) + ->toThrow(IntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerStandard::toNull()) + ->toThrow(IntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From e9bfe220b2248d1ab717ebf7a8d9d04ef8defb2e Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:39 +0200 Subject: [PATCH 55/83] Add null handling to IntegerTiny: fromNull and toNull throw TinyIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `TinyIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/MariaDb/IntegerTiny.php | 16 ++++++++++++++++ tests/Unit/Integer/MariaDb/IntegerTinyTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/MariaDb/IntegerTiny.php b/src/Integer/MariaDb/IntegerTiny.php index 66a61aa1..da1904d2 100755 --- a/src/Integer/MariaDb/IntegerTiny.php +++ b/src/Integer/MariaDb/IntegerTiny.php @@ -96,6 +96,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws TinyIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new TinyIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws TinyIntegerTypeException @@ -168,6 +176,14 @@ public function toInt(): int return $this->value; } + /** + * @throws TinyIntegerTypeException + */ + public static function toNull(): never + { + throw new TinyIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/MariaDb/IntegerTinyTest.php b/tests/Unit/Integer/MariaDb/IntegerTinyTest.php index 3d1e5876..bda963ff 100755 --- a/tests/Unit/Integer/MariaDb/IntegerTinyTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerTinyTest.php @@ -512,4 +512,16 @@ public static function fromString(string $value): static expect(IntegerTinyTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerTiny::fromNull(null)) + ->toThrow(TinyIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerTiny::toNull()) + ->toThrow(TinyIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 5dfec2c1b214d3e473fa61ad5599a9912ec3b1cd Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:45 +0200 Subject: [PATCH 56/83] Add null handling to IntegerTinyUnsigned: fromNull and toNull throw UnsignedTinyIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `UnsignedTinyIntegerTypeException`. --- src/Integer/MariaDb/IntegerTinyUnsigned.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Integer/MariaDb/IntegerTinyUnsigned.php b/src/Integer/MariaDb/IntegerTinyUnsigned.php index f35e3ab6..5a6f6c1b 100755 --- a/src/Integer/MariaDb/IntegerTinyUnsigned.php +++ b/src/Integer/MariaDb/IntegerTinyUnsigned.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws UnsignedTinyIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new UnsignedTinyIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws UnsignedTinyIntegerTypeException @@ -167,6 +175,14 @@ public function toInt(): int return $this->value; } + /** + * @throws UnsignedTinyIntegerTypeException + */ + public static function toNull(): never + { + throw new UnsignedTinyIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ From 3d9eae668660ac0bad0c4118301123ce154d4a60 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:50 +0200 Subject: [PATCH 57/83] Add abstract null handling methods and tests for IntegerTinyUnsigned Declare `fromNull` and `toNull` as abstract methods returning `never` in the base integer type, and add unit tests verifying that both methods throw `UnsignedTinyIntegerTypeException` when invoked. --- src/Base/Primitive/Integer/IntegerTypeAbstract.php | 4 ++++ .../Unit/Integer/MariaDb/IntegerTinyUnsignedTest.php | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Base/Primitive/Integer/IntegerTypeAbstract.php b/src/Base/Primitive/Integer/IntegerTypeAbstract.php index 0bc2c22e..5526e357 100755 --- a/src/Base/Primitive/Integer/IntegerTypeAbstract.php +++ b/src/Base/Primitive/Integer/IntegerTypeAbstract.php @@ -34,6 +34,8 @@ abstract public static function fromFloat(float $value): static; abstract public static function fromInt(int $value): static; + abstract public static function fromNull(null $value): never; + abstract public static function fromString(string $value): static; abstract public function isTypeOf(string ...$classNames): bool; @@ -46,6 +48,8 @@ abstract public function toFloat(): float; abstract public function toInt(): int; + abstract public static function toNull(): never; + abstract public function toString(): string; /** diff --git a/tests/Unit/Integer/MariaDb/IntegerTinyUnsignedTest.php b/tests/Unit/Integer/MariaDb/IntegerTinyUnsignedTest.php index 4c816282..43416e08 100755 --- a/tests/Unit/Integer/MariaDb/IntegerTinyUnsignedTest.php +++ b/tests/Unit/Integer/MariaDb/IntegerTinyUnsignedTest.php @@ -373,4 +373,16 @@ public static function fromString(string $value): static expect(IntegerTinyUnsignedTest::tryFromString('1'))->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerTinyUnsigned::fromNull(null)) + ->toThrow(UnsignedTinyIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerTinyUnsigned::toNull()) + ->toThrow(UnsignedTinyIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 86cf4a37ac5edf157e10840a0f6bf39dcda413b1 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:49:58 +0200 Subject: [PATCH 58/83] Add null handling to IntegerWeekDay: fromNull and toNull throw WeekDayIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `WeekDayIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerWeekDay.php | 16 ++++++++++++++++ .../Unit/Integer/Specific/IntegerWeekDayTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerWeekDay.php b/src/Integer/Specific/IntegerWeekDay.php index 90953b08..5390fcf1 100755 --- a/src/Integer/Specific/IntegerWeekDay.php +++ b/src/Integer/Specific/IntegerWeekDay.php @@ -120,6 +120,14 @@ public static function fromLabel(string $label): static return new static($value); } + /** + * @throws WeekDayIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new WeekDayIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws WeekDayIntegerTypeException @@ -199,6 +207,14 @@ public function toLabel(): string }; } + /** + * @throws WeekDayIntegerTypeException + */ + public static function toNull(): never + { + throw new WeekDayIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerWeekDayTest.php b/tests/Unit/Integer/Specific/IntegerWeekDayTest.php index e3991594..697a1bef 100755 --- a/tests/Unit/Integer/Specific/IntegerWeekDayTest.php +++ b/tests/Unit/Integer/Specific/IntegerWeekDayTest.php @@ -486,4 +486,16 @@ public function __toString(): string expect($result)->toBeInstanceOf(Undefined::class); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerWeekDay::fromNull(null)) + ->toThrow(WeekDayIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerWeekDay::toNull()) + ->toThrow(WeekDayIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From fd18b475450f809bca3aa9b8d3120f75484260b8 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:50:06 +0200 Subject: [PATCH 59/83] Add null handling to IntegerYear: fromNull and toNull throw YearIntegerTypeException Implemented static `fromNull` and `toNull` methods that always throw `YearIntegerTypeException` and added unit tests to verify the exception behavior. --- src/Integer/Specific/IntegerYear.php | 16 ++++++++++++++++ tests/Unit/Integer/Specific/IntegerYearTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Integer/Specific/IntegerYear.php b/src/Integer/Specific/IntegerYear.php index dc4f588c..eaa2e4d9 100755 --- a/src/Integer/Specific/IntegerYear.php +++ b/src/Integer/Specific/IntegerYear.php @@ -94,6 +94,14 @@ public static function fromInt(int $value): static return new static($value); } + /** + * @throws YearIntegerTypeException + */ + public static function fromNull(null $value): never + { + throw new YearIntegerTypeException('Integer type cannot be created from null'); + } + /** * @throws StringTypeException * @throws YearIntegerTypeException @@ -157,6 +165,14 @@ public function toInt(): int return $this->value; } + /** + * @throws YearIntegerTypeException + */ + public static function toNull(): never + { + throw new YearIntegerTypeException('Integer type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/Integer/Specific/IntegerYearTest.php b/tests/Unit/Integer/Specific/IntegerYearTest.php index aa2875eb..e4733d96 100755 --- a/tests/Unit/Integer/Specific/IntegerYearTest.php +++ b/tests/Unit/Integer/Specific/IntegerYearTest.php @@ -303,4 +303,16 @@ public function __toString(): string expect($year->value())->toBe(2024); }); }); + + describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => IntegerYear::fromNull(null)) + ->toThrow(YearIntegerTypeException::class, 'Integer type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => IntegerYear::toNull()) + ->toThrow(YearIntegerTypeException::class, 'Integer type cannot be converted to null'); + }); + }); }); From 3e57b3fbea6ce07f2b18666ff9c804b2641cacaf Mon Sep 17 00:00:00 2001 From: GeorgII Date: Fri, 10 Apr 2026 23:50:13 +0200 Subject: [PATCH 60/83] Add abstract null handling methods to IntegerTypeInterface Declare `fromNull(null)` and `toNull()` as abstract methods returning `never` to enforce consistent null handling across integer types. --- src/Base/Primitive/Integer/IntegerTypeInterface.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Base/Primitive/Integer/IntegerTypeInterface.php b/src/Base/Primitive/Integer/IntegerTypeInterface.php index a21a52f4..44c01319 100755 --- a/src/Base/Primitive/Integer/IntegerTypeInterface.php +++ b/src/Base/Primitive/Integer/IntegerTypeInterface.php @@ -29,6 +29,8 @@ public static function fromFloat(float $value): static; public static function fromInt(int $value): static; + public static function fromNull(null $value): never; + public static function fromString(string $value): static; public function isTypeOf(string ...$classNames): bool; @@ -41,6 +43,8 @@ public function toFloat(): float; public function toInt(): int; + public static function toNull(): never; + public function toString(): string; /** From e7088d5b4fec752ccb95d07dd7c28b8b41bc960f Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:29:59 +0200 Subject: [PATCH 61/83] Add null handling to StringBase64: fromNull and toNull throw Base64StringTypeException Implemented static `fromNull` and `toNull` methods that always throw `Base64StringTypeException`; updated docblocks to reference the correct exception and added unit tests to verify the exception behavior. --- src/String/Specific/StringBase64.php | 25 +++++++++++++++---- .../Unit/String/Specific/StringBase64Test.php | 12 +++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/String/Specific/StringBase64.php b/src/String/Specific/StringBase64.php index 6523f5dd..a962b533 100755 --- a/src/String/Specific/StringBase64.php +++ b/src/String/Specific/StringBase64.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\Base64StringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -88,7 +87,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws Base64StringTypeException - * @throws StringTypeException + * @throws Base64StringTypeException * * @psalm-pure */ @@ -107,6 +106,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws Base64StringTypeException + */ + public static function fromNull(null $value): never + { + throw new Base64StringTypeException('StringBase64 type cannot be created from null'); + } + /** * Creates a Base64 instance from an existing Base64-encoded string. * @@ -146,7 +153,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws Base64StringTypeException */ public function toBool(): bool { @@ -163,7 +170,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws Base64StringTypeException */ public function toFloat(): float { @@ -171,13 +178,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws Base64StringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws Base64StringTypeException + */ + public static function toNull(): never + { + throw new Base64StringTypeException('StringBase64 type cannot be converted to null'); + } + /** * Returns the Base64-encoded string. * diff --git a/tests/Unit/String/Specific/StringBase64Test.php b/tests/Unit/String/Specific/StringBase64Test.php index 196cd8e5..f8ade2ad 100755 --- a/tests/Unit/String/Specific/StringBase64Test.php +++ b/tests/Unit/String/Specific/StringBase64Test.php @@ -344,3 +344,15 @@ public static function fromString(string $value): static ->and(StringBase64Test::tryFromString('SGVsbG8gV29ybGQ='))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringBase64::fromNull(null)) + ->toThrow(Base64StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringBase64::toNull()) + ->toThrow(Base64StringTypeException::class); + }); +}); From c0dd0c13faaedf5eeb65600894d11e3a581f20e4 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:30:05 +0200 Subject: [PATCH 62/83] Add null handling to StringCountryCode: fromNull and toNull throw CountryCodeStringTypeException Update docblocks to reference the correct exception, remove the unused `StringTypeException` import, and add unit tests that verify both methods throw `CountryCodeStringTypeException`. --- src/String/Specific/StringCountryCode.php | 27 ++++++++++++++----- .../String/Specific/StringCountryCodeTest.php | 12 +++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/String/Specific/StringCountryCode.php b/src/String/Specific/StringCountryCode.php index 98eba51f..16228a7b 100755 --- a/src/String/Specific/StringCountryCode.php +++ b/src/String/Specific/StringCountryCode.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\CountryCodeStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -60,7 +59,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws CountryCodeStringTypeException * @throws CountryCodeStringTypeException * * @psalm-pure @@ -83,7 +82,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws CountryCodeStringTypeException - * @throws StringTypeException + * @throws CountryCodeStringTypeException * * @psalm-pure */ @@ -102,6 +101,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws CountryCodeStringTypeException + */ + public static function fromNull(null $value): never + { + throw new CountryCodeStringTypeException('StringCountryCode type cannot be created from null'); + } + /** * @throws CountryCodeStringTypeException * @@ -139,7 +146,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws CountryCodeStringTypeException */ public function toBool(): bool { @@ -156,7 +163,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws CountryCodeStringTypeException */ public function toFloat(): float { @@ -164,13 +171,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws CountryCodeStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws CountryCodeStringTypeException + */ + public static function toNull(): never + { + throw new CountryCodeStringTypeException('StringCountryCode type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/String/Specific/StringCountryCodeTest.php b/tests/Unit/String/Specific/StringCountryCodeTest.php index f794b45f..31e4daf1 100755 --- a/tests/Unit/String/Specific/StringCountryCodeTest.php +++ b/tests/Unit/String/Specific/StringCountryCodeTest.php @@ -232,3 +232,15 @@ public static function fromString(string $value): static ->and(StringCountryCodeTest::tryFromString('US'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringCountryCode::fromNull(null)) + ->toThrow(CountryCodeStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringCountryCode::toNull()) + ->toThrow(CountryCodeStringTypeException::class); + }); +}); From c07f69a70db2e201457139f420a7fd880f996da3 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:30:10 +0200 Subject: [PATCH 63/83] Add null handling to StringCurrencyCode: fromNull and toNull throw CurrencyCodeStringTypeException Remove unused `StringTypeException` import, update docblocks to reference the correct exception, and add unit tests verifying the new null handling methods. --- src/String/Specific/StringCurrencyCode.php | 25 +++++++++++++++---- .../Specific/StringCurrencyCodeTest.php | 12 +++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/String/Specific/StringCurrencyCode.php b/src/String/Specific/StringCurrencyCode.php index cac76c8c..3f7e5a40 100755 --- a/src/String/Specific/StringCurrencyCode.php +++ b/src/String/Specific/StringCurrencyCode.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\CurrencyCodeStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -82,7 +81,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws CurrencyCodeStringTypeException - * @throws StringTypeException + * @throws CurrencyCodeStringTypeException * * @psalm-pure */ @@ -101,6 +100,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws CurrencyCodeStringTypeException + */ + public static function fromNull(null $value): never + { + throw new CurrencyCodeStringTypeException('StringCurrencyCode type cannot be created from null'); + } + /** * @throws CurrencyCodeStringTypeException * @@ -138,7 +145,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws CurrencyCodeStringTypeException */ public function toBool(): bool { @@ -154,7 +161,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws CurrencyCodeStringTypeException * @throws FloatTypeException */ public function toFloat(): float @@ -163,13 +170,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws CurrencyCodeStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws CurrencyCodeStringTypeException + */ + public static function toNull(): never + { + throw new CurrencyCodeStringTypeException('StringCurrencyCode type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/tests/Unit/String/Specific/StringCurrencyCodeTest.php b/tests/Unit/String/Specific/StringCurrencyCodeTest.php index f1b96188..52da20a3 100755 --- a/tests/Unit/String/Specific/StringCurrencyCodeTest.php +++ b/tests/Unit/String/Specific/StringCurrencyCodeTest.php @@ -292,3 +292,15 @@ public static function fromString(string $value): static ->and(StringCurrencyCodeTest::tryFromString('trigger-exception', $default))->toBe($default); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringCurrencyCode::fromNull(null)) + ->toThrow(CurrencyCodeStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringCurrencyCode::toNull()) + ->toThrow(CurrencyCodeStringTypeException::class); + }); +}); From b9812db864bb1ad121faefcce42dd8abb3afa857 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:30:16 +0200 Subject: [PATCH 64/83] Add null handling to StringDomain: fromNull and toNull throw DomainStringTypeException Update docblocks to reference the correct exception and add unit tests verifying the new null handling behavior. --- src/String/Specific/StringDomain.php | 26 +++++++++++++++---- .../Unit/String/Specific/StringDomainTest.php | 12 +++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/String/Specific/StringDomain.php b/src/String/Specific/StringDomain.php index e251e1ce..acf72e30 100755 --- a/src/String/Specific/StringDomain.php +++ b/src/String/Specific/StringDomain.php @@ -47,7 +47,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws DomainStringTypeException * @throws DomainStringTypeException * * @psalm-pure @@ -70,7 +70,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws DomainStringTypeException - * @throws StringTypeException + * @throws DomainStringTypeException * * @psalm-pure */ @@ -89,6 +89,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws DomainStringTypeException + */ + public static function fromNull(null $value): never + { + throw new DomainStringTypeException('StringDomain type cannot be created from null'); + } + /** * @throws DomainStringTypeException * @@ -129,7 +137,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws DomainStringTypeException */ public function toBool(): bool { @@ -145,7 +153,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws DomainStringTypeException * @throws FloatTypeException */ public function toFloat(): float @@ -154,13 +162,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws DomainStringTypeException */ public function toInt(): int { return static::stringToInt($this->value); } + /** + * @throws DomainStringTypeException + */ + public static function toNull(): never + { + throw new DomainStringTypeException('StringDomain type cannot be converted to null'); + } + public function toString(): string { return $this->value; diff --git a/tests/Unit/String/Specific/StringDomainTest.php b/tests/Unit/String/Specific/StringDomainTest.php index ffbed28d..901ea613 100755 --- a/tests/Unit/String/Specific/StringDomainTest.php +++ b/tests/Unit/String/Specific/StringDomainTest.php @@ -198,3 +198,15 @@ public static function fromString(string $value): static ->and(StringDomainTest::tryFromString($validDomain))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringDomain::fromNull(null)) + ->toThrow(DomainStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringDomain::toNull()) + ->toThrow(DomainStringTypeException::class); + }); +}); From 48fb442707df970e389cf3015e347066d83fae0f Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:30:33 +0200 Subject: [PATCH 65/83] Add null handling to StringEmail: fromNull and toNull throw EmailStringTypeException Update docblocks to reference EmailStringTypeException, remove the unused `StringTypeException` import, and add unit tests verifying the new null handling behavior. --- src/String/Specific/StringEmail.php | 27 ++++++++++++++----- .../Unit/String/Specific/StringEmailTest.php | 12 +++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/String/Specific/StringEmail.php b/src/String/Specific/StringEmail.php index 11121983..8f453145 100755 --- a/src/String/Specific/StringEmail.php +++ b/src/String/Specific/StringEmail.php @@ -12,7 +12,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\EmailStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -59,7 +58,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws EmailStringTypeException * @throws EmailStringTypeException * * @psalm-pure @@ -82,7 +81,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws EmailStringTypeException - * @throws StringTypeException + * @throws EmailStringTypeException * * @psalm-pure */ @@ -101,6 +100,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws EmailStringTypeException + */ + public static function fromNull(null $value): never + { + throw new EmailStringTypeException('StringEmail type cannot be created from null'); + } + /** * @throws EmailStringTypeException * @@ -138,7 +145,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws EmailStringTypeException */ public function toBool(): bool { @@ -155,7 +162,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws EmailStringTypeException */ public function toFloat(): float { @@ -163,13 +170,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws EmailStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws EmailStringTypeException + */ + public static function toNull(): never + { + throw new EmailStringTypeException('StringEmail type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/String/Specific/StringEmailTest.php b/tests/Unit/String/Specific/StringEmailTest.php index 231e535b..a6f871f6 100755 --- a/tests/Unit/String/Specific/StringEmailTest.php +++ b/tests/Unit/String/Specific/StringEmailTest.php @@ -182,3 +182,15 @@ public static function fromString(string $value): static ->and(StringEmailTest::tryFromString('test@example.com'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringEmail::fromNull(null)) + ->toThrow(EmailStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringEmail::toNull()) + ->toThrow(EmailStringTypeException::class); + }); +}); From 80d96dcda2cd5ab265bdb59f40805958f4510672 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:30:45 +0200 Subject: [PATCH 66/83] Add null handling to StringEmpty: fromNull and toNull throw StringTypeException Add unit tests verifying that both methods throw the exception. --- src/String/StringEmpty.php | 16 ++++++++++++++++ tests/Unit/String/StringEmptyTest.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/String/StringEmpty.php b/src/String/StringEmpty.php index 05e8cdbe..3e5ca821 100755 --- a/src/String/StringEmpty.php +++ b/src/String/StringEmpty.php @@ -86,6 +86,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringEmpty type cannot be created from null'); + } + /** * @throws StringTypeException * @@ -155,6 +163,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringEmpty type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/tests/Unit/String/StringEmptyTest.php b/tests/Unit/String/StringEmptyTest.php index 84a9e8cd..17a27787 100755 --- a/tests/Unit/String/StringEmptyTest.php +++ b/tests/Unit/String/StringEmptyTest.php @@ -179,3 +179,15 @@ public static function fromString(string $value): static ->and(StringEmptyTest::tryFromString(''))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringEmpty::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringEmpty::toNull()) + ->toThrow(StringTypeException::class); + }); +}); From 810e667e9467f5e87f6db6af0f7cf2f13f8454f9 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:30:50 +0200 Subject: [PATCH 67/83] Add null handling to StringFileName: fromNull and toNull throw FileNameStringTypeException Update docblocks to reference `FileNameStringTypeException`, remove the unused `StringTypeException` import, and add unit tests verifying that both methods throw the exception. --- src/String/Specific/StringFileName.php | 27 ++++++++++++++----- .../String/Specific/StringFileNameTest.php | 12 +++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/String/Specific/StringFileName.php b/src/String/Specific/StringFileName.php index 3de78891..e43a0de4 100755 --- a/src/String/Specific/StringFileName.php +++ b/src/String/Specific/StringFileName.php @@ -13,7 +13,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\FileNameStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -63,7 +62,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws FileNameStringTypeException * @throws FileNameStringTypeException * * @psalm-pure @@ -86,7 +85,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws FileNameStringTypeException - * @throws StringTypeException + * @throws FileNameStringTypeException * * @psalm-pure */ @@ -105,6 +104,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws FileNameStringTypeException + */ + public static function fromNull(null $value): never + { + throw new FileNameStringTypeException('StringFileName type cannot be created from null'); + } + /** * @throws FileNameStringTypeException * @@ -158,7 +165,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws FileNameStringTypeException */ public function toBool(): bool { @@ -175,7 +182,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws FileNameStringTypeException */ public function toFloat(): float { @@ -183,13 +190,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws FileNameStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws FileNameStringTypeException + */ + public static function toNull(): never + { + throw new FileNameStringTypeException('StringFileName type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/tests/Unit/String/Specific/StringFileNameTest.php b/tests/Unit/String/Specific/StringFileNameTest.php index c10cd99b..2b34f63b 100755 --- a/tests/Unit/String/Specific/StringFileNameTest.php +++ b/tests/Unit/String/Specific/StringFileNameTest.php @@ -187,3 +187,15 @@ public static function fromString(string $value): static ->and(StringFileNameTest::tryFromString('image.jpg'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringFileName::fromNull(null)) + ->toThrow(FileNameStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringFileName::toNull()) + ->toThrow(FileNameStringTypeException::class); + }); +}); From 9ab68b20c61d236cab8f78f9f6194eff811311db Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:30:55 +0200 Subject: [PATCH 68/83] Add null handling to StringHex: fromNull and toNull throw HexStringTypeException Removed unused `StringTypeException` import, updated docblocks to reference `HexStringTypeException`, and added unit tests verifying the new null handling methods. --- src/String/Specific/StringHex.php | 25 ++++++++++++++++---- tests/Unit/String/Specific/StringHexTest.php | 12 ++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/String/Specific/StringHex.php b/src/String/Specific/StringHex.php index 59879487..69f10948 100755 --- a/src/String/Specific/StringHex.php +++ b/src/String/Specific/StringHex.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\HexStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -77,7 +76,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws HexStringTypeException - * @throws StringTypeException + * @throws HexStringTypeException * * @psalm-pure */ @@ -96,6 +95,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws HexStringTypeException + */ + public static function fromNull(null $value): never + { + throw new HexStringTypeException('StringHex type cannot be created from null'); + } + /** * Creates a Hex instance from an existing hexadecimal string. * @@ -135,7 +142,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws HexStringTypeException */ public function toBool(): bool { @@ -152,7 +159,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws HexStringTypeException */ public function toFloat(): float { @@ -160,13 +167,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws HexStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws HexStringTypeException + */ + public static function toNull(): never + { + throw new HexStringTypeException('StringHex type cannot be converted to null'); + } + /** * Returns the hexadecimal string. * diff --git a/tests/Unit/String/Specific/StringHexTest.php b/tests/Unit/String/Specific/StringHexTest.php index 8ee3e3a6..621560e6 100755 --- a/tests/Unit/String/Specific/StringHexTest.php +++ b/tests/Unit/String/Specific/StringHexTest.php @@ -230,3 +230,15 @@ public static function fromString(string $value): static ->and(StringHexTest::tryFromString('4a6f686e'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringHex::fromNull(null)) + ->toThrow(HexStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringHex::toNull()) + ->toThrow(HexStringTypeException::class); + }); +}); From bd249abaa48d84726103ae3783cf51630d21079a Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 00:31:27 +0200 Subject: [PATCH 69/83] Add null handling to String: fromNull and toNull throw StringTypeException --- src/String/Alias/StringType.php | 16 +++++++++++ src/String/MariaDb/StringLongText.php | 16 +++++++++++ src/String/MariaDb/StringMediumText.php | 16 +++++++++++ src/String/MariaDb/StringText.php | 16 +++++++++++ src/String/MariaDb/StringTinyText.php | 25 +++++++++++++---- src/String/MariaDb/StringVarChar255.php | 16 +++++++++++ src/String/Specific/StringIban.php | 25 +++++++++++++---- src/String/Specific/StringIpV4.php | 25 +++++++++++++---- src/String/Specific/StringIpV6.php | 25 +++++++++++++---- src/String/Specific/StringJson.php | 25 +++++++++++++---- src/String/Specific/StringJwt.php | 24 ++++++++++++++--- src/String/Specific/StringLanguageCode.php | 25 +++++++++++++---- src/String/Specific/StringLocaleCode.php | 27 ++++++++++++++----- src/String/Specific/StringMacAddress.php | 19 +++++++++++-- src/String/Specific/StringMd5.php | 25 +++++++++++++---- src/String/Specific/StringMimeType.php | 26 ++++++++++++++---- src/String/Specific/StringPath.php | 25 +++++++++++++---- src/String/Specific/StringPhoneE164.php | 26 ++++++++++++++---- src/String/Specific/StringSemVer.php | 25 +++++++++++++---- src/String/Specific/StringSha256.php | 26 ++++++++++++++---- src/String/Specific/StringSha512.php | 26 ++++++++++++++---- src/String/Specific/StringSlug.php | 25 +++++++++++++---- src/String/Specific/StringUrl.php | 25 +++++++++++++---- src/String/Specific/StringUrlPath.php | 25 +++++++++++++---- src/String/Specific/StringUsername.php | 23 +++++++++++++--- src/String/Specific/StringUuidV4.php | 25 +++++++++++++---- src/String/Specific/StringUuidV7.php | 25 +++++++++++++---- src/String/StringNonBlank.php | 16 +++++++++++ src/String/StringNonEmpty.php | 16 +++++++++++ src/String/StringStandard.php | 16 +++++++++++ tests/Unit/String/Alias/StringTypeTest.php | 27 +++++++++++++++++++ .../String/MariaDb/StringLongTextTest.php | 12 +++++++++ .../String/MariaDb/StringMediumTextTest.php | 12 +++++++++ tests/Unit/String/MariaDb/StringTextTest.php | 12 +++++++++ .../String/MariaDb/StringTinyTextTest.php | 12 +++++++++ .../String/MariaDb/StringVarChar255Test.php | 12 +++++++++ tests/Unit/String/Specific/StringIbanTest.php | 12 +++++++++ tests/Unit/String/Specific/StringIpV4Test.php | 12 +++++++++ tests/Unit/String/Specific/StringIpV6Test.php | 12 +++++++++ tests/Unit/String/Specific/StringJsonTest.php | 12 +++++++++ tests/Unit/String/Specific/StringJwtTest.php | 12 +++++++++ .../Specific/StringLanguageCodeTest.php | 12 +++++++++ .../String/Specific/StringLocaleCodeTest.php | 12 +++++++++ .../String/Specific/StringMacAddressTest.php | 12 +++++++++ tests/Unit/String/Specific/StringMd5Test.php | 12 +++++++++ .../String/Specific/StringMimeTypeTest.php | 12 +++++++++ tests/Unit/String/Specific/StringPathTest.php | 12 +++++++++ .../String/Specific/StringPhoneE164Test.php | 12 +++++++++ .../Unit/String/Specific/StringSemVerTest.php | 12 +++++++++ .../Unit/String/Specific/StringSha256Test.php | 12 +++++++++ .../Unit/String/Specific/StringSha512Test.php | 12 +++++++++ tests/Unit/String/Specific/StringSlugTest.php | 12 +++++++++ .../String/Specific/StringUrlPathTest.php | 12 +++++++++ tests/Unit/String/Specific/StringUrlTest.php | 12 +++++++++ .../String/Specific/StringUsernameTest.php | 12 +++++++++ .../Unit/String/Specific/StringUuidV4Test.php | 12 +++++++++ .../Unit/String/Specific/StringUuidV7Test.php | 12 +++++++++ tests/Unit/String/StringNonBlankTest.php | 12 +++++++++ tests/Unit/String/StringNonEmptyTest.php | 12 +++++++++ tests/Unit/String/StringStandardTest.php | 12 +++++++++ 60 files changed, 944 insertions(+), 106 deletions(-) create mode 100755 tests/Unit/String/Alias/StringTypeTest.php diff --git a/src/String/Alias/StringType.php b/src/String/Alias/StringType.php index fe1144c2..329f182f 100755 --- a/src/String/Alias/StringType.php +++ b/src/String/Alias/StringType.php @@ -4,6 +4,7 @@ namespace PhpTypedValues\String\Alias; +use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\String\StringStandard; /** @@ -20,4 +21,19 @@ */ final readonly class StringType extends StringStandard { + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringType type cannot be created from null'); + } + + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringType type cannot be converted to null'); + } } diff --git a/src/String/MariaDb/StringLongText.php b/src/String/MariaDb/StringLongText.php index 8a6e02ad..eb4a32b1 100755 --- a/src/String/MariaDb/StringLongText.php +++ b/src/String/MariaDb/StringLongText.php @@ -91,6 +91,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringLongText type cannot be created from null'); + } + /** * @throws StringTypeException * @@ -160,6 +168,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringLongText type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/MariaDb/StringMediumText.php b/src/String/MariaDb/StringMediumText.php index 70b9f697..fe9f57e2 100755 --- a/src/String/MariaDb/StringMediumText.php +++ b/src/String/MariaDb/StringMediumText.php @@ -91,6 +91,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringMediumText type cannot be created from null'); + } + /** * @throws StringTypeException * @@ -160,6 +168,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringMediumText type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/MariaDb/StringText.php b/src/String/MariaDb/StringText.php index af2e8881..e0695e86 100755 --- a/src/String/MariaDb/StringText.php +++ b/src/String/MariaDb/StringText.php @@ -91,6 +91,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringText type cannot be created from null'); + } + /** * @throws StringTypeException * @@ -160,6 +168,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringText type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/MariaDb/StringTinyText.php b/src/String/MariaDb/StringTinyText.php index bbff65a6..3f07a1f0 100755 --- a/src/String/MariaDb/StringTinyText.php +++ b/src/String/MariaDb/StringTinyText.php @@ -9,7 +9,6 @@ use PhpTypedValues\Base\Primitive\String\StringTypeAbstract; use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\String\TinyTextStringException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; @@ -74,7 +73,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws TinyTextStringException - * @throws StringTypeException + * @throws TinyTextStringException * * @psalm-pure */ @@ -93,6 +92,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws TinyTextStringException + */ + public static function fromNull(null $value): never + { + throw new TinyTextStringException('StringTinyText type cannot be created from null'); + } + /** * @throws TinyTextStringException * @@ -130,7 +137,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws TinyTextStringException */ public function toBool(): bool { @@ -147,7 +154,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws TinyTextStringException */ public function toFloat(): float { @@ -155,13 +162,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws TinyTextStringException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws TinyTextStringException + */ + public static function toNull(): never + { + throw new TinyTextStringException('StringTinyText type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/MariaDb/StringVarChar255.php b/src/String/MariaDb/StringVarChar255.php index b710c37e..171431bf 100755 --- a/src/String/MariaDb/StringVarChar255.php +++ b/src/String/MariaDb/StringVarChar255.php @@ -91,6 +91,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringVarChar255 type cannot be created from null'); + } + /** * @throws StringTypeException * @@ -160,6 +168,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringVarChar255 type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/Specific/StringIban.php b/src/String/Specific/StringIban.php index 8b24e46c..5b67b874 100755 --- a/src/String/Specific/StringIban.php +++ b/src/String/Specific/StringIban.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\IbanStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -82,7 +81,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws IbanStringTypeException - * @throws StringTypeException + * @throws IbanStringTypeException * * @psalm-pure */ @@ -101,6 +100,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws IbanStringTypeException + */ + public static function fromNull(null $value): never + { + throw new IbanStringTypeException('StringIban type cannot be created from null'); + } + /** * Creates an IBAN instance from an existing IBAN string. * @@ -140,7 +147,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws IbanStringTypeException */ public function toBool(): bool { @@ -157,7 +164,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws IbanStringTypeException */ public function toFloat(): float { @@ -165,13 +172,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws IbanStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws IbanStringTypeException + */ + public static function toNull(): never + { + throw new IbanStringTypeException('StringIban type cannot be converted to null'); + } + /** * Returns the IBAN string. * diff --git a/src/String/Specific/StringIpV4.php b/src/String/Specific/StringIpV4.php index 7cb3b667..e01accee 100755 --- a/src/String/Specific/StringIpV4.php +++ b/src/String/Specific/StringIpV4.php @@ -13,7 +13,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\IpV4StringException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -76,7 +75,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws IpV4StringException - * @throws StringTypeException + * @throws IpV4StringException * * @psalm-pure */ @@ -95,6 +94,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws IpV4StringException + */ + public static function fromNull(null $value): never + { + throw new IpV4StringException('StringIpV4 type cannot be created from null'); + } + /** * @throws IpV4StringException * @@ -132,7 +139,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws IpV4StringException */ public function toBool(): bool { @@ -148,7 +155,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws IpV4StringException * @throws FloatTypeException */ public function toFloat(): float @@ -157,13 +164,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws IpV4StringException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws IpV4StringException + */ + public static function toNull(): never + { + throw new IpV4StringException('StringIpV4 type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/Specific/StringIpV6.php b/src/String/Specific/StringIpV6.php index b2463b26..e97af96f 100755 --- a/src/String/Specific/StringIpV6.php +++ b/src/String/Specific/StringIpV6.php @@ -13,7 +13,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\IpV6StringException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -76,7 +75,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws IpV6StringException - * @throws StringTypeException + * @throws IpV6StringException * * @psalm-pure */ @@ -95,6 +94,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws IpV6StringException + */ + public static function fromNull(null $value): never + { + throw new IpV6StringException('StringIpV6 type cannot be created from null'); + } + /** * @throws IpV6StringException * @@ -132,7 +139,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws IpV6StringException */ public function toBool(): bool { @@ -148,7 +155,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws IpV6StringException * @throws FloatTypeException */ public function toFloat(): float @@ -157,13 +164,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws IpV6StringException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws IpV6StringException + */ + public static function toNull(): never + { + throw new IpV6StringException('StringIpV6 type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/Specific/StringJson.php b/src/String/Specific/StringJson.php index 733feb8a..f1ee4e94 100755 --- a/src/String/Specific/StringJson.php +++ b/src/String/Specific/StringJson.php @@ -13,7 +13,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\JsonStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -100,7 +99,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws JsonStringTypeException - * @throws StringTypeException + * @throws JsonStringTypeException * * @psalm-pure */ @@ -119,6 +118,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws JsonStringTypeException + */ + public static function fromNull(null $value): never + { + throw new JsonStringTypeException('StringJson type cannot be created from null'); + } + /** * @throws JsonStringTypeException * @@ -167,7 +174,7 @@ public function toArray(): array } /** - * @throws StringTypeException + * @throws JsonStringTypeException */ public function toBool(): bool { @@ -184,7 +191,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws JsonStringTypeException */ public function toFloat(): float { @@ -192,13 +199,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws JsonStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws JsonStringTypeException + */ + public static function toNull(): never + { + throw new JsonStringTypeException('StringJson type cannot be converted to null'); + } + /** * @throws JsonException */ diff --git a/src/String/Specific/StringJwt.php b/src/String/Specific/StringJwt.php index 1c62c01d..648b4e7c 100755 --- a/src/String/Specific/StringJwt.php +++ b/src/String/Specific/StringJwt.php @@ -48,7 +48,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws JwtStringTypeException * @throws JwtStringTypeException * * @psalm-pure @@ -88,6 +88,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws JwtStringTypeException + */ + public static function fromNull(null $value): never + { + throw new JwtStringTypeException('StringJwt type cannot be created from null'); + } + /** * @throws JwtStringTypeException * @@ -128,7 +136,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws JwtStringTypeException */ public function toBool(): bool { @@ -144,7 +152,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws JwtStringTypeException */ public function toFloat(): float { @@ -152,13 +160,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws JwtStringTypeException */ public function toInt(): int { return static::stringToInt($this->value); } + /** + * @throws JwtStringTypeException + */ + public static function toNull(): never + { + throw new JwtStringTypeException('StringJwt type cannot be converted to null'); + } + public function toString(): string { return $this->value; diff --git a/src/String/Specific/StringLanguageCode.php b/src/String/Specific/StringLanguageCode.php index 46c49df3..d1eda8ad 100755 --- a/src/String/Specific/StringLanguageCode.php +++ b/src/String/Specific/StringLanguageCode.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\LanguageCodeStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -82,7 +81,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws LanguageCodeStringTypeException - * @throws StringTypeException + * @throws LanguageCodeStringTypeException * * @psalm-pure */ @@ -101,6 +100,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws LanguageCodeStringTypeException + */ + public static function fromNull(null $value): never + { + throw new LanguageCodeStringTypeException('StringLanguageCode type cannot be created from null'); + } + /** * @throws LanguageCodeStringTypeException * @@ -138,7 +145,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws LanguageCodeStringTypeException */ public function toBool(): bool { @@ -155,7 +162,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws LanguageCodeStringTypeException */ public function toFloat(): float { @@ -163,13 +170,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws LanguageCodeStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws LanguageCodeStringTypeException + */ + public static function toNull(): never + { + throw new LanguageCodeStringTypeException('StringLanguageCode type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/src/String/Specific/StringLocaleCode.php b/src/String/Specific/StringLocaleCode.php index 8d9f5702..e8f56fd2 100755 --- a/src/String/Specific/StringLocaleCode.php +++ b/src/String/Specific/StringLocaleCode.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\LocaleStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -77,7 +76,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws LocaleStringTypeException * @throws LocaleStringTypeException * * @psalm-pure @@ -100,7 +99,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws LocaleStringTypeException - * @throws StringTypeException + * @throws LocaleStringTypeException * * @psalm-pure */ @@ -119,6 +118,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws LocaleStringTypeException + */ + public static function fromNull(null $value): never + { + throw new LocaleStringTypeException('StringLocaleCode type cannot be created from null'); + } + /** * @throws LocaleStringTypeException * @@ -176,7 +183,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws LocaleStringTypeException */ public function toBool(): bool { @@ -193,7 +200,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws LocaleStringTypeException */ public function toFloat(): float { @@ -201,13 +208,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws LocaleStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws LocaleStringTypeException + */ + public static function toNull(): never + { + throw new LocaleStringTypeException('StringLocaleCode type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/src/String/Specific/StringMacAddress.php b/src/String/Specific/StringMacAddress.php index be22a644..06c1f25f 100755 --- a/src/String/Specific/StringMacAddress.php +++ b/src/String/Specific/StringMacAddress.php @@ -11,7 +11,6 @@ use PhpTypedValues\Base\Primitive\String\StringTypeAbstract; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\MacAddressStringException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -74,7 +73,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws MacAddressStringException - * @throws StringTypeException + * @throws MacAddressStringException * * @psalm-pure */ @@ -93,6 +92,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws MacAddressStringException + */ + public static function fromNull(null $value): never + { + throw new MacAddressStringException('StringMacAddress type cannot be created from null'); + } + /** * @throws MacAddressStringException * @@ -149,6 +156,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws MacAddressStringException + */ + public static function toNull(): never + { + throw new MacAddressStringException('StringMacAddress type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/Specific/StringMd5.php b/src/String/Specific/StringMd5.php index f7f2b81a..1e8ccc33 100755 --- a/src/String/Specific/StringMd5.php +++ b/src/String/Specific/StringMd5.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\Md5StringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -77,7 +76,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws Md5StringTypeException - * @throws StringTypeException + * @throws Md5StringTypeException * * @psalm-pure */ @@ -96,6 +95,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws Md5StringTypeException + */ + public static function fromNull(null $value): never + { + throw new Md5StringTypeException('StringMd5 type cannot be created from null'); + } + /** * Creates an MD5 instance from an existing MD5 hash string. * @@ -135,7 +142,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws Md5StringTypeException */ public function toBool(): bool { @@ -152,7 +159,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws Md5StringTypeException */ public function toFloat(): float { @@ -160,13 +167,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws Md5StringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws Md5StringTypeException + */ + public static function toNull(): never + { + throw new Md5StringTypeException('StringMd5 type cannot be converted to null'); + } + /** * Returns the MD5 hash as a string. * diff --git a/src/String/Specific/StringMimeType.php b/src/String/Specific/StringMimeType.php index 50f36502..498ee5c1 100755 --- a/src/String/Specific/StringMimeType.php +++ b/src/String/Specific/StringMimeType.php @@ -48,7 +48,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws MimeTypeStringTypeException * @throws MimeTypeStringTypeException * * @psalm-pure @@ -71,7 +71,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws MimeTypeStringTypeException - * @throws StringTypeException + * @throws MimeTypeStringTypeException * * @psalm-pure */ @@ -90,6 +90,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws MimeTypeStringTypeException + */ + public static function fromNull(null $value): never + { + throw new MimeTypeStringTypeException('StringMimeType type cannot be created from null'); + } + /** * @throws MimeTypeStringTypeException * @@ -144,7 +152,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws MimeTypeStringTypeException */ public function toBool(): bool { @@ -160,7 +168,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws MimeTypeStringTypeException * @throws FloatTypeException */ public function toFloat(): float @@ -169,13 +177,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws MimeTypeStringTypeException */ public function toInt(): int { return static::stringToInt($this->value); } + /** + * @throws MimeTypeStringTypeException + */ + public static function toNull(): never + { + throw new MimeTypeStringTypeException('StringMimeType type cannot be converted to null'); + } + public function toString(): string { return $this->value; diff --git a/src/String/Specific/StringPath.php b/src/String/Specific/StringPath.php index b7499300..63faf2e1 100755 --- a/src/String/Specific/StringPath.php +++ b/src/String/Specific/StringPath.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\PathStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -83,7 +82,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws PathStringTypeException - * @throws StringTypeException + * @throws PathStringTypeException * * @psalm-pure */ @@ -102,6 +101,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws PathStringTypeException + */ + public static function fromNull(null $value): never + { + throw new PathStringTypeException('StringPath type cannot be created from null'); + } + /** * @throws PathStringTypeException * @@ -139,7 +146,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws PathStringTypeException */ public function toBool(): bool { @@ -156,7 +163,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws PathStringTypeException */ public function toFloat(): float { @@ -164,13 +171,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws PathStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws PathStringTypeException + */ + public static function toNull(): never + { + throw new PathStringTypeException('StringPath type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/src/String/Specific/StringPhoneE164.php b/src/String/Specific/StringPhoneE164.php index 3609f572..c7a1695b 100755 --- a/src/String/Specific/StringPhoneE164.php +++ b/src/String/Specific/StringPhoneE164.php @@ -47,7 +47,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws PhoneE164StringTypeException * @throws PhoneE164StringTypeException * * @psalm-pure @@ -70,7 +70,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws PhoneE164StringTypeException - * @throws StringTypeException + * @throws PhoneE164StringTypeException * * @psalm-pure */ @@ -89,6 +89,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws PhoneE164StringTypeException + */ + public static function fromNull(null $value): never + { + throw new PhoneE164StringTypeException('StringPhoneE164 type cannot be created from null'); + } + /** * @throws PhoneE164StringTypeException * @@ -129,7 +137,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws PhoneE164StringTypeException */ public function toBool(): bool { @@ -145,7 +153,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws PhoneE164StringTypeException * @throws FloatTypeException */ public function toFloat(): float @@ -154,13 +162,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws PhoneE164StringTypeException */ public function toInt(): int { return static::stringToInt($this->value); } + /** + * @throws PhoneE164StringTypeException + */ + public static function toNull(): never + { + throw new PhoneE164StringTypeException('StringPhoneE164 type cannot be converted to null'); + } + public function toString(): string { return $this->value; diff --git a/src/String/Specific/StringSemVer.php b/src/String/Specific/StringSemVer.php index de75b05a..62cf6b9a 100755 --- a/src/String/Specific/StringSemVer.php +++ b/src/String/Specific/StringSemVer.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\SemVerStringTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -79,7 +78,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws SemVerStringTypeException - * @throws StringTypeException + * @throws SemVerStringTypeException * * @psalm-pure */ @@ -98,6 +97,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws SemVerStringTypeException + */ + public static function fromNull(null $value): never + { + throw new SemVerStringTypeException('StringSemVer type cannot be created from null'); + } + /** * Creates a SemVer instance from an existing Semantic Version string. * @@ -137,7 +144,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws SemVerStringTypeException */ public function toBool(): bool { @@ -154,7 +161,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws SemVerStringTypeException */ public function toFloat(): float { @@ -162,13 +169,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws SemVerStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws SemVerStringTypeException + */ + public static function toNull(): never + { + throw new SemVerStringTypeException('StringSemVer type cannot be converted to null'); + } + /** * Returns the Semantic Version string. * diff --git a/src/String/Specific/StringSha256.php b/src/String/Specific/StringSha256.php index 382b02d9..0eadbbb4 100755 --- a/src/String/Specific/StringSha256.php +++ b/src/String/Specific/StringSha256.php @@ -46,7 +46,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws Sha256StringTypeException * @throws Sha256StringTypeException * * @psalm-pure @@ -69,7 +69,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws Sha256StringTypeException - * @throws StringTypeException + * @throws Sha256StringTypeException * * @psalm-pure */ @@ -88,6 +88,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws Sha256StringTypeException + */ + public static function fromNull(null $value): never + { + throw new Sha256StringTypeException('StringSha256 type cannot be created from null'); + } + /** * @throws Sha256StringTypeException * @@ -128,7 +136,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws Sha256StringTypeException */ public function toBool(): bool { @@ -144,7 +152,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws Sha256StringTypeException * @throws FloatTypeException */ public function toFloat(): float @@ -153,13 +161,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws Sha256StringTypeException */ public function toInt(): int { return static::stringToInt($this->value); } + /** + * @throws Sha256StringTypeException + */ + public static function toNull(): never + { + throw new Sha256StringTypeException('StringSha256 type cannot be converted to null'); + } + public function toString(): string { return $this->value; diff --git a/src/String/Specific/StringSha512.php b/src/String/Specific/StringSha512.php index bd896b3f..913ed224 100755 --- a/src/String/Specific/StringSha512.php +++ b/src/String/Specific/StringSha512.php @@ -46,7 +46,7 @@ public function __construct(string $value) } /** - * @throws StringTypeException + * @throws Sha512StringTypeException * @throws Sha512StringTypeException * * @psalm-pure @@ -69,7 +69,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws Sha512StringTypeException - * @throws StringTypeException + * @throws Sha512StringTypeException * * @psalm-pure */ @@ -88,6 +88,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws Sha512StringTypeException + */ + public static function fromNull(null $value): never + { + throw new Sha512StringTypeException('StringSha512 type cannot be created from null'); + } + /** * @throws Sha512StringTypeException * @@ -128,7 +136,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws Sha512StringTypeException */ public function toBool(): bool { @@ -144,7 +152,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws Sha512StringTypeException * @throws FloatTypeException */ public function toFloat(): float @@ -153,13 +161,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws Sha512StringTypeException */ public function toInt(): int { return static::stringToInt($this->value); } + /** + * @throws Sha512StringTypeException + */ + public static function toNull(): never + { + throw new Sha512StringTypeException('StringSha512 type cannot be converted to null'); + } + public function toString(): string { return $this->value; diff --git a/src/String/Specific/StringSlug.php b/src/String/Specific/StringSlug.php index 6d5b9c0b..ab90e7e9 100755 --- a/src/String/Specific/StringSlug.php +++ b/src/String/Specific/StringSlug.php @@ -10,7 +10,6 @@ use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; use PhpTypedValues\Exception\String\SlugStringException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -77,7 +76,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws SlugStringException - * @throws StringTypeException + * @throws SlugStringException * * @psalm-pure */ @@ -96,6 +95,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws SlugStringException + */ + public static function fromNull(null $value): never + { + throw new SlugStringException('StringSlug type cannot be created from null'); + } + /** * @throws SlugStringException * @@ -133,7 +140,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws SlugStringException */ public function toBool(): bool { @@ -149,7 +156,7 @@ public function toDecimal(): string } /** - * @throws StringTypeException + * @throws SlugStringException * @throws FloatTypeException */ public function toFloat(): float @@ -158,13 +165,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws SlugStringException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws SlugStringException + */ + public static function toNull(): never + { + throw new SlugStringException('StringSlug type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/src/String/Specific/StringUrl.php b/src/String/Specific/StringUrl.php index 9e695587..b10bca54 100755 --- a/src/String/Specific/StringUrl.php +++ b/src/String/Specific/StringUrl.php @@ -11,7 +11,6 @@ use PhpTypedValues\Base\Primitive\String\StringTypeAbstract; use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\String\UrlStringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; @@ -79,7 +78,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws UrlStringTypeException - * @throws StringTypeException + * @throws UrlStringTypeException * * @psalm-pure */ @@ -98,6 +97,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws UrlStringTypeException + */ + public static function fromNull(null $value): never + { + throw new UrlStringTypeException('StringUrl type cannot be created from null'); + } + /** * @throws UrlStringTypeException * @@ -135,7 +142,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws UrlStringTypeException */ public function toBool(): bool { @@ -152,7 +159,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws UrlStringTypeException */ public function toFloat(): float { @@ -160,13 +167,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws UrlStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws UrlStringTypeException + */ + public static function toNull(): never + { + throw new UrlStringTypeException('StringUrl type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/src/String/Specific/StringUrlPath.php b/src/String/Specific/StringUrlPath.php index f2603af6..15ac741c 100755 --- a/src/String/Specific/StringUrlPath.php +++ b/src/String/Specific/StringUrlPath.php @@ -9,7 +9,6 @@ use PhpTypedValues\Base\Primitive\String\StringTypeAbstract; use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\String\UrlPathStringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; @@ -90,7 +89,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws UrlPathStringTypeException - * @throws StringTypeException + * @throws UrlPathStringTypeException * * @psalm-pure */ @@ -109,6 +108,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws UrlPathStringTypeException + */ + public static function fromNull(null $value): never + { + throw new UrlPathStringTypeException('StringUrlPath type cannot be created from null'); + } + /** * @throws UrlPathStringTypeException * @@ -146,7 +153,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws UrlPathStringTypeException */ public function toBool(): bool { @@ -163,7 +170,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws UrlPathStringTypeException */ public function toFloat(): float { @@ -171,13 +178,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws UrlPathStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws UrlPathStringTypeException + */ + public static function toNull(): never + { + throw new UrlPathStringTypeException('StringUrlPath type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/src/String/Specific/StringUsername.php b/src/String/Specific/StringUsername.php index 2797d923..cddf9f2a 100755 --- a/src/String/Specific/StringUsername.php +++ b/src/String/Specific/StringUsername.php @@ -9,7 +9,6 @@ use PhpTypedValues\Base\Primitive\String\StringTypeAbstract; use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\String\UsernameStringException; use PhpTypedValues\Undefined\Alias\Undefined; use Stringable; @@ -73,7 +72,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws UsernameStringException - * @throws StringTypeException + * @throws UsernameStringException * * @psalm-pure */ @@ -92,6 +91,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws UsernameStringException + */ + public static function fromNull(null $value): never + { + throw new UsernameStringException('StringUsername type cannot be created from null'); + } + /** * @throws UsernameStringException * @@ -129,7 +136,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws UsernameStringException */ public function toBool(): bool { @@ -153,13 +160,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws UsernameStringException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws UsernameStringException + */ + public static function toNull(): never + { + throw new UsernameStringException('StringUsername type cannot be converted to null'); + } + public function toString(): string { return $this->value; diff --git a/src/String/Specific/StringUuidV4.php b/src/String/Specific/StringUuidV4.php index 3b3d3776..961e4f19 100755 --- a/src/String/Specific/StringUuidV4.php +++ b/src/String/Specific/StringUuidV4.php @@ -9,7 +9,6 @@ use PhpTypedValues\Base\Primitive\String\StringTypeAbstract; use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\String\UuidStringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; @@ -84,7 +83,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws UuidStringTypeException - * @throws StringTypeException + * @throws UuidStringTypeException * * @psalm-pure */ @@ -103,6 +102,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws UuidStringTypeException + */ + public static function fromNull(null $value): never + { + throw new UuidStringTypeException('StringUuidV4 type cannot be created from null'); + } + /** * @throws UuidStringTypeException * @@ -140,7 +147,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws UuidStringTypeException */ public function toBool(): bool { @@ -157,7 +164,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws UuidStringTypeException */ public function toFloat(): float { @@ -165,13 +172,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws UuidStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws UuidStringTypeException + */ + public static function toNull(): never + { + throw new UuidStringTypeException('StringUuidV4 type cannot be converted to null'); + } + /** @return non-empty-string */ public function toString(): string { diff --git a/src/String/Specific/StringUuidV7.php b/src/String/Specific/StringUuidV7.php index 43f2eebf..d065943e 100755 --- a/src/String/Specific/StringUuidV7.php +++ b/src/String/Specific/StringUuidV7.php @@ -9,7 +9,6 @@ use PhpTypedValues\Base\Primitive\String\StringTypeAbstract; use PhpTypedValues\Exception\Decimal\DecimalTypeException; use PhpTypedValues\Exception\Float\FloatTypeException; -use PhpTypedValues\Exception\String\StringTypeException; use PhpTypedValues\Exception\String\UuidStringTypeException; use PhpTypedValues\Exception\TypeException; use PhpTypedValues\Undefined\Alias\Undefined; @@ -84,7 +83,7 @@ public static function fromDecimal(string $value): static /** * @throws FloatTypeException * @throws UuidStringTypeException - * @throws StringTypeException + * @throws UuidStringTypeException * * @psalm-pure */ @@ -103,6 +102,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws UuidStringTypeException + */ + public static function fromNull(null $value): never + { + throw new UuidStringTypeException('StringUuidV7 type cannot be created from null'); + } + /** * @throws UuidStringTypeException * @@ -140,7 +147,7 @@ public function jsonSerialize(): string } /** - * @throws StringTypeException + * @throws UuidStringTypeException */ public function toBool(): bool { @@ -157,7 +164,7 @@ public function toDecimal(): string /** * @throws FloatTypeException - * @throws StringTypeException + * @throws UuidStringTypeException */ public function toFloat(): float { @@ -165,13 +172,21 @@ public function toFloat(): float } /** - * @throws StringTypeException + * @throws UuidStringTypeException */ public function toInt(): int { return static::stringToInt($this->value()); } + /** + * @throws UuidStringTypeException + */ + public static function toNull(): never + { + throw new UuidStringTypeException('StringUuidV7 type cannot be converted to null'); + } + /** @return non-empty-string */ public function toString(): string { diff --git a/src/String/StringNonBlank.php b/src/String/StringNonBlank.php index 0e2fdff2..f8fba3d6 100755 --- a/src/String/StringNonBlank.php +++ b/src/String/StringNonBlank.php @@ -95,6 +95,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringNonBlank type cannot be created from null'); + } + /** * @throws StringTypeException * @@ -164,6 +172,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringNonBlank type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/src/String/StringNonEmpty.php b/src/String/StringNonEmpty.php index b402089d..fc8f7dfd 100755 --- a/src/String/StringNonEmpty.php +++ b/src/String/StringNonEmpty.php @@ -91,6 +91,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringNonEmpty type cannot be created from null'); + } + /** * @throws StringTypeException * @@ -160,6 +168,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringNonEmpty type cannot be converted to null'); + } + /** * @return non-empty-string */ diff --git a/src/String/StringStandard.php b/src/String/StringStandard.php index bc34d61b..55f60ff3 100755 --- a/src/String/StringStandard.php +++ b/src/String/StringStandard.php @@ -76,6 +76,14 @@ public static function fromInt(int $value): static return new static(static::intToString($value)); } + /** + * @throws StringTypeException + */ + public static function fromNull(null $value): never + { + throw new StringTypeException('StringStandard type cannot be created from null'); + } + /** * @psalm-pure */ @@ -143,6 +151,14 @@ public function toInt(): int return static::stringToInt($this->value()); } + /** + * @throws StringTypeException + */ + public static function toNull(): never + { + throw new StringTypeException('StringStandard type cannot be converted to null'); + } + public function toString(): string { return $this->value(); diff --git a/tests/Unit/String/Alias/StringTypeTest.php b/tests/Unit/String/Alias/StringTypeTest.php new file mode 100755 index 00000000..6aa0c2c9 --- /dev/null +++ b/tests/Unit/String/Alias/StringTypeTest.php @@ -0,0 +1,27 @@ +value())->toBe('test'); + }); + + it('throws exception on fromNull', function () { + expect(fn() => StringType::fromNull(null)) + ->toThrow(StringTypeException::class, 'StringType type cannot be created from null'); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringType::toNull()) + ->toThrow(StringTypeException::class, 'StringType type cannot be converted to null'); + }); +}); diff --git a/tests/Unit/String/MariaDb/StringLongTextTest.php b/tests/Unit/String/MariaDb/StringLongTextTest.php index 00dcaca0..c24c47f5 100755 --- a/tests/Unit/String/MariaDb/StringLongTextTest.php +++ b/tests/Unit/String/MariaDb/StringLongTextTest.php @@ -244,3 +244,15 @@ protected static function maxLength(): int expect($reflection->invoke(null))->toBe(4294967295); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringLongText::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringLongText::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/MariaDb/StringMediumTextTest.php b/tests/Unit/String/MariaDb/StringMediumTextTest.php index a6b96a53..dc1c2a9c 100755 --- a/tests/Unit/String/MariaDb/StringMediumTextTest.php +++ b/tests/Unit/String/MariaDb/StringMediumTextTest.php @@ -214,3 +214,15 @@ public static function fromString(string $value): static ->and(StringMediumTextTest::tryFromString('test'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringMediumText::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringMediumText::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/MariaDb/StringTextTest.php b/tests/Unit/String/MariaDb/StringTextTest.php index 189189b6..225331c5 100755 --- a/tests/Unit/String/MariaDb/StringTextTest.php +++ b/tests/Unit/String/MariaDb/StringTextTest.php @@ -212,3 +212,15 @@ public static function fromString(string $value): static ->and(StringTextTest::tryFromString('test'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringText::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringText::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/MariaDb/StringTinyTextTest.php b/tests/Unit/String/MariaDb/StringTinyTextTest.php index 185d3d41..b49ca681 100755 --- a/tests/Unit/String/MariaDb/StringTinyTextTest.php +++ b/tests/Unit/String/MariaDb/StringTinyTextTest.php @@ -218,3 +218,15 @@ public static function fromString(string $value): static ->and(StringTinyTextTest::tryFromString('test'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringTinyText::fromNull(null)) + ->toThrow(TinyTextStringException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringTinyText::toNull()) + ->toThrow(TinyTextStringException::class); + }); +}); diff --git a/tests/Unit/String/MariaDb/StringVarChar255Test.php b/tests/Unit/String/MariaDb/StringVarChar255Test.php index 0fc9a6eb..d67234c0 100755 --- a/tests/Unit/String/MariaDb/StringVarChar255Test.php +++ b/tests/Unit/String/MariaDb/StringVarChar255Test.php @@ -218,3 +218,15 @@ public static function fromString(string $value): static ->and(StringVarChar255Test::tryFromString('test'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringVarChar255::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringVarChar255::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringIbanTest.php b/tests/Unit/String/Specific/StringIbanTest.php index 27554342..c6ab175f 100755 --- a/tests/Unit/String/Specific/StringIbanTest.php +++ b/tests/Unit/String/Specific/StringIbanTest.php @@ -404,3 +404,15 @@ public static function fromString(string $value): static ->and(StringIbanTest::tryFromString('DE89370400440532013000'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringIban::fromNull(null)) + ->toThrow(IbanStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringIban::toNull()) + ->toThrow(IbanStringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringIpV4Test.php b/tests/Unit/String/Specific/StringIpV4Test.php index 2cfd8ce8..522353ae 100755 --- a/tests/Unit/String/Specific/StringIpV4Test.php +++ b/tests/Unit/String/Specific/StringIpV4Test.php @@ -219,3 +219,15 @@ public static function fromString(string $value): static expect($result)->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringIpV4::fromNull(null)) + ->toThrow(IpV4StringException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringIpV4::toNull()) + ->toThrow(IpV4StringException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringIpV6Test.php b/tests/Unit/String/Specific/StringIpV6Test.php index 6150c2e6..92ff3d15 100755 --- a/tests/Unit/String/Specific/StringIpV6Test.php +++ b/tests/Unit/String/Specific/StringIpV6Test.php @@ -209,3 +209,15 @@ public static function fromString(string $value): static expect($result)->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringIpV6::fromNull(null)) + ->toThrow(IpV6StringException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringIpV6::toNull()) + ->toThrow(IpV6StringException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringJsonTest.php b/tests/Unit/String/Specific/StringJsonTest.php index b93d9859..e7bb4129 100755 --- a/tests/Unit/String/Specific/StringJsonTest.php +++ b/tests/Unit/String/Specific/StringJsonTest.php @@ -294,3 +294,15 @@ public static function fromString(string $value): static ->and(StringJsonTest::tryFromString('{"a":1}'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringJson::fromNull(null)) + ->toThrow(JsonStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringJson::toNull()) + ->toThrow(JsonStringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringJwtTest.php b/tests/Unit/String/Specific/StringJwtTest.php index 936e1d84..075ee089 100755 --- a/tests/Unit/String/Specific/StringJwtTest.php +++ b/tests/Unit/String/Specific/StringJwtTest.php @@ -179,3 +179,15 @@ public static function fromString(string $value): static ->and(StringJwtTest::tryFromString($validJwt))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringJwt::fromNull(null)) + ->toThrow(JwtStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringJwt::toNull()) + ->toThrow(JwtStringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringLanguageCodeTest.php b/tests/Unit/String/Specific/StringLanguageCodeTest.php index ad4d722c..7e54b465 100755 --- a/tests/Unit/String/Specific/StringLanguageCodeTest.php +++ b/tests/Unit/String/Specific/StringLanguageCodeTest.php @@ -274,3 +274,15 @@ public static function fromString(string $value): static ->and(StringLanguageCodeTest::tryFromString('en'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringLanguageCode::fromNull(null)) + ->toThrow(LanguageCodeStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringLanguageCode::toNull()) + ->toThrow(LanguageCodeStringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringLocaleCodeTest.php b/tests/Unit/String/Specific/StringLocaleCodeTest.php index 4246529f..fe22812e 100755 --- a/tests/Unit/String/Specific/StringLocaleCodeTest.php +++ b/tests/Unit/String/Specific/StringLocaleCodeTest.php @@ -179,3 +179,15 @@ public static function fromString(string $value): static ->and(StringLocaleCodeTest::tryFromString('en_US'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringLocaleCode::fromNull(null)) + ->toThrow(LocaleStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringLocaleCode::toNull()) + ->toThrow(LocaleStringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringMacAddressTest.php b/tests/Unit/String/Specific/StringMacAddressTest.php index c961014f..bab696f2 100755 --- a/tests/Unit/String/Specific/StringMacAddressTest.php +++ b/tests/Unit/String/Specific/StringMacAddressTest.php @@ -212,3 +212,15 @@ public function isTypeOf(string ...$classNames): bool expect($result)->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringMacAddress::fromNull(null)) + ->toThrow(MacAddressStringException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringMacAddress::toNull()) + ->toThrow(MacAddressStringException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringMd5Test.php b/tests/Unit/String/Specific/StringMd5Test.php index da793d9f..3d6bafb1 100755 --- a/tests/Unit/String/Specific/StringMd5Test.php +++ b/tests/Unit/String/Specific/StringMd5Test.php @@ -229,3 +229,15 @@ public static function fromString(string $value): static ->and(StringMd5Test::tryFromString('5d41402abc4b2a76b9719d911017c592'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringMd5::fromNull(null)) + ->toThrow(Md5StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringMd5::toNull()) + ->toThrow(Md5StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringMimeTypeTest.php b/tests/Unit/String/Specific/StringMimeTypeTest.php index 25bcba3d..5f61eb2f 100755 --- a/tests/Unit/String/Specific/StringMimeTypeTest.php +++ b/tests/Unit/String/Specific/StringMimeTypeTest.php @@ -203,3 +203,15 @@ public static function fromString(string $value): static ->and(StringMimeTypeStandardTest::tryFromString('application/json'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringMimeType::fromNull(null)) + ->toThrow(MimeTypeStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringMimeType::toNull()) + ->toThrow(MimeTypeStringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringPathTest.php b/tests/Unit/String/Specific/StringPathTest.php index 1235c3cf..cfdfceeb 100755 --- a/tests/Unit/String/Specific/StringPathTest.php +++ b/tests/Unit/String/Specific/StringPathTest.php @@ -188,3 +188,15 @@ public static function fromString(string $value): static ->and(StringPathTest::tryFromString('/home/user'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringPath::fromNull(null)) + ->toThrow(PathStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringPath::toNull()) + ->toThrow(PathStringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringPhoneE164Test.php b/tests/Unit/String/Specific/StringPhoneE164Test.php index 264e6b66..33c7e879 100755 --- a/tests/Unit/String/Specific/StringPhoneE164Test.php +++ b/tests/Unit/String/Specific/StringPhoneE164Test.php @@ -180,3 +180,15 @@ public static function fromString(string $value): static ->and(StringPhoneE164Test::tryFromString($validPhone))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringPhoneE164::fromNull(null)) + ->toThrow(PhoneE164StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringPhoneE164::toNull()) + ->toThrow(PhoneE164StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringSemVerTest.php b/tests/Unit/String/Specific/StringSemVerTest.php index 2a1e2122..424f9246 100755 --- a/tests/Unit/String/Specific/StringSemVerTest.php +++ b/tests/Unit/String/Specific/StringSemVerTest.php @@ -235,3 +235,15 @@ public static function fromString(string $value): static ->and(StringSemVerTest::tryFromString('1.2.3'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringSemVer::fromNull(null)) + ->toThrow(SemVerStringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringSemVer::toNull()) + ->toThrow(SemVerStringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringSha256Test.php b/tests/Unit/String/Specific/StringSha256Test.php index a02b0b17..99e27b35 100755 --- a/tests/Unit/String/Specific/StringSha256Test.php +++ b/tests/Unit/String/Specific/StringSha256Test.php @@ -179,3 +179,15 @@ public static function fromString(string $value): static ->and(StringSha256Test::tryFromString($validHash))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringSha256::fromNull(null)) + ->toThrow(Sha256StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringSha256::toNull()) + ->toThrow(Sha256StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringSha512Test.php b/tests/Unit/String/Specific/StringSha512Test.php index 0f5c8850..5923d36a 100755 --- a/tests/Unit/String/Specific/StringSha512Test.php +++ b/tests/Unit/String/Specific/StringSha512Test.php @@ -179,3 +179,15 @@ public static function fromString(string $value): static ->and(StringSha512Test::tryFromString($validHash))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringSha512::fromNull(null)) + ->toThrow(Sha512StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringSha512::toNull()) + ->toThrow(Sha512StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringSlugTest.php b/tests/Unit/String/Specific/StringSlugTest.php index dfa4b717..ec804dea 100755 --- a/tests/Unit/String/Specific/StringSlugTest.php +++ b/tests/Unit/String/Specific/StringSlugTest.php @@ -249,3 +249,15 @@ public static function fromString(string $value): static ->and(StringSlugTest::tryFromString('trigger-exception', $default))->toBe($default); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringSlug::fromNull(null)) + ->toThrow(SlugStringException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringSlug::toNull()) + ->toThrow(SlugStringException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringUrlPathTest.php b/tests/Unit/String/Specific/StringUrlPathTest.php index 78d7b98a..32429cd5 100755 --- a/tests/Unit/String/Specific/StringUrlPathTest.php +++ b/tests/Unit/String/Specific/StringUrlPathTest.php @@ -195,3 +195,15 @@ public static function fromString(string $value): static ->and(StringUrlPathTest::tryFromString('/test'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringUrlPath::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringUrlPath::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringUrlTest.php b/tests/Unit/String/Specific/StringUrlTest.php index b73e68d7..4552b2c6 100755 --- a/tests/Unit/String/Specific/StringUrlTest.php +++ b/tests/Unit/String/Specific/StringUrlTest.php @@ -180,3 +180,15 @@ public static function fromString(string $value): static ->and(StringUrlTest::tryFromString('https://example.com'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringUrl::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringUrl::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringUsernameTest.php b/tests/Unit/String/Specific/StringUsernameTest.php index ad74041f..bc453658 100755 --- a/tests/Unit/String/Specific/StringUsernameTest.php +++ b/tests/Unit/String/Specific/StringUsernameTest.php @@ -253,3 +253,15 @@ public static function fromString(string $value): static ->and(StringUsernameTest::tryFromString('trigger-exception', $default))->toBe($default); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringUsername::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringUsername::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringUuidV4Test.php b/tests/Unit/String/Specific/StringUuidV4Test.php index b3b81b50..f1b45b3b 100755 --- a/tests/Unit/String/Specific/StringUuidV4Test.php +++ b/tests/Unit/String/Specific/StringUuidV4Test.php @@ -208,3 +208,15 @@ public static function fromString(string $value): static ->and(StringUuidV4Test::tryFromString('550e8400-e29b-41d4-a716-446655440000'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringUuidV4::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringUuidV4::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/Specific/StringUuidV7Test.php b/tests/Unit/String/Specific/StringUuidV7Test.php index 3ba9f86d..d5801fc8 100755 --- a/tests/Unit/String/Specific/StringUuidV7Test.php +++ b/tests/Unit/String/Specific/StringUuidV7Test.php @@ -207,3 +207,15 @@ public static function fromString(string $value): static ->and(StringUuidV7Test::tryFromString('01890f2a-5bcd-7def-8abc-1234567890ab'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringUuidV7::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringUuidV7::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/StringNonBlankTest.php b/tests/Unit/String/StringNonBlankTest.php index ef203ebf..81ff106d 100755 --- a/tests/Unit/String/StringNonBlankTest.php +++ b/tests/Unit/String/StringNonBlankTest.php @@ -192,3 +192,15 @@ public static function fromString(string $value): static expect(StringNonBlankTest::tryFromString('test'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringNonBlank::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringNonBlank::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/StringNonEmptyTest.php b/tests/Unit/String/StringNonEmptyTest.php index d5d8acc8..8f295061 100755 --- a/tests/Unit/String/StringNonEmptyTest.php +++ b/tests/Unit/String/StringNonEmptyTest.php @@ -201,3 +201,15 @@ public static function fromString(string $value): static expect(StringNonEmptyTest::tryFromString('test'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringNonEmpty::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringNonEmpty::toNull()) + ->toThrow(StringTypeException::class); + }); +}); diff --git a/tests/Unit/String/StringStandardTest.php b/tests/Unit/String/StringStandardTest.php index 01976358..2447b141 100755 --- a/tests/Unit/String/StringStandardTest.php +++ b/tests/Unit/String/StringStandardTest.php @@ -325,3 +325,15 @@ public static function fromString(string $value): static expect(ThrowingStringStandardTest::tryFromMixed('any'))->toBeInstanceOf(Undefined::class); }); }); + +describe('Null checks', function () { + it('throws exception on fromNull', function () { + expect(fn() => StringStandard::fromNull(null)) + ->toThrow(StringTypeException::class); + }); + + it('throws exception on toNull', function () { + expect(fn() => StringStandard::toNull()) + ->toThrow(StringTypeException::class); + }); +}); From 3d9ff26e29cd1122a9fbee94b3fabe7103618f26 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 11:30:55 +0200 Subject: [PATCH 70/83] Add null handling to DateIso8601: fromNull and toNull throw Iso8601DateTypeException Implemented static `fromNull` and `toNull` methods that always throw `Iso8601DateTypeException`. Updated docblocks accordingly and added unit tests to verify the exception behavior for both methods. --- src/DateTime/DateIso8601.php | 16 ++++++++++++++++ tests/Unit/DateTime/DateIso8601Test.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/DateTime/DateIso8601.php b/src/DateTime/DateIso8601.php index 27fedc06..206b3be8 100755 --- a/src/DateTime/DateIso8601.php +++ b/src/DateTime/DateIso8601.php @@ -54,6 +54,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws Iso8601DateTypeException + */ + public static function fromNull(null $value): never + { + throw new Iso8601DateTypeException('DateIso8601 type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -107,6 +115,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws Iso8601DateTypeException + */ + public static function toNull(): never + { + throw new Iso8601DateTypeException('DateIso8601 type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/DateIso8601Test.php b/tests/Unit/DateTime/DateIso8601Test.php index 0b5c627a..87ed9b68 100755 --- a/tests/Unit/DateTime/DateIso8601Test.php +++ b/tests/Unit/DateTime/DateIso8601Test.php @@ -84,6 +84,18 @@ public function __toString(): string expect(DateIso8601::getFormat())->toBe('Y-m-d'); }); }); + + describe('Null checks', function () { + it('throws an exception when created from null', function () { + expect(fn() => DateIso8601::fromNull(null)) + ->toThrow(Iso8601DateTypeException::class, 'DateIso8601 type cannot be created from null'); + }); + + it('throws an exception when converted to null', function () { + expect(fn() => DateIso8601::toNull()) + ->toThrow(Iso8601DateTypeException::class, 'DateIso8601 type cannot be converted to null'); + }); + }); }); describe('Instance Methods', function () { From 9580e51464c21eb5d70566e91d625753ec1fe81d Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:27:43 +0200 Subject: [PATCH 71/83] Add null handling to DateTimeAtom: fromNull and toNull throw DateTimeTypeException MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented static `fromNull` and instance `toNull` methods that always throw `DateTimeTypeException`. Updated docblocks accordingly and added unit tests to verify the exception behavior for both methods. --- src/DateTime/DateTimeAtom.php | 16 ++++++++++++++++ tests/Unit/DateTime/DateTimeAtomTest.php | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/DateTime/DateTimeAtom.php b/src/DateTime/DateTimeAtom.php index 01c66506..b7a1d9e8 100755 --- a/src/DateTime/DateTimeAtom.php +++ b/src/DateTime/DateTimeAtom.php @@ -58,6 +58,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws DateTimeTypeException + */ + public static function fromNull(null $value): never + { + throw new DateTimeTypeException('DateTimeAtom type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -107,6 +115,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws DateTimeTypeException + */ + public static function toNull(): never + { + throw new DateTimeTypeException('DateTimeAtom type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/DateTimeAtomTest.php b/tests/Unit/DateTime/DateTimeAtomTest.php index b25a9281..0bce0c6d 100755 --- a/tests/Unit/DateTime/DateTimeAtomTest.php +++ b/tests/Unit/DateTime/DateTimeAtomTest.php @@ -78,6 +78,20 @@ }); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeAtom::fromNull(null)) + ->toThrow(DateTimeTypeException::class, 'DateTimeAtom type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $dt = new DateTimeImmutable('2025-01-02T03:04:05+00:00'); + $vo = DateTimeAtom::fromDateTime($dt); + expect(fn() => $vo->toNull()) + ->toThrow(DateTimeTypeException::class, 'DateTimeAtom type cannot be converted to null'); + }); + }); + describe('tryFromString', function () { it('returns instance or default value', function (string $input, string $tz, bool $isSuccess) { $result = DateTimeAtom::tryFromString($input, $tz); From 8fdbecebe20269939762aa5e2d3ab26cd7f9ad7b Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:27:48 +0200 Subject: [PATCH 72/83] Add null handling to DateTimeCookie: fromNull and toNull throw CookieDateTimeTypeException MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented static `fromNull` and instance `toNull` methods that always throw `CookieDateTimeTypeException`. Updated docblocks accordingly and added unit tests to verify the exception behavior for both methods. --- src/DateTime/DateTimeCookie.php | 16 ++++++++++++++++ tests/Unit/DateTime/DateTimeCookieTest.php | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/DateTime/DateTimeCookie.php b/src/DateTime/DateTimeCookie.php index 5e72762a..4a1da2ec 100755 --- a/src/DateTime/DateTimeCookie.php +++ b/src/DateTime/DateTimeCookie.php @@ -57,6 +57,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws CookieDateTimeTypeException + */ + public static function fromNull(null $value): never + { + throw new CookieDateTimeTypeException('DateTimeCookie type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -110,6 +118,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws CookieDateTimeTypeException + */ + public static function toNull(): never + { + throw new CookieDateTimeTypeException('DateTimeCookie type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/DateTimeCookieTest.php b/tests/Unit/DateTime/DateTimeCookieTest.php index 19a6f788..65780f59 100755 --- a/tests/Unit/DateTime/DateTimeCookieTest.php +++ b/tests/Unit/DateTime/DateTimeCookieTest.php @@ -35,6 +35,20 @@ ]); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeCookie::fromNull(null)) + ->toThrow(CookieDateTimeTypeException::class, 'DateTimeCookie type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $dt = new DateTimeImmutable('2025-01-02T03:04:05+00:00'); + $vo = DateTimeCookie::fromDateTime($dt); + expect(fn() => $vo->toNull()) + ->toThrow(CookieDateTimeTypeException::class, 'DateTimeCookie type cannot be converted to null'); + }); + }); + describe('tryFromMixed', function () { it('returns instance for valid mixed inputs', function (mixed $input, string $expected) { $result = DateTimeCookie::tryFromMixed($input); From ad81d6f5afc7c1110d3df71dab1f2e54944dd093 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:27:53 +0200 Subject: [PATCH 73/83] Add null handling to DateTimeRFC1123: fromNull and toNull throw RFC1123DateTimeTypeException Added `fromNull` and `toNull` methods that always throw `RFC1123DateTimeTypeException` and introduced unit tests to confirm the exception behavior. --- src/DateTime/DateTimeRFC1123.php | 16 ++++++++++++++++ tests/Unit/DateTime/DateTimeRFC1123Test.php | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/DateTime/DateTimeRFC1123.php b/src/DateTime/DateTimeRFC1123.php index b401207e..d2731aa4 100755 --- a/src/DateTime/DateTimeRFC1123.php +++ b/src/DateTime/DateTimeRFC1123.php @@ -57,6 +57,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws RFC1123DateTimeTypeException + */ + public static function fromNull(null $value): never + { + throw new RFC1123DateTimeTypeException('DateTimeRFC1123 type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -110,6 +118,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws RFC1123DateTimeTypeException + */ + public static function toNull(): never + { + throw new RFC1123DateTimeTypeException('DateTimeRFC1123 type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/DateTimeRFC1123Test.php b/tests/Unit/DateTime/DateTimeRFC1123Test.php index a80eede7..4ac1931d 100755 --- a/tests/Unit/DateTime/DateTimeRFC1123Test.php +++ b/tests/Unit/DateTime/DateTimeRFC1123Test.php @@ -34,6 +34,19 @@ ]); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeRFC1123::fromNull(null)) + ->toThrow(RFC1123DateTimeTypeException::class, 'DateTimeRFC1123 type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $vo = DateTimeRFC1123::fromString('Thu, 02 Jan 2025 03:04:05 +0000'); + expect(fn() => $vo::toNull()) + ->toThrow(RFC1123DateTimeTypeException::class, 'DateTimeRFC1123 type cannot be converted to null'); + }); + }); + describe('tryFromMixed', function () { it('returns instance for valid mixed inputs', function (mixed $input, string $expected) { $result = DateTimeRFC1123::tryFromMixed($input); From 171c1908023dc34b0236a829ad2c6ea7f534e60b Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:27:57 +0200 Subject: [PATCH 74/83] Add null handling to DateTimeRFC2822: fromNull and toNull throw RFC2822DateTimeTypeException MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented static `fromNull` and instance `toNull` methods that always throw `RFC2822DateTimeTypeException`. Updated docblocks accordingly and added unit tests to verify the exception behavior. --- src/DateTime/DateTimeRFC2822.php | 16 ++++++++++++++++ tests/Unit/DateTime/DateTimeRFC2822Test.php | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/DateTime/DateTimeRFC2822.php b/src/DateTime/DateTimeRFC2822.php index d87b6922..203d380f 100755 --- a/src/DateTime/DateTimeRFC2822.php +++ b/src/DateTime/DateTimeRFC2822.php @@ -57,6 +57,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws RFC2822DateTimeTypeException + */ + public static function fromNull(null $value): never + { + throw new RFC2822DateTimeTypeException('DateTimeRFC2822 type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -110,6 +118,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws RFC2822DateTimeTypeException + */ + public static function toNull(): never + { + throw new RFC2822DateTimeTypeException('DateTimeRFC2822 type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/DateTimeRFC2822Test.php b/tests/Unit/DateTime/DateTimeRFC2822Test.php index d0ebe22c..5f78d6f8 100755 --- a/tests/Unit/DateTime/DateTimeRFC2822Test.php +++ b/tests/Unit/DateTime/DateTimeRFC2822Test.php @@ -33,6 +33,20 @@ ]); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeRFC2822::fromNull(null)) + ->toThrow(RFC2822DateTimeTypeException::class, 'DateTimeRFC2822 type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $dt = new DateTimeImmutable('2025-01-02T03:04:05+00:00'); + $vo = DateTimeRFC2822::fromDateTime($dt); + expect(fn() => $vo->toNull()) + ->toThrow(RFC2822DateTimeTypeException::class, 'DateTimeRFC2822 type cannot be converted to null'); + }); + }); + describe('tryFromMixed', function () { it('returns instance for valid mixed inputs', function (mixed $input, string $expected) { $result = DateTimeRFC2822::tryFromMixed($input); From ab27eb8e2e5772d88a765794014b2a432b3086b8 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:28:02 +0200 Subject: [PATCH 75/83] Add null handling to DateTimeRFC3339 and DateTimeRFC3339Extended: fromNull and toNull throw DateTimeTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `DateTimeTypeException`. Updated docblocks accordingly and added unit tests to verify the exception behavior. --- src/DateTime/DateTimeRFC3339.php | 16 ++++++++++++++++ src/DateTime/DateTimeRFC3339Extended.php | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/DateTime/DateTimeRFC3339.php b/src/DateTime/DateTimeRFC3339.php index c8bc72e7..ea9ea51d 100755 --- a/src/DateTime/DateTimeRFC3339.php +++ b/src/DateTime/DateTimeRFC3339.php @@ -58,6 +58,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws DateTimeTypeException + */ + public static function fromNull(null $value): never + { + throw new DateTimeTypeException('DateTimeRFC3339 type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -107,6 +115,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws DateTimeTypeException + */ + public static function toNull(): never + { + throw new DateTimeTypeException('DateTimeRFC3339 type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/src/DateTime/DateTimeRFC3339Extended.php b/src/DateTime/DateTimeRFC3339Extended.php index b72831cf..ae396c4f 100755 --- a/src/DateTime/DateTimeRFC3339Extended.php +++ b/src/DateTime/DateTimeRFC3339Extended.php @@ -59,6 +59,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws DateTimeTypeException + */ + public static function fromNull(null $value): never + { + throw new DateTimeTypeException('DateTimeRFC3339Extended type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -108,6 +116,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws DateTimeTypeException + */ + public static function toNull(): never + { + throw new DateTimeTypeException('DateTimeRFC3339Extended type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); From 4a95795b5e8d5d26d25e9c3dfa19fe5f10476f51 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:28:09 +0200 Subject: [PATCH 76/83] Add null handling unit tests for DateTimeRFC3339 and DateTimeRFC3339Extended Add describe blocks that verify `fromNull` and `toNull` throw `DateTimeTypeException` for both DateTimeRFC3339 and DateTimeRFC3339Extended classes. --- .../DateTime/DateTimeRFC3339ExtendedTest.php | 27 +++++++++++++++++++ tests/Unit/DateTime/DateTimeRFC3339Test.php | 13 +++++++++ 2 files changed, 40 insertions(+) diff --git a/tests/Unit/DateTime/DateTimeRFC3339ExtendedTest.php b/tests/Unit/DateTime/DateTimeRFC3339ExtendedTest.php index bbc7982a..2f1c8038 100755 --- a/tests/Unit/DateTime/DateTimeRFC3339ExtendedTest.php +++ b/tests/Unit/DateTime/DateTimeRFC3339ExtendedTest.php @@ -78,6 +78,20 @@ }); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeRFC3339Extended::fromNull(null)) + ->toThrow(DateTimeTypeException::class, 'DateTimeRFC3339Extended type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $dt = new DateTimeImmutable('2025-01-02T03:04:05+00:00'); + $vo = DateTimeRFC3339Extended::fromDateTime($dt); + expect(fn() => $vo->toNull()) + ->toThrow(DateTimeTypeException::class, 'DateTimeRFC3339Extended type cannot be converted to null'); + }); + }); + describe('tryFromString', function () { it('returns instance or default value', function (string $input, string $tz, bool $isSuccess) { $result = DateTimeRFC3339Extended::tryFromString($input, $tz); @@ -240,5 +254,18 @@ public function __toString(): string expect($vo->isTypeOf())->toBeFalse(); }); }); + + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeRFC3339Extended::fromNull(null)) + ->toThrow(DateTimeTypeException::class, 'DateTimeRFC3339Extended type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $vo = DateTimeRFC3339Extended::fromString('2025-01-02T03:04:05.000+00:00'); + expect(fn() => $vo::toNull()) + ->toThrow(DateTimeTypeException::class, 'DateTimeRFC3339Extended type cannot be converted to null'); + }); + }); }); }); diff --git a/tests/Unit/DateTime/DateTimeRFC3339Test.php b/tests/Unit/DateTime/DateTimeRFC3339Test.php index f568e98f..d0906be2 100755 --- a/tests/Unit/DateTime/DateTimeRFC3339Test.php +++ b/tests/Unit/DateTime/DateTimeRFC3339Test.php @@ -78,6 +78,19 @@ }); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeRFC3339::fromNull(null)) + ->toThrow(DateTimeTypeException::class, 'DateTimeRFC3339 type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $vo = DateTimeRFC3339::fromString('2025-01-02T03:04:05+00:00'); + expect(fn() => $vo::toNull()) + ->toThrow(DateTimeTypeException::class, 'DateTimeRFC3339 type cannot be converted to null'); + }); + }); + describe('tryFromString', function () { it('returns instance or default value', function (string $input, string $tz, bool $isSuccess) { $result = DateTimeRFC3339::tryFromString($input, $tz); From 3b37ec2df7766f9cd017a4844dfa0bc9e872def2 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:28:14 +0200 Subject: [PATCH 77/83] Add null handling to DateTimeSql: fromNull and toNull throw DateTimeTypeException Implemented static `fromNull` and static `toNull` methods that always throw `DateTimeTypeException`. Updated docblocks and added unit tests to verify the exception behavior. --- src/DateTime/MariaDb/DateTimeSql.php | 16 ++++++++++++++++ tests/Unit/DateTime/MariaDb/DateTimeSqlTest.php | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/DateTime/MariaDb/DateTimeSql.php b/src/DateTime/MariaDb/DateTimeSql.php index 3885abb6..8d5f1939 100755 --- a/src/DateTime/MariaDb/DateTimeSql.php +++ b/src/DateTime/MariaDb/DateTimeSql.php @@ -56,6 +56,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws DateTimeTypeException + */ + public static function fromNull(null $value): never + { + throw new DateTimeTypeException('DateTimeSql type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -105,6 +113,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws DateTimeTypeException + */ + public static function toNull(): never + { + throw new DateTimeTypeException('DateTimeSql type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/MariaDb/DateTimeSqlTest.php b/tests/Unit/DateTime/MariaDb/DateTimeSqlTest.php index 2015dec6..54f88d1b 100755 --- a/tests/Unit/DateTime/MariaDb/DateTimeSqlTest.php +++ b/tests/Unit/DateTime/MariaDb/DateTimeSqlTest.php @@ -122,6 +122,19 @@ public function __toString(): string }); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeSql::fromNull(null)) + ->toThrow(DateTimeTypeException::class, 'DateTimeSql type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $vo = DateTimeSql::fromString('2025-01-02 03:04:05'); + expect(fn() => $vo::toNull()) + ->toThrow(DateTimeTypeException::class, 'DateTimeSql type cannot be converted to null'); + }); + }); + describe('getFormat', function () { it('returns SQL format', function () { expect(DateTimeSql::getFormat())->toBe('Y-m-d H:i:s'); From 612fc5e5d1110d5b8e69c5a672569ab490b81455 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:28:24 +0200 Subject: [PATCH 78/83] Add abstract null handling methods to DateTimeTypeAbstract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare `fromNull` and `toNull` as abstract never‑returning methods that throw `DateTimeTypeException` and add unit tests confirming the exception behavior. --- src/Base/Primitive/DateTime/DateTimeTypeAbstract.php | 4 ++++ .../Primitive/DateTime/DateTimeTypeAbstractTest.php | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/Base/Primitive/DateTime/DateTimeTypeAbstract.php b/src/Base/Primitive/DateTime/DateTimeTypeAbstract.php index b98617ac..e15e2962 100755 --- a/src/Base/Primitive/DateTime/DateTimeTypeAbstract.php +++ b/src/Base/Primitive/DateTime/DateTimeTypeAbstract.php @@ -37,6 +37,8 @@ { abstract public static function fromDateTime(DateTimeImmutable $value): static; + abstract public static function fromNull(null $value): never; + /** * @param non-empty-string $timezone */ @@ -49,6 +51,8 @@ abstract public static function getFormat(): string; abstract public function isTypeOf(string ...$classNames): bool; + abstract public static function toNull(): never; + abstract public function toString(): string; /** diff --git a/tests/Unit/Base/Primitive/DateTime/DateTimeTypeAbstractTest.php b/tests/Unit/Base/Primitive/DateTime/DateTimeTypeAbstractTest.php index 4d979859..f2956775 100755 --- a/tests/Unit/Base/Primitive/DateTime/DateTimeTypeAbstractTest.php +++ b/tests/Unit/Base/Primitive/DateTime/DateTimeTypeAbstractTest.php @@ -44,6 +44,11 @@ public static function fromDateTime(DateTimeImmutable $value): static return new self($value); } + public static function fromNull(null $value): never + { + throw new DateTimeTypeException('DateTimeType type cannot be created from null'); + } + public static function fromString(string $value, string $timezone = self::DEFAULT_ZONE): static { return new self( @@ -103,6 +108,11 @@ public static function testStringToDateTimeZone(string $timezone): DateTimeZone return static::stringToDateTimeZone($timezone); } + public static function toNull(): never + { + throw new DateTimeTypeException('DateTimeType type cannot be converted to null'); + } + public function toString(): string { return $this->dt->format(static::FORMAT); From f209d7e7d70d03bdc629e25ce332cb81dec22679 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:28:40 +0200 Subject: [PATCH 79/83] Add null handling to DateTimeW3C: fromNull and toNull throw DateTimeTypeException Implemented static `fromNull` and `toNull` methods that always throw `DateTimeTypeException` and added unit tests confirming the exception behavior. --- src/DateTime/DateTimeW3C.php | 16 ++++++++++++++++ tests/Unit/DateTime/DateTimeW3CTest.php | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/DateTime/DateTimeW3C.php b/src/DateTime/DateTimeW3C.php index 3c0020ac..9c8ed7be 100755 --- a/src/DateTime/DateTimeW3C.php +++ b/src/DateTime/DateTimeW3C.php @@ -58,6 +58,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws DateTimeTypeException + */ + public static function fromNull(null $value): never + { + throw new DateTimeTypeException('DateTimeW3C type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -109,6 +117,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws DateTimeTypeException + */ + public static function toNull(): never + { + throw new DateTimeTypeException('DateTimeW3C type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/DateTimeW3CTest.php b/tests/Unit/DateTime/DateTimeW3CTest.php index 548d51f4..8f4169b0 100755 --- a/tests/Unit/DateTime/DateTimeW3CTest.php +++ b/tests/Unit/DateTime/DateTimeW3CTest.php @@ -127,6 +127,19 @@ public function __toString(): string ]); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => DateTimeW3C::fromNull(null)) + ->toThrow(DateTimeTypeException::class, 'DateTimeW3C type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $vo = DateTimeW3C::fromString('2025-01-02T03:04:05+00:00'); + expect(fn() => $vo::toNull()) + ->toThrow(DateTimeTypeException::class, 'DateTimeW3C type cannot be converted to null'); + }); + }); + describe('getFormat', function () { it('returns RFC3339 format', function () { expect(DateTimeW3C::getFormat())->toBe(\DATE_RFC3339); From f0710320679f7fd25cd5780633123023de8023d5 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:28:51 +0200 Subject: [PATCH 80/83] Add null handling to TimeIso8601: fromNull and toNull throw Iso8601TimeTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `Iso8601TimeTypeException` and added unit tests to verify the exception behavior. --- src/DateTime/TimeIso8601.php | 16 ++++++++++++++++ tests/Unit/DateTime/TimeIso8601Test.php | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/DateTime/TimeIso8601.php b/src/DateTime/TimeIso8601.php index 56dfcb78..5e2cef38 100755 --- a/src/DateTime/TimeIso8601.php +++ b/src/DateTime/TimeIso8601.php @@ -54,6 +54,14 @@ public static function fromDateTime(DateTimeImmutable $value): static return new static($value); } + /** + * @throws Iso8601TimeTypeException + */ + public static function fromNull(null $value): never + { + throw new Iso8601TimeTypeException('TimeIso8601 type cannot be created from null'); + } + /** * @param non-empty-string $timezone * @@ -107,6 +115,14 @@ public function jsonSerialize(): string return $this->toString(); } + /** + * @throws Iso8601TimeTypeException + */ + public static function toNull(): never + { + throw new Iso8601TimeTypeException('TimeIso8601 type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/TimeIso8601Test.php b/tests/Unit/DateTime/TimeIso8601Test.php index bd8e0b7b..7acdfb14 100755 --- a/tests/Unit/DateTime/TimeIso8601Test.php +++ b/tests/Unit/DateTime/TimeIso8601Test.php @@ -65,6 +65,19 @@ public function __toString(): string ]); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => TimeIso8601::fromNull(null)) + ->toThrow(Iso8601TimeTypeException::class, 'TimeIso8601 type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $vo = TimeIso8601::fromString('15:52:01'); + expect(fn() => $vo::toNull()) + ->toThrow(Iso8601TimeTypeException::class, 'TimeIso8601 type cannot be converted to null'); + }); + }); + describe('tryFromString', function () { it('returns instance or default value', function (string $input, bool $isSuccess) { $result = TimeIso8601::tryFromString($input); From 3bf19317d81dff1741346befdf9c615c574a04f3 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:29:10 +0200 Subject: [PATCH 81/83] Add null handling to TimestampMicroseconds: fromNull and toNull throw TimestampTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `TimestampTypeException` and added unit tests to verify the exception behavior. --- src/DateTime/Timestamp/TimestampMicroseconds.php | 16 ++++++++++++++++ .../Timestamp/TimestampMicrosecondsTest.php | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/DateTime/Timestamp/TimestampMicroseconds.php b/src/DateTime/Timestamp/TimestampMicroseconds.php index 4675e94d..722ca6b8 100755 --- a/src/DateTime/Timestamp/TimestampMicroseconds.php +++ b/src/DateTime/Timestamp/TimestampMicroseconds.php @@ -78,6 +78,14 @@ public static function fromInt(int $value, string $timezone = self::DEFAULT_ZONE return static::fromString((string) $value, $timezone); } + /** + * @throws TimestampTypeException + */ + public static function fromNull(null $value): never + { + throw new TimestampTypeException('TimestampMicroseconds type cannot be created from null'); + } + /** * Parse from a numeric Unix timestamp string (microseconds). * @@ -150,6 +158,14 @@ public function toInt(): int return (int) $this->toString(); } + /** + * @throws TimestampTypeException + */ + public static function toNull(): never + { + throw new TimestampTypeException('TimestampMicroseconds type cannot be converted to null'); + } + /** * Render as microseconds since epoch, e.g. "1732445696123456". */ diff --git a/tests/Unit/DateTime/Timestamp/TimestampMicrosecondsTest.php b/tests/Unit/DateTime/Timestamp/TimestampMicrosecondsTest.php index 9bc174c7..f40d6432 100755 --- a/tests/Unit/DateTime/Timestamp/TimestampMicrosecondsTest.php +++ b/tests/Unit/DateTime/Timestamp/TimestampMicrosecondsTest.php @@ -70,6 +70,20 @@ ]); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => TimestampMicroseconds::fromNull(null)) + ->toThrow(TimestampTypeException::class, 'TimestampMicroseconds type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $dt = new DateTimeImmutable('2025-01-02 03:04:05'); + $vo = TimestampMicroseconds::fromDateTime($dt); + expect(fn() => $vo->toNull()) + ->toThrow(TimestampTypeException::class, 'TimestampMicroseconds type cannot be converted to null'); + }); + }); + describe('tryFromString', function () { it('returns instance or default value', function (string $input, bool $isSuccess) { $result = TimestampMicroseconds::tryFromString($input); From be4b2f829e67d26ddb55e12ca92427baf62696f1 Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:29:17 +0200 Subject: [PATCH 82/83] Add null handling to TimestampMilliseconds: fromNull and toNull throw TimestampTypeException Implemented static `fromNull` and instance `toNull` methods that always throw `TimestampTypeException` and added unit tests to verify the exception behavior. --- src/DateTime/Timestamp/TimestampMilliseconds.php | 16 ++++++++++++++++ .../Timestamp/TimestampMillisecondsTest.php | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/DateTime/Timestamp/TimestampMilliseconds.php b/src/DateTime/Timestamp/TimestampMilliseconds.php index ff7ba9f9..6cc6daf9 100755 --- a/src/DateTime/Timestamp/TimestampMilliseconds.php +++ b/src/DateTime/Timestamp/TimestampMilliseconds.php @@ -78,6 +78,14 @@ public static function fromInt(int $value, string $timezone = self::DEFAULT_ZONE return static::fromString((string) $value, $timezone); } + /** + * @throws TimestampTypeException + */ + public static function fromNull(null $value): never + { + throw new TimestampTypeException('TimestampMilliseconds type cannot be created from null'); + } + /** * Parse from a numeric Unix timestamp string (milliseconds). * @@ -150,6 +158,14 @@ public function toInt(): int return (int) $this->toString(); } + /** + * @throws TimestampTypeException + */ + public static function toNull(): never + { + throw new TimestampTypeException('TimestampMilliseconds type cannot be converted to null'); + } + /** * Render as milliseconds since epoch, e.g. "1732445696123". */ diff --git a/tests/Unit/DateTime/Timestamp/TimestampMillisecondsTest.php b/tests/Unit/DateTime/Timestamp/TimestampMillisecondsTest.php index d8d029a8..6db105f5 100755 --- a/tests/Unit/DateTime/Timestamp/TimestampMillisecondsTest.php +++ b/tests/Unit/DateTime/Timestamp/TimestampMillisecondsTest.php @@ -91,6 +91,19 @@ ]); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => TimestampMilliseconds::fromNull(null)) + ->toThrow(TimestampTypeException::class, 'TimestampMilliseconds type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $vo = TimestampMilliseconds::fromString('1732445696123'); + expect(fn() => $vo::toNull()) + ->toThrow(TimestampTypeException::class, 'TimestampMilliseconds type cannot be converted to null'); + }); + }); + describe('tryFromString', function () { it('returns instance or default value', function (string $input, bool $isSuccess) { $result = TimestampMilliseconds::tryFromString($input); From 09c2a1708acc81be5917952885f0da05adb3a7ee Mon Sep 17 00:00:00 2001 From: GeorgII Date: Sat, 11 Apr 2026 19:29:29 +0200 Subject: [PATCH 83/83] Add null handling to TimestampSeconds: fromNull and toNull throw `TimestampTypeException` Implemented static `fromNull` and instance `toNull` methods that always throw `TimestampTypeException`; added unit tests confirming the exception behavior. --- src/DateTime/Timestamp/TimestampSeconds.php | 16 ++++++++++++++++ .../DateTime/Timestamp/TimestampSecondsTest.php | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/DateTime/Timestamp/TimestampSeconds.php b/src/DateTime/Timestamp/TimestampSeconds.php index 4ebe4155..7d11c959 100755 --- a/src/DateTime/Timestamp/TimestampSeconds.php +++ b/src/DateTime/Timestamp/TimestampSeconds.php @@ -75,6 +75,14 @@ public static function fromInt(int $value, string $timezone = self::DEFAULT_ZONE return static::fromString((string) $value, $timezone); } + /** + * @throws TimestampTypeException + */ + public static function fromNull(null $value): never + { + throw new TimestampTypeException('TimestampSeconds type cannot be created from null'); + } + /** * Parse from a numeric Unix timestamp string (seconds). * @@ -137,6 +145,14 @@ public function toInt(): int return (int) $this->toString(); } + /** + * @throws TimestampTypeException + */ + public static function toNull(): never + { + throw new TimestampTypeException('TimestampSeconds type cannot be converted to null'); + } + public function toString(): string { return $this->value()->format(static::FORMAT); diff --git a/tests/Unit/DateTime/Timestamp/TimestampSecondsTest.php b/tests/Unit/DateTime/Timestamp/TimestampSecondsTest.php index 8ea4bd64..9e49a18e 100755 --- a/tests/Unit/DateTime/Timestamp/TimestampSecondsTest.php +++ b/tests/Unit/DateTime/Timestamp/TimestampSecondsTest.php @@ -103,6 +103,19 @@ }); }); + describe('Null checks', function () { + it('fromNull throws exception', function () { + expect(fn() => TimestampSeconds::fromNull(null)) + ->toThrow(TimestampTypeException::class, 'TimestampSeconds type cannot be created from null'); + }); + + it('toNull throws exception', function () { + $vo = TimestampSeconds::fromString('1735787045'); + expect(fn() => $vo::toNull()) + ->toThrow(TimestampTypeException::class, 'TimestampSeconds type cannot be converted to null'); + }); + }); + describe('tryFromMixed', function () { it('returns instance for valid mixed inputs', function (mixed $input, string $expected) { $result = TimestampSeconds::tryFromMixed($input);