-
Notifications
You must be signed in to change notification settings - Fork 356
Add constraint factory #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
} | ||
|
||
/** | ||
|
@@ -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 | ||
*/ | ||
|
@@ -137,7 +156,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()); | ||
|
@@ -154,7 +173,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()); | ||
|
@@ -170,7 +189,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()); | ||
|
@@ -186,7 +205,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()); | ||
|
@@ -202,7 +221,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()); | ||
|
@@ -218,7 +237,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()); | ||
|
@@ -234,15 +253,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()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a thought - some of the duplication of this class could now be moved into a private method. protected function checkFormat($value, $schema = null, $path = null, $i = null)
{
$this->checkByType('format', $value, $schema, $path, $i);
}
/**
* Create a validator of type $type and validate value against it
*
* @param string $type
* @param mixed $value
* @param mixed $schema
* @param mixed $path
* @param mixed $i
*/
private function checkByType($type, $value, $schema, $path, $i)
{
$validator = $this->getFactory()->factory($type);
$validator->check($value, $schema, $path, $i);
$this->addErrors($validator->getErrors());
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be something for a different PR There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed. |
||
|
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This library appears to duplicate the namespace in the class name. For example: This should maybe be called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be just a cosmetic thing. Prefer to hear other opinions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bighappyface - one for you. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am okay with the name, but I think we would be best served to stick with the convention established in release 1.4.0: https://github.com/justinrainbow/json-schema/releases/tag/1.4.0 (PR #136) That being said, I think the suggestion @alecsammon put forth is good guidance. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well there are lot of opinions and this could be a large discussion.
|
||
{ | ||
/** | ||
* @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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line appears to be untested - here is a test :) /**
* @expectedException JsonSchema\Exception\InvalidArgumentException
*/
public function testInvalidConstraint()
{
$this->factory->factory('badConstraintName');
} |
||
} | ||
} |
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'), | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing |null