Skip to content

Commit dcc2401

Browse files
authored
fix(validation): more lenient scalar validation (#1127)
1 parent e34654a commit dcc2401

File tree

8 files changed

+104
-4
lines changed

8 files changed

+104
-4
lines changed

src/Tempest/Validation/src/Rules/IsFloat.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ public function isValid(mixed $value): bool
2020
return true;
2121
}
2222

23-
return is_float($value);
23+
if ($value === null || $value === false || $value === '' || $value === []) {
24+
return false;
25+
}
26+
27+
// @mago-expect strictness/require-identity-comparison
28+
return is_float($value) || floatval($value) == $value;
2429
}
2530

2631
public function message(): string

src/Tempest/Validation/src/Rules/IsInteger.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ public function isValid(mixed $value): bool
2020
return true;
2121
}
2222

23-
return is_int($value);
23+
if ($value === null || $value === false || $value === '' || $value === []) {
24+
return false;
25+
}
26+
27+
// @mago-expect strictness/require-identity-comparison
28+
return is_int($value) || intval($value) == $value;
2429
}
2530

2631
public function message(): string

src/Tempest/Validation/src/Validator.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use Tempest\Validation\Rules\IsInteger;
1414
use Tempest\Validation\Rules\IsString;
1515
use Tempest\Validation\Rules\NotNull;
16-
use TypeError;
1716

1817
use function Tempest\Support\arr;
1918

src/Tempest/Validation/tests/Rules/BooleanTest.php renamed to src/Tempest/Validation/tests/Rules/IsBooleanTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/**
1111
* @internal
1212
*/
13-
final class BooleanTest extends TestCase
13+
final class IsBooleanTest extends TestCase
1414
{
1515
public function test_boolean(): void
1616
{
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Validation\Tests\Rules;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Tempest\Validation\Rules\IsFloat;
9+
10+
/**
11+
* @internal
12+
*/
13+
final class IsFloatTest extends TestCase
14+
{
15+
public function test_float(): void
16+
{
17+
$rule = new IsFloat();
18+
19+
$this->assertTrue($rule->isValid(1));
20+
$this->assertTrue($rule->isValid(0.1));
21+
$this->assertTrue($rule->isValid('0.1'));
22+
$this->assertFalse($rule->isValid('a'));
23+
$this->assertFalse($rule->isValid(''));
24+
$this->assertFalse($rule->isValid(null));
25+
$this->assertFalse($rule->isValid(false));
26+
$this->assertFalse($rule->isValid([]));
27+
}
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Validation\Tests\Rules;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Tempest\Validation\Rules\IsInteger;
9+
10+
/**
11+
* @internal
12+
*/
13+
final class IsIntegerTest extends TestCase
14+
{
15+
public function test_integer(): void
16+
{
17+
$rule = new IsInteger();
18+
19+
$this->assertTrue($rule->isValid(1));
20+
$this->assertTrue($rule->isValid('1'));
21+
$this->assertFalse($rule->isValid('a'));
22+
$this->assertFalse($rule->isValid(''));
23+
$this->assertFalse($rule->isValid(null));
24+
$this->assertFalse($rule->isValid(false));
25+
$this->assertFalse($rule->isValid([]));
26+
}
27+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Tests\Tempest\Integration\Route\Fixtures;
4+
5+
use Tempest\Router\IsRequest;
6+
use Tempest\Router\Request;
7+
8+
final class RequestWithTypedQueryParam implements Request
9+
{
10+
use IsRequest;
11+
12+
public string $stringParam;
13+
14+
public float $floatParam;
15+
16+
public bool $boolParam;
17+
18+
public int $intParam;
19+
}

tests/Integration/Route/RequestToObjectMapperTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Tests\Tempest\Fixtures\Modules\Books\Requests\CreateBookRequest;
1414
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;
1515
use Tests\Tempest\Integration\Route\Fixtures\RequestObjectA;
16+
use Tests\Tempest\Integration\Route\Fixtures\RequestWithTypedQueryParam;
1617

1718
use function Tempest\map;
1819
use function Tempest\Support\arr;
@@ -64,4 +65,20 @@ public function test_query_parameters_are_mapped_to_properties(): void
6465

6566
$this->assertSame('hello', $request->queryParam);
6667
}
68+
69+
public function test_query_params_with_types(): void
70+
{
71+
$request = map(new GenericRequest(
72+
method: Method::GET,
73+
uri: '/books?stringParam=a&intParam=1&floatParam=0.1&boolParam=1',
74+
body: ['title' => 'Timeline Taxi'],
75+
))->with(
76+
RequestToObjectMapper::class,
77+
)->to(RequestWithTypedQueryParam::class);
78+
79+
$this->assertSame(1, $request->intParam);
80+
$this->assertSame('a', $request->stringParam);
81+
$this->assertSame(true, $request->boolParam);
82+
$this->assertSame(0.1, $request->floatParam);
83+
}
6784
}

0 commit comments

Comments
 (0)