Skip to content

Commit d9602dd

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 18715e5 commit d9602dd

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,10 +217,18 @@ 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

219227
if ('null' === $type) {
228+
if ($coerce) {
229+
$value = $this->toNull($value);
230+
}
231+
220232
return is_null($value);
221233
}
222234

@@ -232,19 +244,21 @@ protected function validateType(&$value, $type, $coerce = false)
232244
*/
233245
protected function toBoolean($value)
234246
{
235-
if ($value === 'true') {
247+
if ($value === 1 || $value === 'true') {
236248
return true;
237249
}
238-
239-
if ($value === 'false') {
250+
if (is_null($value) || $value === 0 || $value === 'false') {
240251
return false;
241252
}
253+
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
254+
return $this->toBoolean(reset($value));
255+
}
242256

243257
return $value;
244258
}
245259

246260
/**
247-
* Converts a numeric string to a number. For example, "4" becomes 4.
261+
* Converts a value to a number. For example, "4.5" becomes 4.5.
248262
*
249263
* @param mixed $value the value to convert to a number
250264
*
@@ -255,14 +269,89 @@ protected function toNumber($value)
255269
if (is_numeric($value)) {
256270
return $value + 0; // cast to number
257271
}
272+
if (is_bool($value) || is_null($value)) {
273+
return (int) $value;
274+
}
275+
if ($this->getTypeCheck()->isArray($value) && count($value) === 1) {
276+
return $this->toNumber(reset($value));
277+
}
258278

259279
return $value;
260280
}
261281

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

268357
return $value;

0 commit comments

Comments
 (0)