Skip to content

Commit

Permalink
Add new validation rules for schema files and implement error handlin…
Browse files Browse the repository at this point in the history
…g for invalid schema data. Add tests to verify the behavior.
  • Loading branch information
Denis Smet committed Mar 10, 2024
1 parent 61a92e7 commit 2d6ffef
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 8 deletions.
5 changes: 2 additions & 3 deletions src/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ public function __construct(null|array|string $csvSchemaFilenameOrArray = null)
} else {
throw new \InvalidArgumentException("Unsupported file extension: {$fileExtension}");
}
} else {
$this->filename = null;
$this->data = new Data();
} elseif (\is_string($csvSchemaFilenameOrArray)) {
throw new \InvalidArgumentException("Invalid schema data: {$csvSchemaFilenameOrArray}");
}

$this->columns = $this->prepareColumns();
Expand Down
52 changes: 47 additions & 5 deletions tests/Blueprint/RulesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ public function testIsBool(): void
'"is_bool" at line 0, column "prop". Value "1" is not allowed. Allowed values: ["true", "false"].',
(string)$rule->validate('1'),
);

$rule = new IsBool('prop', false);
isSame(null, $rule->validate('1'));
}

public function testIsDomain(): void
Expand All @@ -139,12 +142,15 @@ public function testIsDomain(): void
isSame(null, $rule->validate('sub-sub-example.qwerty'));
isSame(
'"is_domain" at line 0, column "prop". Value "example" is not a valid domain.',
(string)(string)$rule->validate('example'),
(string)$rule->validate('example'),
);
isSame(
'"is_domain" at line 0, column "prop". Value "" is not a valid domain.',
(string)$rule->validate(''),
);

$rule = new IsDomain('prop', false);
isSame(null, $rule->validate('example'));
}

public function testIsEmail(): void
Expand All @@ -154,8 +160,11 @@ public function testIsEmail(): void
isSame(null, $rule->validate('[email protected]'));
isSame(
'"is_email" at line 0, column "prop". Value "user:[email protected]" is not a valid email.',
(string)(string)$rule->validate('user:[email protected]'),
(string)$rule->validate('user:[email protected]'),
);

$rule = new IsEmail('prop', false);
isSame(null, $rule->validate('user:[email protected]'));
}

public function testIsFloat(): void
Expand All @@ -179,6 +188,9 @@ public function testIsFloat(): void
'"is_float" at line 0, column "prop". Value " 1" is not a float number.',
(string)$rule->validate(' 1'),
);

$rule = new IsFloat('prop', false);
isSame(null, $rule->validate(' 1'));
}

public function testIsInt(): void
Expand All @@ -195,7 +207,7 @@ public function testIsInt(): void
);
isSame(
'"is_int" at line 0, column "prop". Value "1.1" is not an integer.',
(string)(string)$rule->validate('1.1'),
(string)$rule->validate('1.1'),
);
isSame(
'"is_int" at line 0, column "prop". Value "1.0" is not an integer.',
Expand All @@ -207,12 +219,15 @@ public function testIsInt(): void
);
isSame(
'"is_int" at line 0, column "prop". Value " 1" is not an integer.',
(string)(string)$rule->validate(' 1'),
(string)$rule->validate(' 1'),
);
isSame(
'"is_int" at line 0, column "prop". Value "1 " is not an integer.',
(string)(string)$rule->validate('1 '),
(string)$rule->validate('1 '),
);

$rule = new IsInt('prop', false);
isSame(null, $rule->validate(' 1'));
}

public function testIsIp(): void
Expand Down Expand Up @@ -244,6 +259,9 @@ public function testIsLatitude(): void
'"is_latitude" at line 0, column "prop". Value "90.1.1.1.1" is not a float number.',
(string)$rule->validate('90.1.1.1.1'),
);

$rule = new IsLatitude('prop', false);
isSame(null, $rule->validate('90.1.1.1.1'));
}

public function testIsLongitude(): void
Expand All @@ -269,6 +287,9 @@ public function testIsLongitude(): void
'"is_longitude" at line 0, column "prop". Value "1.0.0.0" is not a float number.',
(string)$rule->validate('1.0.0.0'),
);

$rule = new IsLongitude('prop', false);
isSame(null, $rule->validate('1.0.0.0'));
}

public function testIsUrl(): void
Expand All @@ -285,6 +306,9 @@ public function testIsUrl(): void
'"is_url" at line 0, column "prop". Value "//example.com" is not a valid URL.',
(string)$rule->validate('//example.com'),
);

$rule = new IsUrl('prop', false);
isSame(null, $rule->validate('//example.com'));
}

public function testMin(): void
Expand Down Expand Up @@ -436,6 +460,9 @@ public function testNotEmpty(): void
'"not_empty" at line 0, column "prop". Value is empty.',
(string)$rule->validate(null),
);

$rule = new NotEmpty('prop', false);
isSame(null, $rule->validate(null));
}

public function testOnlyCapitalize(): void
Expand All @@ -454,6 +481,9 @@ public function testOnlyCapitalize(): void
'"only_capitalize" at line 0, column "prop". Value "qwe Rty" should be in capitalize.',
(string)$rule->validate('qwe Rty'),
);

$rule = new OnlyCapitalize('prop', false);
isSame(null, $rule->validate('qwerty'));
}

public function testOnlyLowercase(): void
Expand All @@ -472,6 +502,9 @@ public function testOnlyLowercase(): void
'"only_lowercase" at line 0, column "prop". Value "qwe Rty" should be in lowercase.',
(string)$rule->validate('qwe Rty'),
);

$rule = new OnlyLowercase('prop', false);
isSame(null, $rule->validate('Qwerty'));
}

public function testOnlyUppercase(): void
Expand All @@ -489,6 +522,9 @@ public function testOnlyUppercase(): void
'"only_uppercase" at line 0, column "prop". Value "qwe Rty" is not uppercase.',
(string)$rule->validate('qwe Rty'),
);

$rule = new OnlyUppercase('prop', false);
isSame(null, $rule->validate('Qwerty'));
}

public function testPrecision(): void
Expand Down Expand Up @@ -590,6 +626,9 @@ public function testUsaMarketName(): void
'Market name must have format "New York, NY".',
(string)$rule->validate(', ST'),
);

$rule = new UsaMarketName('prop', false);
isSame(null, $rule->validate(', ST'));
}

public function testIsUuid4(): void
Expand All @@ -600,5 +639,8 @@ public function testIsUuid4(): void
'"is_uuid4" at line 0, column "prop". Value is not a valid UUID v4.',
(string)$rule->validate('123'),
);

$rule = new IsUuid4('prop', false);
isSame(null, $rule->validate('123'));
}
}
38 changes: 38 additions & 0 deletions tests/Blueprint/ValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ final class ValidatorTest extends PHPUnit
private const SCHEMA_SIMPLE_HEADER = PROJECT_TESTS . '/schemas/simple_header.yml';
private const SCHEMA_SIMPLE_NO_HEADER = PROJECT_TESTS . '/schemas/simple_no_header.yml';

private const SCHEMA_SIMPLE_HEADER_PHP = PROJECT_TESTS . '/schemas/simple_header.php';
private const SCHEMA_SIMPLE_HEADER_JSON = PROJECT_TESTS . '/schemas/simple_header.json';

protected function setUp(): void
{
\date_default_timezone_set('UTC');
Expand All @@ -59,6 +62,30 @@ public function testValidWithoutHeader(): void
isSame('', (string)$csv->validate());
}

public function testInvalidSchemaFile(): void
{
$this->expectExceptionMessage('Invalid schema data: undefined_file_name.yml');
$csv = new CsvFile(self::CSV_SIMPLE_HEADER, 'undefined_file_name.yml');
}

public function testSchemaAsPhpFile(): void
{
$csv = new CsvFile(self::CSV_SIMPLE_HEADER, self::SCHEMA_SIMPLE_HEADER_PHP);
isSame(
'"min" at line 2, column "0:seq". Value "1" is less than "2".',
(string)$csv->validate(),
);
}

public function testSchemaAsJsonFile(): void
{
$csv = new CsvFile(self::CSV_SIMPLE_HEADER, self::SCHEMA_SIMPLE_HEADER_JSON);
isSame(
'"min" at line 2, column "0:seq". Value "1" is less than "2".',
(string)$csv->validate(),
);
}

public function testNotEmptyMessage(): void
{
$csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'not_empty', true));
Expand Down Expand Up @@ -375,6 +402,17 @@ public function testQuickStop(): void
isSame(100, $csv->validate()->count());
}

public function testErrorToArray(): void
{
$csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('yn', 'is_email', true));
isSame([
'ruleCode' => 'is_email',
'message' => 'Value "N" is not a valid email',
'columnName' => '0:yn',
'line' => 2,
], $csv->validate(true)->get(0)->toArray());
}

public function testRenderText(): void
{
$csv = new CsvFile(self::CSV_SIMPLE_HEADER, $this->getRule('seq', 'min', 3));
Expand Down
12 changes: 12 additions & 0 deletions tests/schemas/simple_header.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"columns" : [
{
"name" : "seq",
"rules" : {"not_empty" : true, "min" : 2}
},
{
"name" : "bool",
"rules" : {"not_empty" : true}
}
]
}
28 changes: 28 additions & 0 deletions tests/schemas/simple_header.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?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);

return [
'columns' => [
[
'name' => 'seq',
'rules' => ['not_empty' => true, 'min' => 2],
],
[
'name' => 'bool',
'rules' => ['not_empty' => true],
],
],
];

0 comments on commit 2d6ffef

Please sign in to comment.