Skip to content

Commit d98033f

Browse files
committed
Merge pull request #104 from hakre/patch-1
Constraint::check() uses wrong indefinite article in error message to express the type constraint
2 parents 3bf210b + 069fec2 commit d98033f

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

src/JsonSchema/Constraints/Type.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace JsonSchema\Constraints;
1111

1212
use JsonSchema\Exception\InvalidArgumentException;
13+
use UnexpectedValueException as StandardUnexpectedValueException;
1314

1415
/**
1516
* The Type Constraints, validates an element against a given type
@@ -19,6 +20,21 @@
1920
*/
2021
class Type extends Constraint
2122
{
23+
/**
24+
* @var array|string[] type wordings for validation error messages
25+
*/
26+
static $wording = array(
27+
'integer' => 'an integer',
28+
'number' => 'a number',
29+
'boolean' => 'a boolean',
30+
'object' => 'an object',
31+
'array' => 'an array',
32+
'string' => 'a string',
33+
'null' => 'a null',
34+
'any' => NULL, // validation of 'any' is always true so is not needed in message wording
35+
0 => NULL, // validation of a false-y value is always true, so not needed as well
36+
);
37+
2238
/**
2339
* {@inheritDoc}
2440
*/
@@ -56,7 +72,15 @@ public function check($value = null, $schema = null, $path = null, $i = null)
5672
}
5773

5874
if ($isValid === false) {
59-
$this->addError($path, gettype($value) . " value found, but a " . $type . " is required");
75+
if (!isset(self::$wording[$type])) {
76+
throw new StandardUnexpectedValueException(
77+
sprintf(
78+
"No wording for %s available, expected wordings are: [%s]",
79+
var_export($type, true),
80+
implode(', ', array_filter(self::$wording)))
81+
);
82+
}
83+
$this->addError($path, gettype($value) . " value found, but " . self::$wording[$type] . " is required");
6084
}
6185
}
6286

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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+
use JsonSchema\Constraints\Type;
13+
14+
/**
15+
* Class TypeTest
16+
*
17+
* @package JsonSchema\Tests\Constraints
18+
* @author hakre <https://github.com/hakre>
19+
*/
20+
class TypeTest extends \PHPUnit_Framework_TestCase
21+
{
22+
/**
23+
* @see testIndefiniteArticleForTypeInTypeCheckErrorMessage
24+
* @return array
25+
*/
26+
public function provideIndefiniteArticlesForTypes()
27+
{
28+
return array(
29+
array('integer', 'an',),
30+
array('number', 'a',),
31+
array('boolean', 'a',),
32+
array('object', 'an',),
33+
array('array', 'an',),
34+
array('string', 'a',),
35+
array('null', 'a', array(), 'array',),
36+
);
37+
}
38+
39+
/**
40+
* @dataProvider provideIndefiniteArticlesForTypes
41+
*/
42+
public function testIndefiniteArticleForTypeInTypeCheckErrorMessage($type, $wording, $value = null, $label = 'NULL')
43+
{
44+
$constraint = new Type();
45+
$constraint->check($value, (object)array('type' => $type));
46+
$this->assertTypeConstraintError("$label value found, but $wording $type is required", $constraint);
47+
}
48+
49+
/**
50+
* Helper to assert an error message
51+
*
52+
* @param string $expected
53+
* @param Type $actual
54+
*/
55+
private function assertTypeConstraintError($expected, Type $actual)
56+
{
57+
$actualErrors = $actual->getErrors();
58+
59+
$this->assertCount(1, $actualErrors, "Failed to assert that Type has exactly one error to assert the error message against.");
60+
61+
$actualError = $actualErrors[0];
62+
63+
$this->assertInternalType('array', $actualError, sprintf('Failed to assert that Type error is an array, %s given', gettype($actualError)));
64+
65+
$messageKey = 'message';
66+
$this->assertArrayHasKey(
67+
$messageKey, $actualError,
68+
sprintf('Failed to assert that Type error has a message key %s.', var_export($messageKey, true))
69+
);
70+
71+
$actualMessage = $actualError[$messageKey];
72+
73+
$this->assertEquals($expected, $actualMessage); // first equal for the diff
74+
$this->assertSame($expected, $actualMessage); // the same for the strictness
75+
}
76+
}

0 commit comments

Comments
 (0)