Skip to content

Commit

Permalink
Implement min and max precision rules
Browse files Browse the repository at this point in the history
Added new rules for minimum and maximum precision in the schema files and created corresponding validation logic in the PHP files. Updated test files to include tests for these new rules. Enhanced the precision functionality in the schema files and reflected these changes in the README for clarity.
  • Loading branch information
Denis Smet committed Mar 13, 2024
1 parent 5aa3e62 commit 436bb47
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 9 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,9 @@ columns:
# Decimal and integer numbers
min: 10 # Can be integer or float, negative and positive
max: 100.50 # Can be integer or float, negative and positive
precision: 2 # Strict(!) number of digits after the decimal point
precision: 3 # Strict(!) number of digits after the decimal point
min_precision: 2 # Min number of digits after the decimal point
max_precision: 4 # Max number of digits after the decimal point

# Dates
date_format: Y-m-d # See: https://www.php.net/manual/en/datetime.format.php
Expand Down Expand Up @@ -384,7 +386,9 @@ columns:
"only_capitalize" : true,
"min" : 10,
"max" : 100.5,
"precision" : 2,
"precision" : 3,
"min_precision" : 2,
"max_precision" : 4,
"date_format" : "Y-m-d",
"min_date" : "2000-01-02",
"max_date" : "+1 day",
Expand Down Expand Up @@ -449,7 +453,9 @@ return [
'only_capitalize' => true,
'min' => 10,
'max' => 100.5,
'precision' => 2,
'precision' => 3,
'min_precision' => 2,
'max_precision' => 4,
'date_format' => 'Y-m-d',
'min_date' => '2000-01-02',
'max_date' => '+1 day',
Expand Down
4 changes: 3 additions & 1 deletion schema-examples/full.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
"only_capitalize" : true,
"min" : 10,
"max" : 100.5,
"precision" : 2,
"precision" : 3,
"min_precision" : 2,
"max_precision" : 4,
"date_format" : "Y-m-d",
"min_date" : "2000-01-02",
"max_date" : "+1 day",
Expand Down
4 changes: 3 additions & 1 deletion schema-examples/full.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
'only_capitalize' => true,
'min' => 10,
'max' => 100.5,
'precision' => 2,
'precision' => 3,
'min_precision' => 2,
'max_precision' => 4,
'date_format' => 'Y-m-d',
'min_date' => '2000-01-02',
'max_date' => '+1 day',
Expand Down
4 changes: 3 additions & 1 deletion schema-examples/full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ columns:
# Decimal and integer numbers
min: 10 # Can be integer or float, negative and positive
max: 100.50 # Can be integer or float, negative and positive
precision: 2 # Strict(!) number of digits after the decimal point
precision: 3 # Strict(!) number of digits after the decimal point
min_precision: 2 # Min number of digits after the decimal point
max_precision: 4 # Max number of digits after the decimal point

# Dates
date_format: Y-m-d # See: https://www.php.net/manual/en/datetime.format.php
Expand Down
32 changes: 32 additions & 0 deletions src/Rules/MaxPrecision.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/**
* JBZoo Toolbox - Csv-Blueprint.
*
* This file is part of the JBZoo Toolbox project.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT
* @copyright Copyright (C) JBZoo.com, All rights reserved.
* @see https://github.com/JBZoo/Csv-Blueprint
*/

declare(strict_types=1);

namespace JBZoo\CsvBlueprint\Rules;

final class MaxPrecision extends Precision
{
public function validateRule(?string $cellValue): ?string
{
$valuePrecision = self::getFloatPrecision($cellValue);

if ($valuePrecision > $this->getOptionAsInt()) {
return "Value \"<c>{$cellValue}</c>\" has a precision of {$valuePrecision} " .
"but should have a max precision of <green>{$this->getOptionAsInt()}</green>";
}

return null;
}
}
32 changes: 32 additions & 0 deletions src/Rules/MinPrecision.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/**
* JBZoo Toolbox - Csv-Blueprint.
*
* This file is part of the JBZoo Toolbox project.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT
* @copyright Copyright (C) JBZoo.com, All rights reserved.
* @see https://github.com/JBZoo/Csv-Blueprint
*/

declare(strict_types=1);

namespace JBZoo\CsvBlueprint\Rules;

final class MinPrecision extends Precision
{
public function validateRule(?string $cellValue): ?string
{
$valuePrecision = self::getFloatPrecision($cellValue);

if ($valuePrecision < $this->getOptionAsInt()) {
return "Value \"<c>{$cellValue}</c>\" has a precision of {$valuePrecision} " .
"but should have a min precision of <green>{$this->getOptionAsInt()}</green>";
}

return null;
}
}
6 changes: 3 additions & 3 deletions src/Rules/Precision.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@

namespace JBZoo\CsvBlueprint\Rules;

final class Precision extends AbstarctRule
class Precision extends AbstarctRule
{
public function validateRule(?string $cellValue): ?string
{
$valuePrecision = self::getFloatPrecision($cellValue);

if ($this->getOptionAsInt() !== $valuePrecision) {
if ($valuePrecision !== $this->getOptionAsInt()) {
return "Value \"<c>{$cellValue}</c>\" has a precision of {$valuePrecision} " .
"but should have a precision of <green>{$this->getOptionAsInt()}</green>";
}

return null;
}

private static function getFloatPrecision(?string $cellValue): int
protected static function getFloatPrecision(?string $cellValue): int
{
$floatAsString = (string)$cellValue;
$dotPosition = \strpos($floatAsString, '.');
Expand Down
71 changes: 71 additions & 0 deletions tests/Blueprint/RulesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@
use JBZoo\CsvBlueprint\Rules\Max;
use JBZoo\CsvBlueprint\Rules\MaxDate;
use JBZoo\CsvBlueprint\Rules\MaxLength;
use JBZoo\CsvBlueprint\Rules\MaxPrecision;
use JBZoo\CsvBlueprint\Rules\Min;
use JBZoo\CsvBlueprint\Rules\MinDate;
use JBZoo\CsvBlueprint\Rules\MinLength;
use JBZoo\CsvBlueprint\Rules\MinPrecision;
use JBZoo\CsvBlueprint\Rules\NotEmpty;
use JBZoo\CsvBlueprint\Rules\OnlyCapitalize;
use JBZoo\CsvBlueprint\Rules\OnlyLowercase;
Expand Down Expand Up @@ -575,6 +577,75 @@ public function testPrecision(): void
);
}

public function testMinPrecision(): void
{
$rule = new MinPrecision('prop', 0);
isSame(null, $rule->validate('0'));
isSame(null, $rule->validate('0.0'));
isSame(null, $rule->validate('0.1'));
isSame(null, $rule->validate('-1.0'));
isSame(null, $rule->validate('10.01'));
isSame(null, $rule->validate('-10.0001'));

$rule = new MinPrecision('prop', 1);
isSame(null, $rule->validate('0.0'));
isSame(null, $rule->validate('10.0'));
isSame(null, $rule->validate('-10.0'));

isSame(
'"min_precision" at line 0, column "prop". ' .
'Value "2" has a precision of 0 but should have a min precision of 1.',
\strip_tags((string)$rule->validate('2')),
);

$rule = new MinPrecision('prop', 2);
isSame(null, $rule->validate('10.01'));
isSame(null, $rule->validate('-10.0001'));

isSame(
'"min_precision" at line 0, column "prop". ' .
'Value "2" has a precision of 0 but should have a min precision of 2.',
\strip_tags((string)$rule->validate('2')),
);

isSame(
'"min_precision" at line 0, column "prop". ' .
'Value "2.0" has a precision of 1 but should have a min precision of 2.',
\strip_tags((string)$rule->validate('2.0')),
);
}

public function testMaxPrecision(): void
{
$rule = new MaxPrecision('prop', 0);
isSame(null, $rule->validate('0'));
isSame(null, $rule->validate('10'));
isSame(null, $rule->validate('-10'));

isSame(
'"max_precision" at line 0, column "prop". ' .
'Value "2.0" has a precision of 1 but should have a max precision of 0.',
\strip_tags((string)$rule->validate('2.0')),
);

$rule = new MaxPrecision('prop', 1);
isSame(null, $rule->validate('0.0'));
isSame(null, $rule->validate('10.0'));
isSame(null, $rule->validate('-10.0'));

isSame(
'"max_precision" at line 0, column "prop". ' .
'Value "-2.003" has a precision of 3 but should have a max precision of 1.',
\strip_tags((string)$rule->validate('-2.003')),
);

isSame(
'"max_precision" at line 0, column "prop". ' .
'Value "2.00000" has a precision of 5 but should have a max precision of 1.',
\strip_tags((string)$rule->validate('2.00000')),
);
}

public function testRegex(): void
{
$rule = new Regex('prop', '/^a/');
Expand Down

0 comments on commit 436bb47

Please sign in to comment.