diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..b641120
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,59 @@
+name: CI Tests
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ operating-system: [ ubuntu-latest ]
+ php: [ '7.4', '8.0' ]
+
+ name: PHP ${{ matrix.php }}
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ tools: composer:v2
+ coverage: none
+ ini-values: expose_php=1
+
+ - name: Validate composer.json and composer.lock
+ run: composer validate
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: |
+ echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Install dependencies
+ run: composer install --prefer-dist --no-progress
+
+ - name: Run spec tests
+ run: composer tests-spec
+
+ - name: Run tests suite
+ run: composer tests
+
+ - name: Run phpstan
+ run: composer analyze
+
+ - name: Run codestyle checker
+ run: composer cs-check
+
+ - uses: actions/cache@v1
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-
diff --git a/.gitignore b/.gitignore
index 0a60947..9a8c46e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
.idea/
vendor
composer.lock
+.phpunit.result.cache
+/data/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1727505..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-dist: trusty
-language: php
-
-matrix:
- include:
- - php: 5.6
- - php: hhvm
- - php: 7.0
- - php: 7.1
- - php: nightly
- allow_failures:
- - php: nightly
- fast_finish: true
-
-before_install:
-
-install:
- - composer install
-
-script:
- - vendor/bin/phpspec run --no-interaction
- - vendor/bin/phpunit tests
diff --git a/README.md b/README.md
index 4bcb02c..14bee5e 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,8 @@
PHP Structure Check
===================
-[](https://travis-ci.org/1blankz7/php-structure-check)
-[](https://packagist.org/packages/1blankz7/php-structure-check)
-[](https://packagist.org/packages/1blankz7/php-structure-check)
-[](https://packagist.org/packages/1blankz7/php-structure-check)
+[](https://travis-ci.org/CubiclDev/php-structure-check)
+[](https://packagist.org/packages/cubicl/php-structure-check)
This library can check a complex array structure against a given requirement.
The purpose of this library is to create a better experience when testing a result set from an api or something similar.
@@ -12,7 +10,7 @@ The purpose of this library is to create a better experience when testing a resu
## Installation
```
-composer require 1blankz7/php-structure-check
+composer require cubicl/php-structure-check
```
## Usage
@@ -84,6 +82,7 @@ Currently the following types are supported:
* Datetime
* Regex
* Optional
+ * Enum
There are some open issues with ideas for more types. Feel free to send pull requests.
diff --git a/composer.json b/composer.json
index 22fe000..edac254 100644
--- a/composer.json
+++ b/composer.json
@@ -1,29 +1,54 @@
{
- "name": "1blankz7/php-structure-check",
- "description": "Structural check of arrays for PHP 5.6+",
- "keywords": ["array", "structure", "types"],
- "homepage": "https://github.com/1blankz7/php-structure-check",
- "type": "library",
- "license": "MIT",
- "authors": [
- {
- "name": "Christian Blank",
- "email": "mail@cblank.de",
- "homepage": "http://cblank.de"
- }
+ "name": "cubicl/php-structure-check",
+ "description": "Structural check of arrays for PHP 7.4+",
+ "keywords": [
+ "array",
+ "structure",
+ "types"
+ ],
+ "homepage": "https://github.com/cubicldev/php-structure-check",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Christian Blank",
+ "email": "christian@cubicl.de",
+ "homepage": "https://cubicl.de"
+ }
+ ],
+ "scripts": {
+ "check": [
+ "@analyze",
+ "@tests",
+ "@tests-spec",
+ "@cs-check"
],
- "require-dev": {
- "phpspec/phpspec": "^3.2",
- "phpunit/phpunit": "^5.6"
- },
- "autoload": {
- "psr-4": {
- "StructureCheck\\": [
- "src"
- ],
- "StructureCheck\\Test\\": [
- "tests"
- ]
- }
+ "tests": "phpunit tests",
+ "analyze": "phpstan analyse --level max",
+ "tests-spec": "phpspec run --no-interaction",
+ "cs-check": "phpcs --parallel=50",
+ "cs-fix": "phpcbf"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^6.2",
+ "phpunit/phpunit": "^9.4",
+ "phpstan/phpstan": "^0.12.51",
+ "phpstan/phpstan-deprecation-rules": "^0.12.4",
+ "phpstan/phpstan-phpunit": "^0.12.16",
+ "squizlabs/php_codesniffer": "^3.5.5"
+ },
+ "autoload": {
+ "psr-4": {
+ "Cubicl\\StructureCheck\\": [
+ "src"
+ ],
+ "Cubicl\\StructureCheck\\Test\\": [
+ "tests"
+ ]
}
+ },
+ "require": {
+ "ext-json": "*",
+ "php": "^7.4|^8.0"
+ }
}
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
new file mode 100644
index 0000000..1c5e692
--- /dev/null
+++ b/phpcs.xml.dist
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ src
+ tests
+
\ No newline at end of file
diff --git a/phpspec.yml b/phpspec.yml
index 2a4150f..42b140e 100644
--- a/phpspec.yml
+++ b/phpspec.yml
@@ -1,4 +1,4 @@
suites:
structure_check_suite:
- namespace: StructureCheck
- psr4_prefix: StructureCheck
\ No newline at end of file
+ namespace: Cubicl\StructureCheck
+ psr4_prefix: Cubicl\StructureCheck
\ No newline at end of file
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..da420ab
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,9 @@
+includes:
+ - vendor/phpstan/phpstan-phpunit/extension.neon
+ - vendor/phpstan/phpstan-deprecation-rules/rules.neon
+parameters:
+ tmpDir: data
+ level: max
+ paths:
+ - src
+ - tests
\ No newline at end of file
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..a2d1acc
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,11 @@
+
+
+
+
+ ./tests/
+
+
+
\ No newline at end of file
diff --git a/spec/Check/CountCheckSpec.php b/spec/Check/CountCheckSpec.php
index e1c08c3..6a53485 100644
--- a/spec/Check/CountCheckSpec.php
+++ b/spec/Check/CountCheckSpec.php
@@ -1,12 +1,14 @@
isValid()->willReturn(false);
- $child->check(Argument::any())->willReturn($result);
+ $child->check('', Argument::any())->willReturn($result);
$this->beConstructedWith($child, 1);
- $this->check([])->shouldHaveType(ResultInterface::class);
+ $this->check('', [])->shouldHaveType(ResultInterface::class);
}
function it_returns_a_result_on_check(TypeInterface $child, ResultInterface $result)
{
$result->isValid()->willReturn(true);
- $child->check(Argument::any())->willReturn($result);
+ $child->check('', Argument::any())->willReturn($result);
$this->beConstructedWith($child, 1);
- $this->check([3])->shouldHaveType(ResultInterface::class);
+ $this->check('', [3])->shouldHaveType(ResultInterface::class);
}
}
diff --git a/spec/Check/NumericRangeCheckSpec.php b/spec/Check/NumericRangeCheckSpec.php
index b0fe05c..ae71910 100644
--- a/spec/Check/NumericRangeCheckSpec.php
+++ b/spec/Check/NumericRangeCheckSpec.php
@@ -1,12 +1,14 @@
isValid()->willReturn(false);
- $child->check(Argument::any())->willReturn($result);
+ $child->check('', Argument::any())->willReturn($result);
$this->beConstructedWith($child, 0, 1);
- $this->check(Argument::any())->shouldHaveType(ResultInterface::class);
+ $this->check('', Argument::any())->shouldHaveType(ResultInterface::class);
}
function it_returns_a_result_on_check(TypeInterface $child, ResultInterface $result)
{
$result->isValid()->willReturn(true);
- $child->check(Argument::any())->willReturn($result);
+ $child->check('', Argument::any())->willReturn($result);
$this->beConstructedWith($child, 0, 1);
- $this->check(0)->shouldHaveType(ResultInterface::class);
+ $this->check('', 0)->shouldHaveType(ResultInterface::class);
}
}
diff --git a/spec/CheckerSpec.php b/spec/CheckerSpec.php
index b351b52..ad2a345 100644
--- a/spec/CheckerSpec.php
+++ b/spec/CheckerSpec.php
@@ -1,27 +1,30 @@
shouldHaveType(Checker::class);
}
- function it_accepts_a_type_and_an_array_as_parameter_for_fulfills(TypeInterface $type)
+ function it_accepts_a_type_and_an_array_as_parameter_for_fulfills(TypeInterface $type, ResultInterface $result)
{
+ $type->check('', [])->willReturn($result);
$this->fulfills([], $type);
}
function it_returns_the_result_of_the_type_in_fulfills(TypeInterface $type, ResultInterface $result)
{
- $type->check([])->willReturn($result);
+ $type->check('', [])->willReturn($result);
$this->fulfills([], $type)->shouldBe($result);
}
}
diff --git a/spec/ResultSpec.php b/spec/ResultSpec.php
index b3149e7..2a5c2bb 100644
--- a/spec/ResultSpec.php
+++ b/spec/ResultSpec.php
@@ -1,9 +1,11 @@
beConstructedWith(true);
+ $this->beConstructedWith(true, []);
$this->getErrors()->shouldHaveCount(0);
}
}
diff --git a/spec/Type/AnyTypeSpec.php b/spec/Type/AnyTypeSpec.php
index 26b6cf9..43b428f 100644
--- a/spec/Type/AnyTypeSpec.php
+++ b/spec/Type/AnyTypeSpec.php
@@ -1,8 +1,10 @@
check(null)->isValid()->shouldBe(true);
+ $this->check('', null)->isValid()->shouldBe(true);
}
function it_should_return_empty_errors_for_null()
{
- $this->check(null)->getErrors()->shouldHaveCount(0);
+ $this->check('', null)->getErrors()->shouldHaveCount(0);
}
function it_should_return_valid_for_all_values()
{
- $this->check(true)->isValid()->shouldBe(true);
- $this->check("foo")->isValid()->shouldBe(true);
- $this->check(13)->isValid()->shouldBe(true);
+ $this->check('', true)->isValid()->shouldBe(true);
+ $this->check('', "foo")->isValid()->shouldBe(true);
+ $this->check('', 13)->isValid()->shouldBe(true);
}
function it_should_return_empty_errors_for_all_values()
{
- $this->check(true)->getErrors()->shouldHaveCount(0);
- $this->check("foo")->getErrors()->shouldHaveCount(0);
- $this->check(13)->getErrors()->shouldHaveCount(0);
+ $this->check('', true)->getErrors()->shouldHaveCount(0);
+ $this->check('', "foo")->getErrors()->shouldHaveCount(0);
+ $this->check('', 13)->getErrors()->shouldHaveCount(0);
}
}
diff --git a/spec/Type/BoolTypeSpec.php b/spec/Type/BoolTypeSpec.php
index aac647f..aae328c 100644
--- a/spec/Type/BoolTypeSpec.php
+++ b/spec/Type/BoolTypeSpec.php
@@ -1,9 +1,11 @@
check(true)->isValid()->shouldBe(true);
- $this->check(false)->isValid()->shouldBe(true);
+ $this->check('', true)->isValid()->shouldBe(true);
+ $this->check('', false)->isValid()->shouldBe(true);
}
function it_should_return_invalid_for_others()
{
- $this->check(null)->isValid()->shouldBe(false);
- $this->check("foo")->isValid()->shouldBe(false);
- $this->check([])->isValid()->shouldBe(false);
- $this->check(1)->isValid()->shouldBe(false);
- $this->check(1.0)->isValid()->shouldBe(false);
+ $this->check('', null)->isValid()->shouldBe(false);
+ $this->check('', "foo")->isValid()->shouldBe(false);
+ $this->check('', [])->isValid()->shouldBe(false);
+ $this->check('', 1)->isValid()->shouldBe(false);
+ $this->check('', 1.0)->isValid()->shouldBe(false);
}
}
diff --git a/spec/Type/DatetimeTypeSpec.php b/spec/Type/DatetimeTypeSpec.php
index 27ed724..3008718 100644
--- a/spec/Type/DatetimeTypeSpec.php
+++ b/spec/Type/DatetimeTypeSpec.php
@@ -1,35 +1,37 @@
beConstructedWith('d-m-Y h:m:s', 'UTC');
$this->shouldHaveType(DatetimeType::class);
}
- function it_should_return_valid_for_correct_values()
+ public function it_should_return_valid_for_correct_values(): void
{
$this->beConstructedWith('d-m-Y h:m:s', 'Europe/Berlin');
- $this->check('12-12-2012 12:12:10')->isValid()->shouldBe(true);
+ $this->check('', '12-12-2012 12:12:10')->isValid()->shouldBe(true);
}
- function it_should_return_invalid_for_others()
+ public function it_should_return_invalid_for_others(): void
{
$this->beConstructedWith('d-m-Y h:m:s', 'Europe/Berlin');
- $this->check(null)->isValid()->shouldBe(false);
- $this->check('foo')->isValid()->shouldBe(false);
- $this->check([])->isValid()->shouldBe(false);
- $this->check(1.234)->isValid()->shouldBe(false);
- $this->check(true)->isValid()->shouldBe(false);
- $this->check(false)->isValid()->shouldBe(false);
+ $this->check('', null)->isValid()->shouldBe(false);
+ $this->check('', 'foo')->isValid()->shouldBe(false);
+ $this->check('', [])->isValid()->shouldBe(false);
+ $this->check('', 1.234)->isValid()->shouldBe(false);
+ $this->check('', true)->isValid()->shouldBe(false);
+ $this->check('', false)->isValid()->shouldBe(false);
}
}
diff --git a/spec/Type/EnumTypeSpec.php b/spec/Type/EnumTypeSpec.php
new file mode 100644
index 0000000..453c4e1
--- /dev/null
+++ b/spec/Type/EnumTypeSpec.php
@@ -0,0 +1,37 @@
+beConstructedWith(['test', 1, null]);
+
+ $this->shouldHaveType(EnumType::class);
+ }
+
+ function it_is_valid_for_all_allowed_values()
+ {
+ $this->beConstructedWith(['test', 1, null]);
+
+ $this->check('', 'test')->isValid()->shouldBe(true);
+ $this->check('', 1)->isValid()->shouldBe(true);
+ $this->check('', null)->isValid()->shouldBe(true);
+ }
+
+ function it_is_invalid_for_not_allowed_values()
+ {
+ $this->beConstructedWith(['test', 1, null]);
+
+ $this->check('', 'array')->isValid()->shouldBe(false);
+ $this->check('', 100)->isValid()->shouldBe(false);
+ $this->check('', 1.5)->isValid()->shouldBe(false);
+ $this->check('', ['test'])->isValid()->shouldBe(false);
+ }
+}
diff --git a/spec/Type/ExactValueTypeSpec.php b/spec/Type/ExactValueTypeSpec.php
index 38ff88b..c2faf8b 100644
--- a/spec/Type/ExactValueTypeSpec.php
+++ b/spec/Type/ExactValueTypeSpec.php
@@ -1,8 +1,10 @@
beConstructedWith(null);
- $this->check(null)->isValid()->shouldBe(true);
+ $this->check('', null)->isValid()->shouldBe(true);
}
}
diff --git a/spec/Type/FloatTypeSpec.php b/spec/Type/FloatTypeSpec.php
index 04e1dd3..698abf6 100644
--- a/spec/Type/FloatTypeSpec.php
+++ b/spec/Type/FloatTypeSpec.php
@@ -1,8 +1,10 @@
check(0.0)->isValid()->shouldBe(true);
- $this->check(1.1)->isValid()->shouldBe(true);
- $this->check(2.0)->isValid()->shouldBe(true);
- $this->check(-144.2)->isValid()->shouldBe(true);
+ $this->check('', 0.0)->isValid()->shouldBe(true);
+ $this->check('', 1.1)->isValid()->shouldBe(true);
+ $this->check('', 2.0)->isValid()->shouldBe(true);
+ $this->check('', -144.2)->isValid()->shouldBe(true);
}
function it_should_return_invalid_for_others()
{
- $this->check(null)->isValid()->shouldBe(false);
- $this->check("foo")->isValid()->shouldBe(false);
- $this->check([])->isValid()->shouldBe(false);
- $this->check(1)->isValid()->shouldBe(false);
- $this->check(true)->isValid()->shouldBe(false);
- $this->check(false)->isValid()->shouldBe(false);
+ $this->check('', null)->isValid()->shouldBe(false);
+ $this->check('', "foo")->isValid()->shouldBe(false);
+ $this->check('', [])->isValid()->shouldBe(false);
+ $this->check('', 1)->isValid()->shouldBe(false);
+ $this->check('', true)->isValid()->shouldBe(false);
+ $this->check('', false)->isValid()->shouldBe(false);
}
}
diff --git a/spec/Type/IntTypeSpec.php b/spec/Type/IntTypeSpec.php
index df75166..93bc2b7 100644
--- a/spec/Type/IntTypeSpec.php
+++ b/spec/Type/IntTypeSpec.php
@@ -1,8 +1,10 @@
check(0)->isValid()->shouldBe(true);
- $this->check(1)->isValid()->shouldBe(true);
- $this->check(20)->isValid()->shouldBe(true);
- $this->check(-144)->isValid()->shouldBe(true);
+ $this->check('', 0)->isValid()->shouldBe(true);
+ $this->check('', 1)->isValid()->shouldBe(true);
+ $this->check('', 20)->isValid()->shouldBe(true);
+ $this->check('', -144)->isValid()->shouldBe(true);
}
function it_should_return_invalid_for_others()
{
- $this->check(null)->isValid()->shouldBe(false);
- $this->check("foo")->isValid()->shouldBe(false);
- $this->check([])->isValid()->shouldBe(false);
- $this->check(1.234)->isValid()->shouldBe(false);
- $this->check(true)->isValid()->shouldBe(false);
- $this->check(false)->isValid()->shouldBe(false);
+ $this->check('', null)->isValid()->shouldBe(false);
+ $this->check('', "foo")->isValid()->shouldBe(false);
+ $this->check('', [])->isValid()->shouldBe(false);
+ $this->check('', 1.234)->isValid()->shouldBe(false);
+ $this->check('', true)->isValid()->shouldBe(false);
+ $this->check('', false)->isValid()->shouldBe(false);
}
}
diff --git a/spec/Type/ListTypeSpec.php b/spec/Type/ListTypeSpec.php
index 7884f1d..8edad91 100644
--- a/spec/Type/ListTypeSpec.php
+++ b/spec/Type/ListTypeSpec.php
@@ -1,11 +1,13 @@
beConstructedWith($childType);
- $this->check(null)->isValid()->shouldBe(true);
+ $this->check('', null)->isValid()->shouldBe(true);
}
function it_should_return_the_value_from_the_child(TypeInterface $childType) {
$this->beConstructedWith($childType);
- $childType->check(false)->willReturn(new Result(false, []));
- $this->check(false)->isValid()->shouldBe(false);
+ $childType->check('', false)->willReturn(new Result(false, []));
+ $this->check('', false)->isValid()->shouldBe(false);
}
}
diff --git a/spec/Type/NumericTypeSpec.php b/spec/Type/NumericTypeSpec.php
index 9e863a3..449cbc2 100644
--- a/spec/Type/NumericTypeSpec.php
+++ b/spec/Type/NumericTypeSpec.php
@@ -1,8 +1,10 @@
check(0)->isValid()->shouldBe(true);
- $this->check(1)->isValid()->shouldBe(true);
- $this->check(20)->isValid()->shouldBe(true);
- $this->check(-144)->isValid()->shouldBe(true);
+ $this->check('', 0)->isValid()->shouldBe(true);
+ $this->check('', 1)->isValid()->shouldBe(true);
+ $this->check('', 20)->isValid()->shouldBe(true);
+ $this->check('', -144)->isValid()->shouldBe(true);
}
function it_should_return_valid_for_floats()
{
- $this->check(0.0)->isValid()->shouldBe(true);
- $this->check(1.1235)->isValid()->shouldBe(true);
- $this->check(-0.00001)->isValid()->shouldBe(true);
- $this->check(-144.12313131313)->isValid()->shouldBe(true);
+ $this->check('', 0.0)->isValid()->shouldBe(true);
+ $this->check('', 1.1235)->isValid()->shouldBe(true);
+ $this->check('', -0.00001)->isValid()->shouldBe(true);
+ $this->check('', -144.12313131313)->isValid()->shouldBe(true);
}
function it_should_return_invalid_for_others()
{
- $this->check(null)->isValid()->shouldBe(false);
- $this->check("foo")->isValid()->shouldBe(false);
- $this->check([])->isValid()->shouldBe(false);
- $this->check(true)->isValid()->shouldBe(false);
- $this->check(false)->isValid()->shouldBe(false);
+ $this->check('', null)->isValid()->shouldBe(false);
+ $this->check('', "foo")->isValid()->shouldBe(false);
+ $this->check('', [])->isValid()->shouldBe(false);
+ $this->check('', true)->isValid()->shouldBe(false);
+ $this->check('', false)->isValid()->shouldBe(false);
}
}
diff --git a/spec/Type/ObjectTypeSpec.php b/spec/Type/ObjectTypeSpec.php
index 3b94d01..3941dde 100644
--- a/spec/Type/ObjectTypeSpec.php
+++ b/spec/Type/ObjectTypeSpec.php
@@ -1,11 +1,13 @@
beConstructedWith($childType);
$this->shouldHaveType(OptionalType::class);
}
- function it_should_return_the_value_from_the_child(TypeInterface $childType) {
+ function it_should_return_the_value_from_the_child(TypeInterface $childType): void
+ {
$this->beConstructedWith($childType);
- $childType->check(false)->willReturn(new Result(false, []));
- $this->check(false)->isValid()->shouldBe(false);
+ $childType->check('', false)->willReturn(new Result(false, []));
+ $this->check('', false)->isValid()->shouldBe(false);
}
}
diff --git a/spec/Type/RegexTypeSpec.php b/spec/Type/RegexTypeSpec.php
index 5b89312..3f260a4 100644
--- a/spec/Type/RegexTypeSpec.php
+++ b/spec/Type/RegexTypeSpec.php
@@ -1,42 +1,44 @@
beConstructedWith('/^def/');
$this->shouldHaveType(RegexType::class);
}
- function it_should_return_valid_for_matching_strings()
+ function it_should_return_valid_for_matching_strings(): void
{
$this->beConstructedWith('/^def/');
- $this->check('definitive')->isValid()->shouldBe(true);
+ $this->check('', 'definitive')->isValid()->shouldBe(true);
}
- function it_should_return_invalid_for_not_matching_strings()
+ function it_should_return_invalid_for_not_matching_strings(): void
{
$this->beConstructedWith('/^def/');
- $this->check('developers')->isValid()->shouldBe(false);
+ $this->check('', 'developers')->isValid()->shouldBe(false);
}
- function it_should_return_invalid_for_others()
+ function it_should_return_invalid_for_others(): void
{
$this->beConstructedWith('/^def/');
- $this->check(null)->isValid()->shouldBe(false);
- $this->check(12.3)->isValid()->shouldBe(false);
- $this->check([])->isValid()->shouldBe(false);
- $this->check(-1)->isValid()->shouldBe(false);
- $this->check(true)->isValid()->shouldBe(false);
+ $this->check('', null)->isValid()->shouldBe(false);
+ $this->check('', 12.3)->isValid()->shouldBe(false);
+ $this->check('', [])->isValid()->shouldBe(false);
+ $this->check('', -1)->isValid()->shouldBe(false);
+ $this->check('', true)->isValid()->shouldBe(false);
}
}
diff --git a/spec/Type/StringTypeSpec.php b/spec/Type/StringTypeSpec.php
index 789627b..9c1ca8c 100644
--- a/spec/Type/StringTypeSpec.php
+++ b/spec/Type/StringTypeSpec.php
@@ -1,31 +1,33 @@
shouldHaveType(StringType::class);
}
- function it_should_return_valid_for_strings()
+ function it_should_return_valid_for_strings(): void
{
- $this->check("")->isValid()->shouldBe(true);
- $this->check("fooo")->isValid()->shouldBe(true);
- $this->check('adadsad asd a')->isValid()->shouldBe(true);
+ $this->check('', '')->isValid()->shouldBe(true);
+ $this->check('', 'fooo')->isValid()->shouldBe(true);
+ $this->check('', 'adadsad asd a')->isValid()->shouldBe(true);
}
- function it_should_return_invalid_for_others()
+ function it_should_return_invalid_for_others(): void
{
- $this->check(null)->isValid()->shouldBe(false);
- $this->check(12.3)->isValid()->shouldBe(false);
- $this->check([])->isValid()->shouldBe(false);
- $this->check(-1)->isValid()->shouldBe(false);
- $this->check(true)->isValid()->shouldBe(false);
+ $this->check('', null)->isValid()->shouldBe(false);
+ $this->check('', 12.3)->isValid()->shouldBe(false);
+ $this->check('', [])->isValid()->shouldBe(false);
+ $this->check('', -1)->isValid()->shouldBe(false);
+ $this->check('', true)->isValid()->shouldBe(false);
}
}
diff --git a/src/Check/CountCheck.php b/src/Check/CountCheck.php
index c640dde..6b629d6 100644
--- a/src/Check/CountCheck.php
+++ b/src/Check/CountCheck.php
@@ -1,74 +1,51 @@
child = $child;
$this->count = $count;
}
- /**
- * @inheritdoc
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
- $result = $this->child->check($value);
+ $result = $this->child->check($key, $value);
if (!$result->isValid()) {
return $result;
}
if (!$value instanceof Countable) {
- return new Result(
- false,
- [sprintf(self::$countableErrorMessage, json_encode($value))]
- );
+ return Result::invalid([
+ new Error($key, sprintf(self::$countableErrorMessage, json_encode($value)))
+ ]);
}
if (count($value) !== $this->count) {
- return new Result(
- false,
- [sprintf(self::$countErrorMessage, json_encode($value), $this->count)]
- );
+ return Result::invalid([
+ new Error($key, sprintf(self::$countErrorMessage, json_encode($value), $this->count))
+ ]);
}
- return new Result(true);
+ return Result::valid();
}
}
diff --git a/src/Check/NumericRangeCheck.php b/src/Check/NumericRangeCheck.php
index b14c5c2..ef3dc38 100644
--- a/src/Check/NumericRangeCheck.php
+++ b/src/Check/NumericRangeCheck.php
@@ -1,14 +1,14 @@
child = $child;
$this->upperBound = $upperBound;
$this->lowerBound = $lowerBound;
}
- /**
- * @inheritdoc
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
- $result = $this->child->check($value);
+ $result = $this->child->check($key, $value);
if (!$result->isValid()) {
- return $result;
+ return $result;
}
if ($this->lowerBound > $value) {
- return new Result(
- false,
- [sprintf(self::$lowerBoundErrorMessage, $this->lowerBound, $value)]
- );
+ return Result::invalid([
+ new Error($key, sprintf(self::$lowerBoundErrorMessage, $this->lowerBound, $value))
+ ]);
}
if ($this->upperBound < $value) {
- return new Result(
- false,
- [sprintf(self::$upperBoundErrorMessage, $this->upperBound, $value)]
- );
+ return Result::invalid([
+ new Error($key, sprintf(self::$upperBoundErrorMessage, $this->lowerBound, $value))
+ ]);
}
- return new Result(true);
+ return Result::valid();
}
}
diff --git a/src/Checker.php b/src/Checker.php
index 88b3f3d..9f06034 100644
--- a/src/Checker.php
+++ b/src/Checker.php
@@ -1,22 +1,15 @@
check($element);
+ return $requirement->check('', $element);
}
-
-}
\ No newline at end of file
+}
diff --git a/src/CheckerInterface.php b/src/CheckerInterface.php
index 57a0605..e6ecc55 100644
--- a/src/CheckerInterface.php
+++ b/src/CheckerInterface.php
@@ -1,21 +1,15 @@
key = $key;
+ $this->message = $message;
+ }
+
+ public function getKey(): string
+ {
+ return $this->key;
+ }
+
+ public function getMessage(): string
+ {
+ return $this->message;
+ }
+}
diff --git a/src/ErrorInterface.php b/src/ErrorInterface.php
new file mode 100644
index 0000000..6efb18a
--- /dev/null
+++ b/src/ErrorInterface.php
@@ -0,0 +1,12 @@
+
*/
- private $errors;
+ private array $errors;
/**
- * Result constructor.
- *
- * @param bool $valid
- * @param array $errors
+ * @param array $errors
*/
- public function __construct($valid, array $errors = [])
+ public function __construct(bool $valid, array $errors)
{
$this->valid = $valid;
$this->errors = $errors;
}
+ public static function valid(): ResultInterface
+ {
+ return new self(true, []);
+ }
+
/**
- * @inheritdoc
+ * @param array $errors
*/
- public function isValid()
+ public static function invalid(array $errors): ResultInterface
+ {
+ return new self(false, $errors);
+ }
+
+ public function isValid(): bool
{
return $this->valid;
}
- /**
- * @inheritdoc
- */
- public function getErrors()
+ public function getErrors(): array
{
return $this->errors;
}
-}
\ No newline at end of file
+}
diff --git a/src/ResultInterface.php b/src/ResultInterface.php
index 8a4ee76..17eabde 100644
--- a/src/ResultInterface.php
+++ b/src/ResultInterface.php
@@ -1,24 +1,23 @@
*/
- public function getErrors();
-}
\ No newline at end of file
+ public function getErrors(): array;
+}
diff --git a/src/Type/AnyType.php b/src/Type/AnyType.php
index 4e8b1b4..aecd21b 100644
--- a/src/Type/AnyType.php
+++ b/src/Type/AnyType.php
@@ -1,20 +1,16 @@
datetimeFormat = $format;
$this->datetimeZone = $datetimeZone;
}
- /**
- * @param mixed $value
- *
- * @return ResultInterface
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
$checkResult = is_string($value) && $this->isValidDatetime($value);
- return new Result(
- $checkResult,
- !$checkResult ? [sprintf(self::$errorMessage, json_encode($value))] : []
- );
+ return $checkResult
+ ? Result::valid()
+ : Result::invalid([new Error($key, sprintf(self::$errorMessage, json_encode($value)))]);
}
- /**
- * @param string $value
- *
- * @return bool
- */
- private function isValidDatetime($value) {
+ private function isValidDatetime(string $value): bool
+ {
$date = DateTime::createFromFormat($this->datetimeFormat, $value, new DateTimeZone($this->datetimeZone));
- $errors = DateTime::getLastErrors()["warning_count"];
+ $errors = DateTime::getLastErrors();
- return $date && $errors["warning_count"] == 0 && $errors["error_count"] == 0;
+ return $date && (
+ !$errors || ($errors['warning_count'] === 0 && $errors['error_count'] === 0)
+ );
}
}
diff --git a/src/Type/EnumType.php b/src/Type/EnumType.php
new file mode 100644
index 0000000..064e502
--- /dev/null
+++ b/src/Type/EnumType.php
@@ -0,0 +1,42 @@
+ */
+ private array $values;
+
+ /**
+ * @param array $values
+ */
+ public function __construct(array $values)
+ {
+ $this->values = $values;
+ }
+
+ /**
+ * @param string $key
+ * @param T $value
+ */
+ public function check(string $key, $value): ResultInterface
+ {
+ $checkResult = in_array($value, $this->values, true);
+ return $checkResult
+ ? Result::valid()
+ : Result::invalid([
+ new Error($key, sprintf(self::$errorMessage, json_encode($value), implode(',', $this->values)))
+ ]);
+ }
+}
diff --git a/src/Type/ExactValueType.php b/src/Type/ExactValueType.php
index ae72087..36d03cb 100644
--- a/src/Type/ExactValueType.php
+++ b/src/Type/ExactValueType.php
@@ -1,21 +1,21 @@
value = $value;
}
- /**
- * @param mixed $value
- *
- * @return ResultInterface
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
$checkResult = $this->value === $value;
- return new Result(
- $checkResult,
- !$checkResult ? [sprintf(self::$errorMessage, json_encode($value), $this->value)] : []
- );
+ return $checkResult
+ ? Result::valid()
+ : Result::invalid([
+ new Error($key, sprintf(self::$errorMessage, json_encode($value), json_encode($this->value)))
+ ]);
}
}
diff --git a/src/Type/FloatType.php b/src/Type/FloatType.php
index 70e74b4..80aec7a 100644
--- a/src/Type/FloatType.php
+++ b/src/Type/FloatType.php
@@ -1,23 +1,23 @@
child = $child;
}
- /**
- * @inheritdoc
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
if (!is_array($value)) {
- return new Result(
- false,
- [sprintf(self::$isNotAnArrayMessage, json_encode($value))]
+ return Result::invalid(
+ [new Error($key, sprintf(self::$isNotAnArrayMessage, json_encode($value)))]
);
}
$errors = [];
$valid = true;
- foreach ($value as $item) {
- $result = $this->child->check($item);
+ foreach ($value as $idx => $item) {
+ $result = $this->child->check(sprintf('%s.%d', $key, $idx), $item);
$valid = $valid && $result->isValid();
$errors += $result->getErrors();
}
- return new Result($valid, $errors);
+ return $valid
+ ? Result::valid()
+ : Result::invalid($errors);
}
}
diff --git a/src/Type/NullableType.php b/src/Type/NullableType.php
index 8853ff9..f3eb64e 100644
--- a/src/Type/NullableType.php
+++ b/src/Type/NullableType.php
@@ -1,40 +1,27 @@
child = $child;
}
- /**
- * @inheritdoc
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
- if(is_null($value)) {
- return new Result(true);
+ if ($value === null) {
+ return Result::valid();
}
- return $this->child->check($value);
+ return $this->child->check($key, $value);
}
-}
\ No newline at end of file
+}
diff --git a/src/Type/NumericType.php b/src/Type/NumericType.php
index 7cc1c56..96a24da 100644
--- a/src/Type/NumericType.php
+++ b/src/Type/NumericType.php
@@ -1,26 +1,23 @@
children = $children;
}
- /**
- * @inheritdoc
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
$errors = [];
$valid = true;
- foreach ($this->children as $key => $child) {
- if (!array_key_exists($key, $value)) {
+ foreach ($this->children as $objectProperty => $child) {
+ $fullKey = sprintf('%s.%s', $key, $objectProperty);
+ if (!array_key_exists($objectProperty, $value)) {
if (!$child instanceof OptionalType) {
$valid = false;
- $errors[] = sprintf(self::$missingKeyErrorMessage, $key);
+ $errors[] = new Error($fullKey, sprintf(self::$missingKeyErrorMessage, $objectProperty));
}
-
continue;
}
- $result = $child->check($value[$key]);
+ $result = $child->check($fullKey, $value[$objectProperty]);
$valid = $valid && $result->isValid();
$errors += $result->getErrors();
}
diff --git a/src/Type/OptionalType.php b/src/Type/OptionalType.php
index 9110a5a..91cb0b8 100644
--- a/src/Type/OptionalType.php
+++ b/src/Type/OptionalType.php
@@ -1,37 +1,22 @@
- */
class OptionalType implements TypeInterface
{
- /**
- * @var TypeInterface
- */
- private $child;
+ private TypeInterface $child;
- /**
- * OptionalType constructor.
- * @param TypeInterface $child
- */
public function __construct(TypeInterface $child)
{
$this->child = $child;
}
- /**
- * @param mixed $value
- *
- * @return ResultInterface
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
- return $this->child->check($value);
+ return $this->child->check($key, $value);
}
-}
\ No newline at end of file
+}
diff --git a/src/Type/RegexType.php b/src/Type/RegexType.php
index fe033c8..7471246 100644
--- a/src/Type/RegexType.php
+++ b/src/Type/RegexType.php
@@ -1,48 +1,32 @@
regex = $regex;
}
- /**
- * @param mixed $value
- *
- * @return ResultInterface
- */
- public function check($value)
+ public function check(string $key, $value): ResultInterface
{
$checkResult = is_string($value) && preg_match($this->regex, $value) === 1;
- return new Result(
- $checkResult,
- !$checkResult ? [sprintf(self::$errorMessage, json_encode($value), $this->regex)] : []
- );
+ return $checkResult
+ ? Result::valid()
+ : Result::invalid([
+ new Error($key, sprintf(self::$errorMessage, json_encode($value), json_encode($this->regex)))
+ ]);
}
}
diff --git a/src/Type/StringType.php b/src/Type/StringType.php
index 46af09d..7fcb4ca 100644
--- a/src/Type/StringType.php
+++ b/src/Type/StringType.php
@@ -1,30 +1,23 @@
*/
class ObjectTypeTest extends TestCase
{
- /**
- * @var CheckerInterface
- */
- private $checker;
+ private CheckerInterface $checker;
- /**
- *
- */
- protected function setUp()
+ protected function setUp(): void
{
parent::setUp();
$this->checker = new Checker();
@@ -33,14 +29,14 @@ protected function setUp()
/**
* @test
*/
- public function itShouldHandleAbsenceOfOptionalDeclaredType()
+ public function itShouldHandleAbsenceOfOptionalDeclaredType(): void
{
$structure = new ObjectType([
'opt' => new OptionalType(new AnyType())
]);
- $actual = $structure->check([]);
+ $actual = $structure->check('', []);
$this->assertSame(true, $actual->isValid());
}
-}
\ No newline at end of file
+}