Skip to content

Commit 42411d8

Browse files
committed
Add remaining coercion cases & rewrite tests
* Add all remaining coercion cases from ajv matrix * Rewrite the coercion tests to tidy things up a bit
1 parent 79b5881 commit 42411d8

File tree

3 files changed

+252
-256
lines changed

3 files changed

+252
-256
lines changed

src/JsonSchema/Constraints/TypeConstraint.php

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ public function check(&$value = null, $schema = null, JsonPointer $path = null,
6969
$wording[] = self::$wording[$type];
7070
}
7171
$this->addError(ConstraintError::TYPE(), $path, array(
72-
'expected' => gettype($value),
73-
'found' => $this->implodeWith($wording, ', ', 'or')
72+
'found' => gettype($value),
73+
'expected' => $this->implodeWith($wording, ', ', 'or')
7474
));
7575
}
7676
}
@@ -185,6 +185,10 @@ protected function validateType(&$value, $type, $coerce = false)
185185
}
186186

187187
if ('array' === $type) {
188+
if ($coerce) {
189+
$value = $this->toArray($value);
190+
}
191+
188192
return $this->getTypeCheck()->isArray($value);
189193
}
190194

@@ -213,6 +217,10 @@ protected function validateType(&$value, $type, $coerce = false)
213217
}
214218

215219
if ('string' === $type) {
220+
if ($coerce) {
221+
$value = $this->toString($value);
222+
}
223+
216224
return is_string($value);
217225
}
218226

@@ -221,6 +229,10 @@ protected function validateType(&$value, $type, $coerce = false)
221229
}
222230

223231
if ('null' === $type) {
232+
if ($coerce) {
233+
$value = $this->toNull($value);
234+
}
235+
224236
return is_null($value);
225237
}
226238

@@ -236,19 +248,21 @@ protected function validateType(&$value, $type, $coerce = false)
236248
*/
237249
protected function toBoolean($value)
238250
{
239-
if ($value === 'true') {
251+
if ($value === 1 || $value === 'true') {
240252
return true;
241253
}
242-
243-
if ($value === 'false') {
254+
if (is_null($value) || $value === 0 || $value === 'false') {
244255
return false;
245256
}
257+
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
258+
return $this->toBoolean(reset($value));
259+
}
246260

247261
return $value;
248262
}
249263

250264
/**
251-
* Converts a numeric string to a number. For example, "4" becomes 4.
265+
* Converts a value to a number. For example, "4.5" becomes 4.5.
252266
*
253267
* @param mixed $value the value to convert to a number
254268
*
@@ -259,14 +273,89 @@ protected function toNumber($value)
259273
if (is_numeric($value)) {
260274
return $value + 0; // cast to number
261275
}
276+
if (is_bool($value) || is_null($value)) {
277+
return (int) $value;
278+
}
279+
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
280+
return $this->toNumber(reset($value));
281+
}
262282

263283
return $value;
264284
}
265285

286+
/**
287+
* Converts a value to an integer. For example, "4" becomes 4.
288+
*
289+
* @param mixed $value
290+
*
291+
* @return int|mixed
292+
*/
266293
protected function toInteger($value)
267294
{
268-
if (is_numeric($value) && (int) $value == $value) {
269-
return (int) $value; // cast to number
295+
$numberValue = $this->toNumber($value);
296+
if (is_numeric($numberValue) && (int) $numberValue == $numberValue) {
297+
return (int) $numberValue; // cast to number
298+
}
299+
300+
return $value;
301+
}
302+
303+
/**
304+
* Converts a value to an array containing that value. For example, [4] becomes 4.
305+
*
306+
* @param mixed $value
307+
*
308+
* @return array|mixed
309+
*/
310+
protected function toArray($value)
311+
{
312+
if (is_scalar($value) || is_null($value)) {
313+
return array($value);
314+
}
315+
316+
return $value;
317+
}
318+
319+
/**
320+
* Convert a value to a string representation of that value. For example, null becomes "".
321+
*
322+
* @param mixed $value
323+
*
324+
* @return string|mixed
325+
*/
326+
protected function toString($value)
327+
{
328+
if (is_numeric($value)) {
329+
return "$value";
330+
}
331+
if ($value === true) {
332+
return 'true';
333+
}
334+
if ($value === false) {
335+
return 'false';
336+
}
337+
if (is_null($value)) {
338+
return '';
339+
}
340+
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
341+
return $this->toString(reset($value));
342+
}
343+
}
344+
345+
/**
346+
* Convert a value to a null. For example, 0 becomes null.
347+
*
348+
* @param mixed $value
349+
*
350+
* @return null|mixed
351+
*/
352+
protected function toNull($value)
353+
{
354+
if ($value === 0 || $value === false || $value === '') {
355+
return null;
356+
}
357+
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
358+
return $this->toNull(reset($value));
270359
}
271360

272361
return $value;

0 commit comments

Comments
 (0)