Skip to content

Commit

Permalink
feat(validation): Handle float with comma in NumberRule and improve o…
Browse files Browse the repository at this point in the history
…verflow detection
  • Loading branch information
pionl committed Oct 11, 2022
1 parent 92e20df commit 9f1eb6e
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/Validation/Rules/NumberRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ class NumberRule implements Rule
{
public function passes($attribute, $value): bool
{
if (is_float($value)) {
return $value <= PHP_FLOAT_MAX && $value >= PHP_FLOAT_MIN;
if (is_string($value)) {
$value = str_replace(',', '.', $value);
}

if ((is_float($value)) || (is_numeric($value) && str_contains((string) $value, '.'))) {
$floatVal = (float) $value;
$stringVal = (string) $floatVal;
return is_finite($floatVal) && $stringVal === (string) $value;
} elseif (is_numeric($value)) {
return $value <= PHP_INT_MAX && $value >= PHP_INT_MIN;
$intVal = (int) $value;
return $intVal !== PHP_INT_MAX && $intVal !== PHP_INT_MIN;
}

return false;
Expand Down
47 changes: 47 additions & 0 deletions tests/Unit/Validation/Rules/AbstractRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Unit\Validation\Rules;

use Illuminate\Contracts\Validation\Rule;
use PHPUnit\Framework\TestCase;

abstract class AbstractRuleTest extends TestCase
{
/**
* @dataProvider testPassesData
*/
public function testPasses(RuleExpectation $expectation): void
{
$rule = $this->createRule();

$this->assertEquals($expectation->expectedIsValid, $rule->passes('test', $expectation->value));
}

public function testMessage(): void
{
$rule = $this->createRule();

$this->assertEquals($this->getExpectedMessage(), str_replace(':attribute', 'test', $rule->message()));
}

abstract public function createRule(): Rule;

/**
* @return array<RuleExpectation>
*/
abstract protected function testData(): array;

abstract protected function getExpectedMessage(): string;

protected function testPassesData(): array
{
$data = [];
foreach ($this->testData() as $index => $entity) {
$data[$index . ' with value: ' . $entity->value] = [$entity];
}

return $data;
}
}
44 changes: 44 additions & 0 deletions tests/Unit/Validation/Rules/NumberRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Unit\Validation\Rules;

use Illuminate\Contracts\Validation\Rule;
use LaraStrict\Validation\Rules\NumberRule;

class NumberRuleTest extends AbstractRuleTest
{
public function createRule(): Rule
{
return new NumberRule();
}

protected function testData(): array
{
return [
new RuleExpectation('test', false),
new RuleExpectation('234', true),
new RuleExpectation(234, true),
new RuleExpectation('-234', true),
new RuleExpectation(-245, true),
new RuleExpectation('245.5', true),
new RuleExpectation('-245.5', true),
new RuleExpectation(245.50, true),
new RuleExpectation(-245.50, true),
new RuleExpectation('9223372036854775807', false),
new RuleExpectation('9223372036854775807.5', false),
new RuleExpectation('922337203685477580703434355.5', false),
new RuleExpectation('-922337203685477580703434355.5', false),
new RuleExpectation('9223372036854775807', false),
new RuleExpectation('9223372036854775807.5', false),
new RuleExpectation('9223372036854775.5', false),
new RuleExpectation('-922337203685477.5', false),
];
}

protected function getExpectedMessage(): string
{
return 'Given test is not a valid number or it exceeds int/float limits.';
}
}
14 changes: 14 additions & 0 deletions tests/Unit/Validation/Rules/RuleExpectation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Unit\Validation\Rules;

class RuleExpectation
{
public function __construct(
public mixed $value,
public bool $expectedIsValid,
) {
}
}

0 comments on commit 9f1eb6e

Please sign in to comment.