Skip to content

Commit

Permalink
Add string coercion cases from ajv matrix
Browse files Browse the repository at this point in the history
  • Loading branch information
erayd committed Mar 13, 2017
1 parent a8af693 commit 584d05f
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 15 deletions.
48 changes: 37 additions & 11 deletions src/JsonSchema/Constraints/TypeConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ protected function validateType(&$value, $type, $coerce = false)
}

if ('string' === $type) {
if ($coerce) {
$value = $this->toString($value);
}

return is_string($value);
}

Expand Down Expand Up @@ -247,16 +251,14 @@ protected function toBoolean($value)
return false;
}
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
reset($value);

return $this->toBoolean(current($value));
return $this->toBoolean(reset($value));
}

return $value;
}

/**
* Converts a numeric string to a number. For example, "4" becomes 4.
* Converts a numeric string to a number. For example, "4.5" becomes 4.5.
*
* @param mixed $value the value to convert to a number
*
Expand All @@ -271,20 +273,18 @@ protected function toNumber($value)
return (int) $value;
}
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
reset($value);

return $this->toNumber(current($value));
return $this->toNumber(reset($value));
}

return $value;
}

/**
* Converts a value to an integer
* Converts a value to an integer. For example, "4" becomes 4.
*
* @param mixed $value
*
* @return mixed
* @return int|mixed
*/
protected function toInteger($value)
{
Expand All @@ -297,11 +297,11 @@ protected function toInteger($value)
}

/**
* Converts a value to an array containing that value
* Converts a value to an array containing that value. For example, [4] becomes 4.
*
* @param mixed $value
*
* @return array
* @return array|mixed
*/
protected function toArray($value)
{
Expand All @@ -311,4 +311,30 @@ protected function toArray($value)

return $value;
}

/**
* Convert a value to a string representation of that value. For example, null becomes "".
*
* @param mixed $value
*
* @return string|mixed
*/
protected function toString($value)
{
if (is_numeric($value)) {
return "$value";
}
if ($value === true) {
return 'true';
}
if ($value === false) {
return 'false';
}
if (is_null($value)) {
return '';
}
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
return $this->toString(reset($value));
}
}
}
59 changes: 55 additions & 4 deletions tests/Constraints/CoerciveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,35 @@ public function testValidCoerceCases($input, $schema, $errors = array())
$validator = new Validator(new Factory($schemaStorage, null, $checkMode));
$value = json_decode($input);

$this->assertTrue(gettype($value->string) == 'string');
$this->assertTrue(gettype($value->numberString) == 'integer');
$this->assertTrue(gettype($value->boolString) == 'boolean');
$this->assertTrue(gettype($value->boolFalseString) == 'boolean');
$this->assertTrue(gettype($value->nullString) == 'NULL');
$this->assertTrue(gettype($value->arrayString) == 'array');
$this->assertTrue(gettype($value->number) == 'string');
$this->assertTrue(gettype($value->boolNumber) == 'boolean');
$this->assertTrue(gettype($value->nullNumber) == 'NULL');
$this->assertTrue(gettype($value->arrayNumber) == 'array');
$this->assertTrue(gettype($value->integer) == 'string');
$this->assertTrue(gettype($value->negativeInteger) == 'string');
$this->assertTrue(gettype($value->boolean) == 'string');
$this->assertTrue(gettype($value->numberBoolean) == 'integer');
$this->assertTrue(gettype($value->nullBoolean) == 'NULL');
$this->assertTrue(gettype($value->arrayBoolean) == 'array');
$this->assertTrue(gettype($value->array) == 'string');
$this->assertTrue(gettype($value->numberArray) == 'integer');
$this->assertTrue(gettype($value->boolArray) == 'boolean');
$this->assertTrue(gettype($value->nullArray) == 'NULL');

$validator->validate($value, $schema, $checkMode);

$this->assertTrue(gettype($value->string) == 'string');
$this->assertTrue(gettype($value->numberString) == 'string');
$this->assertTrue(gettype($value->boolString) == 'string');
$this->assertTrue(gettype($value->boolFalseString) == 'string');
$this->assertTrue(gettype($value->nullString) == 'string');
$this->assertTrue(gettype($value->arrayString) == 'string');
$this->assertTrue(gettype($value->number) == 'double');
$this->assertTrue(gettype($value->boolNumber) == 'integer');
$this->assertTrue(gettype($value->nullNumber) == 'integer');
Expand All @@ -64,12 +87,22 @@ public function testValidCoerceCases($input, $schema, $errors = array())
$this->assertTrue(gettype($value->numberBoolean) == 'boolean');
$this->assertTrue(gettype($value->nullBoolean) == 'boolean');
$this->assertTrue(gettype($value->arrayBoolean) == 'boolean');
$this->assertTrue(gettype($value->array) == 'array');
$this->assertTrue(gettype($value->numberArray) == 'array');
$this->assertTrue(gettype($value->boolArray) == 'array');
$this->assertTrue(gettype($value->nullArray) == 'array');

$this->assertTrue(gettype($value->multitype1) == 'boolean');
$this->assertTrue(gettype($value->multitype2) == 'double');
$this->assertTrue(gettype($value->multitype3) == 'integer');
$this->assertTrue(gettype($value->multitype4) == 'string');

$this->assertTrue($value->string === 'string test');
$this->assertTrue($value->numberString === '45');
$this->assertTrue($value->boolString === 'true');
$this->assertTrue($value->boolFalseString === 'false');
$this->assertTrue($value->nullString === '');
$this->assertTrue($value->arrayString === '45');
$this->assertTrue($value->number === 1.5);
$this->assertTrue($value->boolNumber === 1);
$this->assertTrue($value->nullNumber === 0);
Expand All @@ -80,6 +113,10 @@ public function testValidCoerceCases($input, $schema, $errors = array())
$this->assertTrue($value->numberBoolean === true);
$this->assertTrue($value->nullBoolean === false);
$this->assertTrue($value->arrayBoolean === true);
$this->assertTrue($value->array === array('string'));
$this->assertTrue($value->numberArray === array(45));
$this->assertTrue($value->boolArray === array(true));
$this->assertTrue($value->nullArray === array(null));

$this->assertTrue($validator->isValid(), print_r($validator->getErrors(), true));
}
Expand Down Expand Up @@ -130,6 +167,11 @@ public function getValidCoerceTests()
array(
'{
"string":"string test",
"numberString":45,
"boolString":true,
"boolFalseString":false,
"nullString":null,
"arrayString":[45],
"number":"1.5",
"boolNumber":true,
"nullNumber":null,
Expand All @@ -141,9 +183,10 @@ public function getValidCoerceTests()
"nullBoolean":null,
"arrayBoolean":["true"],
"object":{},
"array":[],
"array":"string",
"numberArray":45,
"boolArray":true,
"nullArray":null,
"stringArray":"string",
"null":null,
"any": "string",
"allOf": "1",
Expand All @@ -164,6 +207,11 @@ public function getValidCoerceTests()
"type":"object",
"properties":{
"string":{"type":"string"},
"numberString":{"type":"string"},
"boolString":{"type":"string"},
"boolFalseString":{"type":"string"},
"nullString":{"type":"string"},
"arrayString":{"type":"string"},
"number":{"type":"number"},
"boolNumber":{"type":"number"},
"nullNumber":{"type":"number"},
Expand All @@ -176,8 +224,9 @@ public function getValidCoerceTests()
"arrayBoolean":{"type":"boolean"},
"object":{"type":"object"},
"array":{"type":"array"},
"numberArray":{"type":"array"},
"boolArray":{"type":"array"},
"nullArray":{"type":"array"},
"stringArray":{"type":"array"},
"null":{"type":"null"},
"any": {"type":"any"},
"allOf" : {"allOf":[{
Expand Down Expand Up @@ -220,7 +269,9 @@ public function getInvalidCoerceTests()
return array(
array( // #0
'{
"string":null
"string":{
"I am":"an object!"
}
}',
'{
"type":"object",
Expand Down

0 comments on commit 584d05f

Please sign in to comment.