diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f13169..65b07f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +VERSION 3.2.0 +------------- +Release date: 2020-04-02 + + - added ValidationBuilder + +VERSION 3.1.1 +------------- +Release date: 2020-03-27 + + - added "autoload-dev" to composer.json (thank you @ordago) + - added missing extension "ext-json" to composer.json (thank you @ordago) + VERSION 3.1.0 ------------- Release date: 2020-03-26 diff --git a/README.md b/README.md index 0e4e5cd..f06b3e5 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,18 @@ This component help you to validate array structure by: - ensuring a data structure with expected keys requirements - preventing structure pollution by allowing only a set of keys -This is specially useful when dealing with json data request, before using the data, you must validate his content so +This is especially useful when dealing with json data request, before using the data, you must validate his content so you can afterward check the value of those keys with your business logic without worrying about the type or presence of any key value. # How to use -##### 7 Usages +##### 8 Usages ## 1- General validation "à la carte" (stateless) ```php $validator = new Validator(); -if ($validator->expectExactlyKeys($array, $keys) === true) { +if ($validator->expectExactlyKeys($data, $keys) === true) { // ... } ``` @@ -47,7 +47,8 @@ $validation ->expectKeyToBeString('name'); if ($validation->hasErrors()) { - // die($validation->getLastError()) + // $lastError = $validation->getLastError(); + // $errors = $validation->getErrors(); } ``` @@ -55,7 +56,7 @@ if ($validation->hasErrors()) { ```php -$validation = new StrictValidation($arrayToValidate); +$validation = new StrictValidation($data); // will throw an exception if any of tests below fail $validation @@ -90,7 +91,7 @@ if ($validation->hasErrors()) { ## 5- Create a validation Schema for later usage -Schema is just another way to write validation definitions. This format is ideal when you want to store schemas in file (ex: json, php array file, yml, ...) +Schema is just another way to write validation definitions. This format is ideal when you want to store schemas in file (ex: json, php array file, yml, etc.) ```php @@ -130,6 +131,27 @@ new StrictValidationFromDefinition($validationDefinition, $arrayToValidate); new StrictValidationFromSchema($schema, $arrayToValidate); ``` +## 8- Validation and Strict Validation with ValidationBuilder + +```php +$validation = new ValidationBuilder(); +$validation + ->expectOnlyKeys(['title', 'content', 'description']) + ->expectAtLeastKeys(['title', 'content']) + ->expectKeysToBeString(['title', 'content', 'description']); + +if ($validation->validate($data) === false) { + // $validation->getErrors(); + // $validation->getLastError(); +} +``` + +and with strict validation: + +```php +// will throw an exception if any of tests fail +$validation->strictValidate($data); +``` # Validation methods ```php @@ -151,5 +173,7 @@ interface ValidationInterface public function expectKeysToBeString(array $keys, bool $acceptNull = false); public function expectKeyToBeBoolean(string $key, bool $acceptNull = false); public function expectKeysToBeBoolean(array $keys, bool $acceptNull = false); + public function expectKeyToBeObject(string $key, bool $acceptNull = false); + public function expectKeysToBeObject(array $keys, bool $acceptNull = false); } ``` \ No newline at end of file diff --git a/composer.json b/composer.json index c734826..7eae421 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,8 @@ "type": "library", "require": { "php": ">=7.2", - "symfony/polyfill-php73": "^1.14" + "symfony/polyfill-php73": "^1.14", + "ext-json": "*" }, "require-dev": { "phpunit/phpunit": "^9.0", @@ -16,5 +17,10 @@ "psr-4": { "Peak\\ArrayValidation\\": "src/" } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } } } diff --git a/src/ValidationBuilder.php b/src/ValidationBuilder.php new file mode 100644 index 0000000..0b77d75 --- /dev/null +++ b/src/ValidationBuilder.php @@ -0,0 +1,56 @@ +errors = $validation->getErrors(); + $this->lastError = $validation->getLastError(); + return !$validation->hasErrors(); + } + + /** + * @param array $data + * @throw InvalidStructureException + * @throw InvalidTypeException + */ + public function strictValidate(array $data): void + { + new StrictValidationFromDefinition($this, $data); + } + + /** + * @return array + */ + public function getErrors(): array + { + return $this->errors; + } + + /** + * @return string|null + */ + public function getLastError(): ?string + { + return $this->lastError; + } +} diff --git a/tests/StrictValidationTest.php b/tests/StrictValidationTest.php index 70d83a2..6287cd3 100644 --- a/tests/StrictValidationTest.php +++ b/tests/StrictValidationTest.php @@ -2,6 +2,8 @@ declare(strict_types=1); +namespace Tests; + use Peak\ArrayValidation\Exception\InvalidStructureException; use Peak\ArrayValidation\Exception\InvalidTypeException; use Peak\ArrayValidation\StrictValidation; diff --git a/tests/ValidationBuilderTest.php b/tests/ValidationBuilderTest.php new file mode 100644 index 0000000..abcbdf9 --- /dev/null +++ b/tests/ValidationBuilderTest.php @@ -0,0 +1,72 @@ +expectNKeys(2) + ->expectAtLeastKeys(['title', 'content']) + ->expectExactlyKeys(['title', 'content']) + ->expectOnlyKeys(['title', 'content']) + ->expectKeysToBeString(['title', 'content'], true); + + $data = [ + 'title' => 'test', + 'content' => 'test', + ]; + + $validationPass = $validation->validate($data); + $this->assertTrue($validationPass); + $this->assertTrue($validation->getErrors() === []); + $this->assertTrue($validation->getLastError() === null); + } + + public function testStrictValidate() + { + $validation = new ValidationBuilder(); + $validation + ->expectNKeys(2) + ->expectAtLeastKeys(['title', 'content']) + ->expectExactlyKeys(['title', 'content']) + ->expectOnlyKeys(['title', 'content']) + ->expectKeysToBeString(['title', 'content'], true); + + $data = [ + 'title' => 'test', + 'content' => 'test', + ]; + + $validation->strictValidate($data); + $this->assertTrue(true); + } + + public function testStrictValidateException() + { + $validation = new ValidationBuilder(); + $validation + ->expectNKeys(2) + ->expectAtLeastKeys(['title', 'content']) + ->expectExactlyKeys(['title', 'content']) + ->expectOnlyKeys(['title', 'content']) + ->expectKeysToBeString(['title', 'content'], true); + + $data = [ + 'title' => 1, + 'content' => 'test', + ]; + + $this->expectException(ArrayValidationExceptionInterface::class); + $validation->strictValidate($data); + } + +} diff --git a/tests/ValidationTest.php b/tests/ValidationTest.php index 59d5956..6dd1c05 100644 --- a/tests/ValidationTest.php +++ b/tests/ValidationTest.php @@ -6,6 +6,7 @@ use Peak\ArrayValidation\Validation; use \PHPUnit\Framework\TestCase; +use StdClass; class ValidationTest extends TestCase { @@ -15,7 +16,7 @@ public function dataProvider() return [ [ - ['field1' => [], 'field2' => 'text', 'field3' => 1, 'field4'=> true, 'field5' => 1.2, 'field6' => new \StdClass()], // data + ['field1' => [], 'field2' => 'text', 'field3' => 1, 'field4'=> true, 'field5' => 1.2, 'field6' => new StdClass()], // data null, // dataName [ // validation rules 'expectOnlyKeys' => [ ['field1', 'field2', 'field3', 'field4', 'field5', 'field6'] ], @@ -41,7 +42,7 @@ public function dataProvider() // this one will test types errors [ - ['field6' => [], 'field5' => 'text', 'field4' => 1, 'field3'=> true, 'field2' => 1.2, 'field1' => new \StdClass()], // data + ['field6' => [], 'field5' => 'text', 'field4' => 1, 'field3'=> true, 'field2' => 1.2, 'field1' => new StdClass()], // data 'myValidation', // dataName [ // validation rules 'expectKeyToBeArray' => ['field1'], diff --git a/tests/ValidatorTest.php b/tests/ValidatorTest.php index 9c41921..6d79dba 100644 --- a/tests/ValidatorTest.php +++ b/tests/ValidatorTest.php @@ -2,8 +2,12 @@ declare(strict_types=1); +namespace Tests; + +use DateTime; use \PHPUnit\Framework\TestCase; use \Peak\ArrayValidation\Validator; +use stdClass; class ValidatorTest extends TestCase {