Skip to content

Commit a4bf903

Browse files
authored
Merge pull request #507 from martin-helmich/feature/const-support
Add support for "const"
2 parents e0b253f + 8a9cd12 commit a4bf903

File tree

7 files changed

+218
-1
lines changed

7 files changed

+218
-1
lines changed

src/JsonSchema/ConstraintError.php

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class ConstraintError extends Enum
1414
const DISALLOW = 'disallow';
1515
const DIVISIBLE_BY = 'divisibleBy';
1616
const ENUM = 'enum';
17+
const CONSTANT = 'const';
1718
const EXCLUSIVE_MINIMUM = 'exclusiveMinimum';
1819
const EXCLUSIVE_MAXIMUM = 'exclusiveMaximum';
1920
const FORMAT_COLOR = 'colorFormat';
@@ -63,6 +64,7 @@ public function getMessage()
6364
self::DISALLOW => 'Disallowed value was matched',
6465
self::DIVISIBLE_BY => 'Is not divisible by %d',
6566
self::ENUM => 'Does not have a value in the enumeration %s',
67+
self::CONSTANT => 'Does not have a value equal to %s',
6668
self::EXCLUSIVE_MINIMUM => 'Must have a minimum value greater than %d',
6769
self::EXCLUSIVE_MAXIMUM => 'Must have a maximum value less than %d',
6870
self::FORMAT_COLOR => 'Invalid color',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the JsonSchema package.
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace JsonSchema\Constraints;
11+
12+
use JsonSchema\ConstraintError;
13+
use JsonSchema\Entity\JsonPointer;
14+
15+
/**
16+
* The ConstConstraint Constraints, validates an element against a constant value
17+
*
18+
* @author Martin Helmich <martin@helmich.me>
19+
*/
20+
class ConstConstraint extends Constraint
21+
{
22+
/**
23+
* {@inheritdoc}
24+
*/
25+
public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
26+
{
27+
// Only validate const if the attribute exists
28+
if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) {
29+
return;
30+
}
31+
$const = $schema->const;
32+
33+
$type = gettype($element);
34+
$constType = gettype($const);
35+
36+
if ($this->factory->getConfig(self::CHECK_MODE_TYPE_CAST) && $type == 'array' && $constType == 'object') {
37+
if ((object) $element == $const) {
38+
return;
39+
}
40+
}
41+
42+
if ($type === gettype($const)) {
43+
if ($type == 'object') {
44+
if ($element == $const) {
45+
return;
46+
}
47+
} elseif ($element === $const) {
48+
return;
49+
}
50+
}
51+
52+
$this->addError(ConstraintError::CONSTANT(), $path, array('const' => $schema->const));
53+
}
54+
}

src/JsonSchema/Constraints/Constraint.php

+16
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,22 @@ protected function checkEnum($value, $schema = null, JsonPointer $path = null, $
169169
$this->addErrors($validator->getErrors());
170170
}
171171

172+
/**
173+
* Checks a const element
174+
*
175+
* @param mixed $value
176+
* @param mixed $schema
177+
* @param JsonPointer|null $path
178+
* @param mixed $i
179+
*/
180+
protected function checkConst($value, $schema = null, JsonPointer $path = null, $i = null)
181+
{
182+
$validator = $this->factory->createInstanceFor('const');
183+
$validator->check($value, $schema, $path, $i);
184+
185+
$this->addErrors($validator->getErrors());
186+
}
187+
172188
/**
173189
* Checks format of an element
174190
*

src/JsonSchema/Constraints/Factory.php

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class Factory
5858
'string' => 'JsonSchema\Constraints\StringConstraint',
5959
'number' => 'JsonSchema\Constraints\NumberConstraint',
6060
'enum' => 'JsonSchema\Constraints\EnumConstraint',
61+
'const' => 'JsonSchema\Constraints\ConstConstraint',
6162
'format' => 'JsonSchema\Constraints\FormatConstraint',
6263
'schema' => 'JsonSchema\Constraints\SchemaConstraint',
6364
'validator' => 'JsonSchema\Validator'

src/JsonSchema/Constraints/UndefinedConstraint.php

+5
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ public function validateTypes(&$value, $schema = null, JsonPointer $path, $i = n
9696
if (isset($schema->enum)) {
9797
$this->checkEnum($value, $schema, $path, $i);
9898
}
99+
100+
// check const
101+
if (isset($schema->const)) {
102+
$this->checkConst($value, $schema, $path, $i);
103+
}
99104
}
100105

101106
/**

tests/Constraints/CoerciveTest.php

+42-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,48 @@ public function dataCoerceCases()
130130
'string', 'integer', 42, true
131131
);
132132

133-
$tests = array();
133+
// #46 check coercion with "const"
134+
$tests[] = array(
135+
'{"properties":{"propertyOne":{"type":"string","const":"42"}}}',
136+
'{"propertyOne":42}',
137+
'integer', 'string', '42', true
138+
);
139+
140+
// #47 check coercion with "const"
141+
$tests[] = array(
142+
'{"properties":{"propertyOne":{"type":"number","const":42}}}',
143+
'{"propertyOne":"42"}',
144+
'string', 'integer', 42, true
145+
);
146+
147+
// #48 check boolean coercion with "const"
148+
$tests[] = array(
149+
'{"properties":{"propertyOne":{"type":"boolean","const":false}}}',
150+
'{"propertyOne":"false"}',
151+
'string', 'boolean', false, true
152+
);
153+
154+
// #49 check boolean coercion with "const"
155+
$tests[] = array(
156+
'{"properties":{"propertyOne":{"type":"boolean","const":true}}}',
157+
'{"propertyOne":"true"}',
158+
'string', 'boolean', true, true
159+
);
160+
161+
// #50 check boolean coercion with "const"
162+
$tests[] = array(
163+
'{"properties":{"propertyOne":{"type":"boolean","const":true}}}',
164+
'{"propertyOne":1}',
165+
'integer', 'boolean', true, true
166+
);
167+
168+
// #51 check boolean coercion with "const"
169+
$tests[] = array(
170+
'{"properties":{"propertyOne":{"type":"boolean","const":false}}}',
171+
'{"propertyOne":"false"}',
172+
'string', 'boolean', false, true
173+
);
174+
134175
foreach ($types as $toType => $testCases) {
135176
foreach ($testCases as $testCase) {
136177
$tests[] = array(

tests/Constraints/ConstTest.php

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the JsonSchema package.
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace JsonSchema\Tests\Constraints;
11+
12+
class ConstTest extends BaseTestCase
13+
{
14+
protected $schemaSpec = 'http://json-schema.org/draft-06/schema#';
15+
protected $validateSchema = true;
16+
17+
public function getInvalidTests()
18+
{
19+
return array(
20+
array(
21+
'{"value":"foo"}',
22+
'{
23+
"type":"object",
24+
"properties":{
25+
"value":{"type":"string","const":"bar"}
26+
},
27+
"additionalProperties":false
28+
}'
29+
),
30+
array(
31+
'{"value":5}',
32+
'{
33+
"type":"object",
34+
"properties":{
35+
"value":{"type":"integer","const":6}
36+
},
37+
"additionalProperties":false
38+
}'
39+
),
40+
array(
41+
'{"value":false}',
42+
'{
43+
"type":"object",
44+
"properties":{
45+
"value":{"type":"boolean","const":true}
46+
},
47+
"additionalProperties":false
48+
}'
49+
),
50+
);
51+
}
52+
53+
public function getValidTests()
54+
{
55+
return array(
56+
array(
57+
'{"value":"bar"}',
58+
'{
59+
"type":"object",
60+
"properties":{
61+
"value":{"type":"string","const":"bar"}
62+
},
63+
"additionalProperties":false
64+
}'
65+
),
66+
array(
67+
'{"value":false}',
68+
'{
69+
"type":"object",
70+
"properties":{
71+
"value":{"type":"boolean","const":false}
72+
},
73+
"additionalProperties":false
74+
}'
75+
),
76+
array(
77+
'{"value":true}',
78+
'{
79+
"type":"object",
80+
"properties":{
81+
"value":{"type":"boolean","const":true}
82+
},
83+
"additionalProperties":false
84+
}'
85+
),
86+
array(
87+
'{"value":5}',
88+
'{
89+
"type":"object",
90+
"properties":{
91+
"value":{"type":"integer","const":5}
92+
},
93+
"additionalProperties":false
94+
}'
95+
),
96+
);
97+
}
98+
}

0 commit comments

Comments
 (0)