Skip to content

Commit c53df4f

Browse files
authored
Merge pull request #4 from GeorgII-web/tiny-int
Add `IntTiny` type for TINYINT range validation with tests and alias …
2 parents 06e9a5b + 5dcf6bb commit c53df4f

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

src/Integer/Alias/TinyInt.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Integer\Alias;
6+
7+
use PhpTypedValues\Integer\DB\IntTiny;
8+
9+
/**
10+
* Alias of IntTiny.
11+
*
12+
* Example "1"
13+
*
14+
* @psalm-immutable
15+
*/
16+
readonly class TinyInt extends IntTiny
17+
{
18+
}

src/Integer/DB/IntTiny.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Integer\DB;
6+
7+
use PhpTypedValues\Abstract\Integer\IntType;
8+
use PhpTypedValues\Exception\IntegerTypeException;
9+
10+
use function sprintf;
11+
12+
/**
13+
* Database tiny integer (TINYINT signed: -128..127).
14+
*
15+
* Example "-5"
16+
*
17+
* @psalm-immutable
18+
*/
19+
readonly class IntTiny extends IntType
20+
{
21+
/** @var int<-128, 127> */
22+
protected int $value;
23+
24+
/**
25+
* @throws IntegerTypeException
26+
*/
27+
public function __construct(int $value)
28+
{
29+
if ($value < -128 || $value > 127) {
30+
throw new IntegerTypeException(sprintf('Expected tiny integer in range -128..127, got "%d"', $value));
31+
}
32+
33+
$this->value = $value;
34+
}
35+
36+
/**
37+
* @throws IntegerTypeException
38+
*/
39+
public static function fromInt(int $value): static
40+
{
41+
return new static($value);
42+
}
43+
44+
/**
45+
* @throws IntegerTypeException
46+
*/
47+
public static function fromString(string $value): static
48+
{
49+
parent::assertIntegerString($value);
50+
51+
return new static((int) $value);
52+
}
53+
54+
/**
55+
* @return int<-128, 127>
56+
*/
57+
public function value(): int
58+
{
59+
return $this->value;
60+
}
61+
}

src/psalmTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
use PhpTypedValues\Integer\Alias\IntType;
2121
use PhpTypedValues\Integer\Alias\NonNegativeInt;
2222
use PhpTypedValues\Integer\Alias\PositiveInt;
23+
use PhpTypedValues\Integer\Alias\TinyInt;
24+
use PhpTypedValues\Integer\DB\IntTiny;
2325
use PhpTypedValues\Integer\IntegerNonNegative;
2426
use PhpTypedValues\Integer\IntegerPositive;
2527
use PhpTypedValues\Integer\IntegerStandard;
@@ -37,6 +39,11 @@
3739
testNonNegativeInt(IntegerNonNegative::fromInt(10)->value());
3840
testWeekDayInt(IntegerWeekDay::fromInt(7)->value());
3941

42+
// DB tinyint usage
43+
echo TinyInt::fromInt(-5)->toString() . \PHP_EOL;
44+
echo IntTiny::fromInt(-5)->toString() . \PHP_EOL;
45+
echo IntTiny::fromString('127')->toString() . \PHP_EOL;
46+
4047
echo NonNegativeInt::fromString('10')->toString() . \PHP_EOL;
4148
echo PositiveInt::fromString('10')->toString() . \PHP_EOL;
4249
echo IntegerStandard::fromString('10')->toString() . \PHP_EOL;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PhpTypedValues\Exception\IntegerTypeException;
6+
use PhpTypedValues\Integer\DB\IntTiny;
7+
8+
it('accepts values within signed tinyint range and preserves value', function (): void {
9+
$a = new IntTiny(-128);
10+
$b = IntTiny::fromInt(0);
11+
$c = IntTiny::fromInt(127);
12+
13+
expect($a->value())->toBe(-128)
14+
->and($a->toString())->toBe('-128')
15+
->and($b->value())->toBe(0)
16+
->and($b->toString())->toBe('0')
17+
->and($c->value())->toBe(127)
18+
->and($c->toString())->toBe('127');
19+
});
20+
21+
it('fromString parses integers and enforces tinyint bounds', function (): void {
22+
$v = IntTiny::fromString('-5');
23+
expect($v->value())->toBe(-5)
24+
->and($v->toString())->toBe('-5');
25+
});
26+
27+
it('throws when value is below -128', function (): void {
28+
expect(fn() => new IntTiny(-129))
29+
->toThrow(IntegerTypeException::class, 'Expected tiny integer in range -128..127, got "-129"');
30+
});
31+
32+
it('throws when value is above 127', function (): void {
33+
expect(fn() => IntTiny::fromInt(128))
34+
->toThrow(IntegerTypeException::class, 'Expected tiny integer in range -128..127, got "128"');
35+
});
36+
37+
it('fromString throws on non-integer strings (strict check)', function (): void {
38+
expect(fn() => IntTiny::fromString('12.3'))
39+
->toThrow(IntegerTypeException::class, 'String "12.3" has no valid integer value');
40+
});

0 commit comments

Comments
 (0)