Skip to content

Commit

Permalink
Merge pull request #507 from martin-helmich/feature/const-support
Browse files Browse the repository at this point in the history
Add support for "const"
  • Loading branch information
bighappyface committed May 23, 2018
2 parents e0b253f + 8a9cd12 commit a4bf903
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/JsonSchema/ConstraintError.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class ConstraintError extends Enum
const DISALLOW = 'disallow';
const DIVISIBLE_BY = 'divisibleBy';
const ENUM = 'enum';
const CONSTANT = 'const';
const EXCLUSIVE_MINIMUM = 'exclusiveMinimum';
const EXCLUSIVE_MAXIMUM = 'exclusiveMaximum';
const FORMAT_COLOR = 'colorFormat';
Expand Down Expand Up @@ -63,6 +64,7 @@ public function getMessage()
self::DISALLOW => 'Disallowed value was matched',
self::DIVISIBLE_BY => 'Is not divisible by %d',
self::ENUM => 'Does not have a value in the enumeration %s',
self::CONSTANT => 'Does not have a value equal to %s',
self::EXCLUSIVE_MINIMUM => 'Must have a minimum value greater than %d',
self::EXCLUSIVE_MAXIMUM => 'Must have a maximum value less than %d',
self::FORMAT_COLOR => 'Invalid color',
Expand Down
54 changes: 54 additions & 0 deletions src/JsonSchema/Constraints/ConstConstraint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?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\ConstraintError;
use JsonSchema\Entity\JsonPointer;

/**
* The ConstConstraint Constraints, validates an element against a constant value
*
* @author Martin Helmich <martin@helmich.me>
*/
class ConstConstraint extends Constraint
{
/**
* {@inheritdoc}
*/
public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
{
// Only validate const if the attribute exists
if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) {
return;
}
$const = $schema->const;

$type = gettype($element);
$constType = gettype($const);

if ($this->factory->getConfig(self::CHECK_MODE_TYPE_CAST) && $type == 'array' && $constType == 'object') {
if ((object) $element == $const) {
return;
}
}

if ($type === gettype($const)) {
if ($type == 'object') {
if ($element == $const) {
return;
}
} elseif ($element === $const) {
return;
}
}

$this->addError(ConstraintError::CONSTANT(), $path, array('const' => $schema->const));
}
}
16 changes: 16 additions & 0 deletions src/JsonSchema/Constraints/Constraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,22 @@ protected function checkEnum($value, $schema = null, JsonPointer $path = null, $
$this->addErrors($validator->getErrors());
}

/**
* Checks a const element
*
* @param mixed $value
* @param mixed $schema
* @param JsonPointer|null $path
* @param mixed $i
*/
protected function checkConst($value, $schema = null, JsonPointer $path = null, $i = null)
{
$validator = $this->factory->createInstanceFor('const');
$validator->check($value, $schema, $path, $i);

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

/**
* Checks format of an element
*
Expand Down
1 change: 1 addition & 0 deletions src/JsonSchema/Constraints/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class Factory
'string' => 'JsonSchema\Constraints\StringConstraint',
'number' => 'JsonSchema\Constraints\NumberConstraint',
'enum' => 'JsonSchema\Constraints\EnumConstraint',
'const' => 'JsonSchema\Constraints\ConstConstraint',
'format' => 'JsonSchema\Constraints\FormatConstraint',
'schema' => 'JsonSchema\Constraints\SchemaConstraint',
'validator' => 'JsonSchema\Validator'
Expand Down
5 changes: 5 additions & 0 deletions src/JsonSchema/Constraints/UndefinedConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ public function validateTypes(&$value, $schema = null, JsonPointer $path, $i = n
if (isset($schema->enum)) {
$this->checkEnum($value, $schema, $path, $i);
}

// check const
if (isset($schema->const)) {
$this->checkConst($value, $schema, $path, $i);
}
}

/**
Expand Down
43 changes: 42 additions & 1 deletion tests/Constraints/CoerciveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,48 @@ public function dataCoerceCases()
'string', 'integer', 42, true
);

$tests = array();
// #46 check coercion with "const"
$tests[] = array(
'{"properties":{"propertyOne":{"type":"string","const":"42"}}}',
'{"propertyOne":42}',
'integer', 'string', '42', true
);

// #47 check coercion with "const"
$tests[] = array(
'{"properties":{"propertyOne":{"type":"number","const":42}}}',
'{"propertyOne":"42"}',
'string', 'integer', 42, true
);

// #48 check boolean coercion with "const"
$tests[] = array(
'{"properties":{"propertyOne":{"type":"boolean","const":false}}}',
'{"propertyOne":"false"}',
'string', 'boolean', false, true
);

// #49 check boolean coercion with "const"
$tests[] = array(
'{"properties":{"propertyOne":{"type":"boolean","const":true}}}',
'{"propertyOne":"true"}',
'string', 'boolean', true, true
);

// #50 check boolean coercion with "const"
$tests[] = array(
'{"properties":{"propertyOne":{"type":"boolean","const":true}}}',
'{"propertyOne":1}',
'integer', 'boolean', true, true
);

// #51 check boolean coercion with "const"
$tests[] = array(
'{"properties":{"propertyOne":{"type":"boolean","const":false}}}',
'{"propertyOne":"false"}',
'string', 'boolean', false, true
);

foreach ($types as $toType => $testCases) {
foreach ($testCases as $testCase) {
$tests[] = array(
Expand Down
98 changes: 98 additions & 0 deletions tests/Constraints/ConstTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?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;

class ConstTest extends BaseTestCase
{
protected $schemaSpec = 'http://json-schema.org/draft-06/schema#';
protected $validateSchema = true;

public function getInvalidTests()
{
return array(
array(
'{"value":"foo"}',
'{
"type":"object",
"properties":{
"value":{"type":"string","const":"bar"}
},
"additionalProperties":false
}'
),
array(
'{"value":5}',
'{
"type":"object",
"properties":{
"value":{"type":"integer","const":6}
},
"additionalProperties":false
}'
),
array(
'{"value":false}',
'{
"type":"object",
"properties":{
"value":{"type":"boolean","const":true}
},
"additionalProperties":false
}'
),
);
}

public function getValidTests()
{
return array(
array(
'{"value":"bar"}',
'{
"type":"object",
"properties":{
"value":{"type":"string","const":"bar"}
},
"additionalProperties":false
}'
),
array(
'{"value":false}',
'{
"type":"object",
"properties":{
"value":{"type":"boolean","const":false}
},
"additionalProperties":false
}'
),
array(
'{"value":true}',
'{
"type":"object",
"properties":{
"value":{"type":"boolean","const":true}
},
"additionalProperties":false
}'
),
array(
'{"value":5}',
'{
"type":"object",
"properties":{
"value":{"type":"integer","const":5}
},
"additionalProperties":false
}'
),
);
}
}

0 comments on commit a4bf903

Please sign in to comment.