Skip to content

Commit

Permalink
Merge pull request #143 from Maks3w/feature/constraint-factory
Browse files Browse the repository at this point in the history
Add constraint factory
  • Loading branch information
bighappyface committed Nov 8, 2015
2 parents 043bc7c + 34f9ae1 commit 09ab4df
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 10 deletions.
37 changes: 28 additions & 9 deletions src/JsonSchema/Constraints/Constraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,21 @@ abstract class Constraint implements ConstraintInterface
const CHECK_MODE_NORMAL = 1;
const CHECK_MODE_TYPE_CAST = 2;

/**
* @var null|Factory
*/
private $factory;

/**
* @param int $checkMode
* @param UriRetriever $uriRetriever
* @param Factory $factory
*/
public function __construct($checkMode = self::CHECK_MODE_NORMAL, UriRetriever $uriRetriever = null)
public function __construct($checkMode = self::CHECK_MODE_NORMAL, UriRetriever $uriRetriever = null, Factory $factory = null)
{
$this->checkMode = $checkMode;
$this->uriRetriever = $uriRetriever;
$this->factory = $factory;
}

/**
Expand All @@ -50,6 +57,18 @@ public function getUriRetriever()
return $this->uriRetriever;
}

/**
* @return Factory
*/
public function getFactory()
{
if (!$this->factory) {
$this->factory = new Factory($this->getUriRetriever());
}

return $this->factory;
}

/**
* @param UriRetriever $uriRetriever
*/
Expand Down Expand Up @@ -145,7 +164,7 @@ protected function incrementPath($path, $i)
*/
protected function checkArray($value, $schema = null, $path = null, $i = null)
{
$validator = new CollectionConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('collection');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -162,7 +181,7 @@ protected function checkArray($value, $schema = null, $path = null, $i = null)
*/
protected function checkObject($value, $schema = null, $path = null, $i = null, $patternProperties = null)
{
$validator = new ObjectConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('object');
$validator->check($value, $schema, $path, $i, $patternProperties);

$this->addErrors($validator->getErrors());
Expand All @@ -178,7 +197,7 @@ protected function checkObject($value, $schema = null, $path = null, $i = null,
*/
protected function checkType($value, $schema = null, $path = null, $i = null)
{
$validator = new TypeConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('type');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -194,7 +213,7 @@ protected function checkType($value, $schema = null, $path = null, $i = null)
*/
protected function checkUndefined($value, $schema = null, $path = null, $i = null)
{
$validator = new UndefinedConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('undefined');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -210,7 +229,7 @@ protected function checkUndefined($value, $schema = null, $path = null, $i = nul
*/
protected function checkString($value, $schema = null, $path = null, $i = null)
{
$validator = new StringConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('string');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -226,7 +245,7 @@ protected function checkString($value, $schema = null, $path = null, $i = null)
*/
protected function checkNumber($value, $schema = null, $path = null, $i = null)
{
$validator = new NumberConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('number');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand All @@ -242,15 +261,15 @@ protected function checkNumber($value, $schema = null, $path = null, $i = null)
*/
protected function checkEnum($value, $schema = null, $path = null, $i = null)
{
$validator = new EnumConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('enum');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}

protected function checkFormat($value, $schema = null, $path = null, $i = null)
{
$validator = new FormatConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('format');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
Expand Down
81 changes: 81 additions & 0 deletions src/JsonSchema/Constraints/Factory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Constraints;

use JsonSchema\Exception\InvalidArgumentException;
use JsonSchema\Uri\UriRetriever;
use JsonSchema\Validator;

/**
* Factory for centralize constraint initialization.
*/
class Factory
{
/**
* @var UriRetriever
*/
protected $uriRetriever;

/**
* @param UriRetriever $uriRetriever
*/
public function __construct(UriRetriever $uriRetriever = null)
{
if (!$uriRetriever) {
$uriRetriever = new UriRetriever();
}

$this->uriRetriever = $uriRetriever;
}

/**
* @return UriRetriever
*/
public function getUriRetriever()
{
return $this->uriRetriever;
}

/**
* Create a constraint instance for the given constraint name.
*
* @param string $constraintName
* @return ConstraintInterface|ObjectConstraint
* @throws InvalidArgumentException if is not possible create the constraint instance.
*/
public function createInstanceFor($constraintName)
{
switch ($constraintName) {
case 'array':
case 'collection':
return new CollectionConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'object':
return new ObjectConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'type':
return new TypeConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'undefined':
return new UndefinedConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'string':
return new StringConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'number':
return new NumberConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'enum':
return new EnumConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'format':
return new FormatConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'schema':
return new SchemaConstraint(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
case 'validator':
return new Validator(Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
}

throw new InvalidArgumentException('Unknown constraint ' . $constraintName);
}
}
2 changes: 1 addition & 1 deletion src/JsonSchema/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Validator extends Constraint
*/
public function check($value, $schema = null, $path = null, $i = null)
{
$validator = new SchemaConstraint($this->checkMode, $this->uriRetriever);
$validator = $this->getFactory()->createInstanceFor('schema');
$validator->check($value, $schema);

$this->addErrors(array_unique($validator->getErrors(), SORT_REGULAR));
Expand Down
78 changes: 78 additions & 0 deletions tests/JsonSchema/Tests/Constraints/FactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Tests\Constraints;

use JsonSchema\Constraints\Factory;
use PHPUnit_Framework_TestCase as TestCase;

class FactoryTest extends TestCase
{
/**
* @var Factory
*/
protected $factory;

protected function setUp()
{
$this->factory = new Factory();
}

/**
* @dataProvider constraintNameProvider
*
* @param string $constraintName
* @param string $expectedClass
* @return void
*/
public function testCreateInstanceForConstraintName($constraintName, $expectedClass)
{
$constraint = $this->factory->createInstanceFor($constraintName);

$this->assertInstanceOf($expectedClass, $constraint);
$this->assertInstanceOf('JsonSchema\Constraints\ConstraintInterface', $constraint);
$this->assertSame($this->factory->getUriRetriever(), $constraint->getUriRetriever());
}

public function constraintNameProvider()
{
return array(
array('array', 'JsonSchema\Constraints\CollectionConstraint'),
array('collection', 'JsonSchema\Constraints\CollectionConstraint'),
array('object', 'JsonSchema\Constraints\ObjectConstraint'),
array('type', 'JsonSchema\Constraints\TypeConstraint'),
array('undefined', 'JsonSchema\Constraints\UndefinedConstraint'),
array('string', 'JsonSchema\Constraints\StringConstraint'),
array('number', 'JsonSchema\Constraints\NumberConstraint'),
array('enum', 'JsonSchema\Constraints\EnumConstraint'),
array('format', 'JsonSchema\Constraints\FormatConstraint'),
array('schema', 'JsonSchema\Constraints\SchemaConstraint'),
array('validator', 'JsonSchema\Validator'),
);
}

/**
* @dataProvider invalidConstraintNameProvider
*
* @param string $constraintName
* @return void
*/
public function testExceptionWhenCreateInstanceForInvalidConstraintName($constraintName)
{
$this->setExpectedException('JsonSchema\Exception\InvalidArgumentException');
$this->factory->createInstanceFor($constraintName);
}

public function invalidConstraintNameProvider()
{
return array(
array('invalidConstraintName'),
);
}
}

0 comments on commit 09ab4df

Please sign in to comment.