Merge branch '4.4'
* 4.4: Fix an error message to be more accurate
This commit is contained in:
commit
3483d9a9ee
@ -919,7 +919,7 @@ class OptionsResolver implements Options
|
|||||||
|
|
||||||
// Validate the type of the resolved option
|
// Validate the type of the resolved option
|
||||||
if (isset($this->allowedTypes[$option])) {
|
if (isset($this->allowedTypes[$option])) {
|
||||||
$valid = false;
|
$valid = true;
|
||||||
$invalidTypes = [];
|
$invalidTypes = [];
|
||||||
|
|
||||||
foreach ($this->allowedTypes[$option] as $type) {
|
foreach ($this->allowedTypes[$option] as $type) {
|
||||||
@ -931,13 +931,18 @@ class OptionsResolver implements Options
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$valid) {
|
if (!$valid) {
|
||||||
$keys = array_keys($invalidTypes);
|
$fmtActualValue = $this->formatValue($value);
|
||||||
|
$fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]);
|
||||||
|
$fmtProvidedTypes = implode('|', array_keys($invalidTypes));
|
||||||
|
$allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static function ($item) {
|
||||||
|
return '[]' === substr(self::$typeAliases[$item] ?? $item, -2);
|
||||||
|
})) > 0;
|
||||||
|
|
||||||
if (1 === \count($keys) && '[]' === substr($keys[0], -2)) {
|
if (\is_array($value) && $allowedContainsArrayType) {
|
||||||
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $this->formatOptions([$option]), $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), $keys[0]));
|
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $this->formatOptions([$option]), $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $this->formatOptions([$option]), $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), implode('|', array_keys($invalidTypes))));
|
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $this->formatOptions([$option]), $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,26 +1047,23 @@ class OptionsResolver implements Options
|
|||||||
{
|
{
|
||||||
if (\is_array($value) && '[]' === substr($type, -2)) {
|
if (\is_array($value) && '[]' === substr($type, -2)) {
|
||||||
$type = substr($type, 0, -2);
|
$type = substr($type, 0, -2);
|
||||||
|
$valid = true;
|
||||||
|
|
||||||
foreach ($value as $val) {
|
foreach ($value as $val) {
|
||||||
if (!$this->verifyTypes($type, $val, $invalidTypes, $level + 1)) {
|
if (!$this->verifyTypes($type, $val, $invalidTypes, $level + 1)) {
|
||||||
return false;
|
$valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return $valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (('null' === $type && null === $value) || (\function_exists($func = 'is_'.$type) && $func($value)) || $value instanceof $type) {
|
if (('null' === $type && null === $value) || (\function_exists($func = 'is_'.$type) && $func($value)) || $value instanceof $type) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$invalidTypes) {
|
if (!$invalidTypes || $level > 0) {
|
||||||
$suffix = '';
|
$invalidTypes[$this->formatTypeOf($value)] = true;
|
||||||
while (\strlen($suffix) < $level * 2) {
|
|
||||||
$suffix .= '[]';
|
|
||||||
}
|
|
||||||
$invalidTypes[$this->formatTypeOf($value).$suffix] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -776,7 +776,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testResolveFailsIfInvalidTypedArray()
|
public function testResolveFailsIfInvalidTypedArray()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime[]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'int[]');
|
$this->resolver->setAllowedTypes('foo', 'int[]');
|
||||||
|
|
||||||
@ -796,7 +796,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testResolveFailsIfTypedArrayContainsInvalidTypes()
|
public function testResolveFailsIfTypedArrayContainsInvalidTypes()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass[]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass|array|DateTime".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'int[]');
|
$this->resolver->setAllowedTypes('foo', 'int[]');
|
||||||
$values = range(1, 5);
|
$values = range(1, 5);
|
||||||
@ -811,7 +811,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testResolveFailsWithCorrectLevelsButWrongScalar()
|
public function testResolveFailsWithCorrectLevelsButWrongScalar()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double[][]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'int[][]');
|
$this->resolver->setAllowedTypes('foo', 'int[][]');
|
||||||
|
|
||||||
@ -847,6 +847,11 @@ class OptionsResolverTest extends TestCase
|
|||||||
[42, 'string', 'The option "option" with value 42 is expected to be of type "string", but is of type "integer".'],
|
[42, 'string', 'The option "option" with value 42 is expected to be of type "string", but is of type "integer".'],
|
||||||
[null, 'string', 'The option "option" with value null is expected to be of type "string", but is of type "NULL".'],
|
[null, 'string', 'The option "option" with value null is expected to be of type "string", but is of type "NULL".'],
|
||||||
['bar', '\stdClass', 'The option "option" with value "bar" is expected to be of type "\stdClass", but is of type "string".'],
|
['bar', '\stdClass', 'The option "option" with value "bar" is expected to be of type "\stdClass", but is of type "string".'],
|
||||||
|
[['foo', 12], 'string[]', 'The option "option" with value array is expected to be of type "string[]", but one of the elements is of type "integer".'],
|
||||||
|
[123, ['string[]', 'string'], 'The option "option" with value 123 is expected to be of type "string[]" or "string", but is of type "integer".'],
|
||||||
|
[[null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'],
|
||||||
|
[['string', null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'],
|
||||||
|
[[\stdClass::class], ['string'], 'The option "option" with value array is expected to be of type "string", but is of type "array".'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1898,7 +1903,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testNestedArraysException()
|
public function testNestedArraysException()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer[][][][]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'float[][][][]');
|
$this->resolver->setAllowedTypes('foo', 'float[][][][]');
|
||||||
|
|
||||||
@ -1916,7 +1921,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testNestedArrayException1()
|
public function testNestedArrayException1()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'int[][]');
|
$this->resolver->setAllowedTypes('foo', 'int[][]');
|
||||||
$this->resolver->resolve([
|
$this->resolver->resolve([
|
||||||
@ -1929,7 +1934,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testNestedArrayException2()
|
public function testNestedArrayException2()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'int[][]');
|
$this->resolver->setAllowedTypes('foo', 'int[][]');
|
||||||
$this->resolver->resolve([
|
$this->resolver->resolve([
|
||||||
@ -1942,7 +1947,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testNestedArrayException3()
|
public function testNestedArrayException3()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string[][]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string|integer".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'string[][][]');
|
$this->resolver->setAllowedTypes('foo', 'string[][][]');
|
||||||
$this->resolver->resolve([
|
$this->resolver->resolve([
|
||||||
@ -1955,7 +1960,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testNestedArrayException4()
|
public function testNestedArrayException4()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer[][][]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'string[][][]');
|
$this->resolver->setAllowedTypes('foo', 'string[][][]');
|
||||||
$this->resolver->resolve([
|
$this->resolver->resolve([
|
||||||
@ -1969,7 +1974,7 @@ class OptionsResolverTest extends TestCase
|
|||||||
public function testNestedArrayException5()
|
public function testNestedArrayException5()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException');
|
||||||
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array[]".');
|
$this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array".');
|
||||||
$this->resolver->setDefined('foo');
|
$this->resolver->setDefined('foo');
|
||||||
$this->resolver->setAllowedTypes('foo', 'string[]');
|
$this->resolver->setAllowedTypes('foo', 'string[]');
|
||||||
$this->resolver->resolve([
|
$this->resolver->resolve([
|
||||||
|
Reference in New Issue
Block a user