Skip to content

Commit

Permalink
Added json schema validation feature
Browse files Browse the repository at this point in the history
  • Loading branch information
mschindler83 committed Feb 15, 2020
1 parent f4293aa commit a863c5f
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 1 deletion.
17 changes: 17 additions & 0 deletions ArrayAccess/ArrayAccess.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

use BadMethodCallException;
use Mschindler83\ArrayAccess\DotAnnotation\DotAnnotation;
use Opis\JsonSchema\Schema;
use Opis\JsonSchema\Validator;

/**
* @method string string(...$path)
Expand All @@ -31,6 +33,21 @@ public static function create($value): self
return new self($value);
}

public static function createWithJsonSchemaValidation($value, string $jsonSchemaDefinition): self
{
if (!is_array($value)) {
throw ArrayAccessFailed::notAnArray($value);
}
$schema = Schema::fromJsonString($jsonSchemaDefinition);
$result = (new Validator())->schemaValidation(\json_decode(\json_encode($value)), $schema, 10);

if (!$result->isValid()) {
throw ArrayAccessFailed::jsonSchemaValidationFailed(...$result->getErrors());
}

return new self($value);
}

public static function newFromDotAnnotation(DotAnnotation ...$dotAnnotations): self
{
$newArray = [];
Expand Down
20 changes: 20 additions & 0 deletions ArrayAccess/ArrayAccessFailed.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

namespace Mschindler83\ArrayAccess;

use Opis\JsonSchema\ValidationError;

class ArrayAccessFailed extends \RuntimeException
{
public static function notAnArray($value): self
Expand Down Expand Up @@ -51,4 +53,22 @@ public static function pathNotFound(): self
{
return new self('Path not found');
}

public static function jsonSchemaValidationFailed(ValidationError ...$errors): self
{
$messages = \array_map(
function (ValidationError $error) {
return \sprintf(
'Error: [%s], Data pointer: [%s]',
$error->keyword(),
\implode(', ', $error->dataPointer()),
);
},
$errors
);

return new self(
\sprintf('Json schema validation failed: %s', \implode(', ', $messages))
);
}
}
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Library to ease array access handling
## Features

- Savely access typed values from a given array
- Optional JSON schema validation
- Support for datetime parsing
- Define your own validation callback when retrieving values
- Create a new array in form of "dot annotations"
Expand Down Expand Up @@ -69,6 +70,37 @@ Array
)
)
```
### Array access with JSON schema validation
```
$data = [
'key1' => 'value1',
'key2' => true,
];
$access = ArrayAccess::createWithJsonSchemaValidation($data, \file_get_contents('json-schema.json'));
```

JSON schema: <json-schema.json>
```
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"key1": {
"type": "string",
"minLength": 3,
"maxLength": 64,
"pattern": "^[a-zA-Z0-9\\-]+(\\s[a-zA-Z0-9\\-]+)*$"
},
"key2": {
"type": "boolean"
}
},
"required": ["key1", "key2"],
"additionalProperties": false
}
```

### Access values
```
Expand Down
32 changes: 32 additions & 0 deletions Tests/ArrayAccess/ArrayAccessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,38 @@ public function it_returns_array_data(): void
static::assertSame($testArray, $access->data());
}

/**
* @test
*/
public function it_validates_with_json_schema_validator(): void
{
$data = [
'key1' => 'value1',
'key2' => true,
];

$access = ArrayAccess::createWithJsonSchemaValidation($data, \file_get_contents(__DIR__ . '/../Fixture/json-schema.json'));
static::assertSame('value1', $access->string('key1'));
static::assertTrue($access->bool('key2'));
}

/**
* @test
*/
public function it_raises_an_exception_on_failed_json_schema_validation(): void
{
$this->expectException(ArrayAccessFailed::class);
$this->expectExceptionMessage('Json schema validation failed: Error: [minLength], Data pointer: [key1], Error: [type], Data pointer: [key2], Error: [additionalProperties], Data pointer: []');

$data = [
'key1' => 'v',
'key2' => '1',
'key3' => 'some-other-value',
];

ArrayAccess::createWithJsonSchemaValidation($data, \file_get_contents(__DIR__ . '/../Fixture/json-schema.json'));
}

/**
* @test
*/
Expand Down
17 changes: 17 additions & 0 deletions Tests/Fixture/json-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"key1": {
"type": "string",
"minLength": 3,
"maxLength": 64,
"pattern": "^[a-zA-Z0-9\\-]+(\\s[a-zA-Z0-9\\-]+)*$"
},
"key2": {
"type": "boolean"
}
},
"required": ["key1", "key2"],
"additionalProperties": false
}
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"license": "MIT",

"require": {
"php": ">=7.4"
"php": ">=7.4",
"opis/json-schema": "^1.0",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^8.5"
Expand Down

0 comments on commit a863c5f

Please sign in to comment.