Skip to content

Commit

Permalink
Allow the schema to be an associative array (jsonrainbow#389)
Browse files Browse the repository at this point in the history
* Allow the schema to be an associative array

Implements jsonrainbow#388.

* Use json_decode(json_encode()) for array -> object cast

* Skip exception check on PHP versions < 5.5.0

* Skip test on HHVM, as it's happy to encode resources
  • Loading branch information
erayd committed Mar 21, 2017
1 parent c53c87b commit 6400012
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/JsonSchema/Constraints/BaseConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JsonSchema\Constraints;

use JsonSchema\Entity\JsonPointer;
use JsonSchema\Exception\InvalidArgumentException;
use JsonSchema\Exception\ValidationException;

/**
Expand Down Expand Up @@ -81,4 +82,25 @@ public function reset()
{
$this->errors = array();
}

/**
* Recursively cast an associative array to an object
*
* @param array $array
*
* @return object
*/
public static function arrayToObjectRecursive($array)
{
$json = json_encode($array);
if (json_last_error() !== \JSON_ERROR_NONE) {
$message = 'Unable to encode schema array as JSON';
if (version_compare(phpversion(), '5.5.0', '>=')) {
$message .= ': ' . json_last_error_msg();
}
throw new InvalidArgumentException($message);
}

return json_decode($json);
}
}
9 changes: 9 additions & 0 deletions src/JsonSchema/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ class Validator extends BaseConstraint
*/
public function validate(&$value, $schema = null, $checkMode = null)
{
// reset errors prior to validation
$this->reset();

// make sure $schema is an object
if (is_array($schema)) {
$schema = self::arrayToObjectRecursive($schema);
}

// set checkMode
$initialCheckMode = $this->factory->getConfig();
if ($checkMode !== null) {
$this->factory->setConfig($checkMode);
Expand Down
59 changes: 59 additions & 0 deletions tests/ValidatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace JsonSchema\Tests;

use JsonSchema\Constraints\Constraint;
use JsonSchema\Validator;

class ValidatorTest extends \PHPUnit_Framework_TestCase
{
public function testValidateWithAssocSchema()
{
$schema = json_decode('{"properties":{"propertyOne":{"type":"array","items":[{"type":"string"}]}}}', true);
$data = json_decode('{"propertyOne":[42]}', true);

$validator = new Validator();
$validator->validate($data, $schema);

$this->assertFalse($validator->isValid(), 'Validation succeeded, but should have failed.');
}

public function testBadAssocSchemaInput()
{
if (version_compare(phpversion(), '5.5.0', '<')) {
$this->markTestSkipped('PHP versions < 5.5.0 trigger an error on json_encode issues');
}
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('HHVM has no problem with encoding resources');
}
$schema = array('propertyOne' => fopen('php://stdout', 'w'));
$data = json_decode('{"propertyOne":[42]}', true);

$validator = new Validator();

$this->setExpectedException('\JsonSchema\Exception\InvalidArgumentException');
$validator->validate($data, $schema);
}

public function testCheck()
{
$schema = json_decode('{"type":"string"}');
$data = json_decode('42');

$validator = new Validator();
$validator->check($data, $schema);

$this->assertFalse($validator->isValid(), 'Validation succeeded, but should have failed.');
}

public function testCoerce()
{
$schema = json_decode('{"type":"integer"}');
$data = json_decode('"42"');

$validator = new Validator();
$validator->coerce($data, $schema);

$this->assertTrue($validator->isValid(), 'Validation failed, but should have succeeded.');
}
}

0 comments on commit 6400012

Please sign in to comment.