diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 91271e1..7c4d94c 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -799,7 +799,14 @@ class Executor private static function completeLeafValue(Type $returnType, &$result) { Utils::invariant(method_exists($returnType, 'serialize'), 'Missing serialize method on type'); - return $returnType->serialize($result); + $serializedResult = $returnType->serialize($result); + + if ($serializedResult === null) { + throw new \UnexpectedValueException( + 'Expected a value of type "'. $returnType . '" but received: ' . Utils::printSafe($result) + ); + } + return $serializedResult; } /** diff --git a/src/Type/Definition/FloatType.php b/src/Type/Definition/FloatType.php index 7beb1df..522d507 100644 --- a/src/Type/Definition/FloatType.php +++ b/src/Type/Definition/FloatType.php @@ -3,6 +3,7 @@ namespace GraphQL\Type\Definition; use GraphQL\Language\AST\FloatValue; use GraphQL\Language\AST\IntValue; +use GraphQL\Utils; /** * Class FloatType @@ -47,7 +48,15 @@ values as specified by */ private function coerceFloat($value) { - return is_numeric($value) || $value === true || $value === false ? (float) $value : null; + if ($value === '') { + throw new \UnexpectedValueException( + 'Float cannot represent non numeric value: (empty string)' + ); + } + if (is_numeric($value) || $value === true || $value === false) { + return (float)$value; + } + throw new \UnexpectedValueException('Float cannot represent non numeric value: ' . Utils::printSafe($value)); } /** diff --git a/src/Type/Definition/IntType.php b/src/Type/Definition/IntType.php index 77a04ed..b36cca8 100644 --- a/src/Type/Definition/IntType.php +++ b/src/Type/Definition/IntType.php @@ -3,6 +3,7 @@ namespace GraphQL\Type\Definition; use GraphQL\Language\AST\IntValue; use GraphQL\Language\AST\Value; +use GraphQL\Utils; /** * Class IntType @@ -54,13 +55,20 @@ values. Int can represent values between -(2^31) and 2^31 - 1. '; */ private function coerceInt($value) { + if ($value === '') { + throw new \UnexpectedValueException( + 'Int cannot represent non 32-bit signed integer value: (empty string)' + ); + } if (false === $value || true === $value) { return (int) $value; } if (is_numeric($value) && $value <= self::MAX_INT && $value >= self::MIN_INT) { return (int) $value; } - return null; + throw new \UnexpectedValueException( + 'Int cannot represent non 32-bit signed integer value: ' . Utils::printSafe($value) + ); } /** diff --git a/tests/Type/ScalarSerializationTest.php b/tests/Type/ScalarSerializationTest.php index 21f0864..cd95daf 100644 --- a/tests/Type/ScalarSerializationTest.php +++ b/tests/Type/ScalarSerializationTest.php @@ -15,6 +15,7 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase $intType = Type::int(); $this->assertSame(1, $intType->serialize(1)); + $this->assertSame(123, $intType->serialize('123')); $this->assertSame(0, $intType->serialize(0)); $this->assertSame(-1, $intType->serialize(-1)); $this->assertSame(0, $intType->serialize(0.1)); @@ -23,12 +24,50 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase $this->assertSame(100000, $intType->serialize(1e5)); // Maybe a safe PHP int, but bigger than 2^32, so not // representable as a GraphQL Int - $this->assertSame(null, $intType->serialize(9876504321)); - $this->assertSame(null, $intType->serialize(-9876504321)); - $this->assertSame(null, $intType->serialize(1e100)); - $this->assertSame(null, $intType->serialize(-1e100)); + try { + $intType->serialize(9876504321); + $this->fail('Expected exception was not thrown'); + } catch (\UnexpectedValueException $e) { + $this->assertEquals('Int cannot represent non 32-bit signed integer value: 9876504321', $e->getMessage()); + } + + try { + $intType->serialize(-9876504321); + $this->fail('Expected exception was not thrown'); + } catch (\UnexpectedValueException $e) { + $this->assertEquals('Int cannot represent non 32-bit signed integer value: -9876504321', $e->getMessage()); + } + + try { + $intType->serialize(1e100); + $this->fail('Expected exception was not thrown'); + } catch (\UnexpectedValueException $e) { + $this->assertEquals('Int cannot represent non 32-bit signed integer value: 1.0E+100', $e->getMessage()); + } + + try { + $intType->serialize(-1e100); + $this->fail('Expected exception was not thrown'); + } catch (\UnexpectedValueException $e) { + $this->assertEquals('Int cannot represent non 32-bit signed integer value: -1.0E+100', $e->getMessage()); + } + $this->assertSame(-1, $intType->serialize('-1.1')); - $this->assertSame(null, $intType->serialize('one')); + + try { + $intType->serialize('one'); + $this->fail('Expected exception was not thrown'); + } catch (\UnexpectedValueException $e) { + $this->assertEquals('Int cannot represent non 32-bit signed integer value: one', $e->getMessage()); + } + + try { + $intType->serialize(''); + $this->fail('Expected exception was not thrown'); + } catch (\UnexpectedValueException $e) { + $this->assertEquals('Int cannot represent non 32-bit signed integer value: (empty string)', $e->getMessage()); + } + $this->assertSame(0, $intType->serialize(false)); $this->assertSame(1, $intType->serialize(true)); } @@ -42,12 +81,27 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase $this->assertSame(1.0, $floatType->serialize(1)); $this->assertSame(0.0, $floatType->serialize(0)); + $this->assertSame(123.5, $floatType->serialize('123.5')); $this->assertSame(-1.0, $floatType->serialize(-1)); $this->assertSame(0.1, $floatType->serialize(0.1)); $this->assertSame(1.1, $floatType->serialize(1.1)); $this->assertSame(-1.1, $floatType->serialize(-1.1)); $this->assertSame(-1.1, $floatType->serialize('-1.1')); - $this->assertSame(null, $floatType->serialize('one')); + + try { + $floatType->serialize('one'); + $this->fail('Expected exception was not thrown'); + } catch (\UnexpectedValueException $e) { + $this->assertEquals('Float cannot represent non numeric value: one', $e->getMessage()); + } + + try { + $floatType->serialize(''); + $this->fail('Expected exception was not thrown'); + } catch (\UnexpectedValueException $e) { + $this->assertEquals('Float cannot represent non numeric value: (empty string)', $e->getMessage()); + } + $this->assertSame(0.0, $floatType->serialize(false)); $this->assertSame(1.0, $floatType->serialize(true)); } @@ -81,6 +135,6 @@ class ScalarSerializationTest extends \PHPUnit_Framework_TestCase $this->assertSame(true, $boolType->serialize(true)); $this->assertSame(false, $boolType->serialize(false)); - // TODO: how should it behaive on '0'? + // TODO: how should it behave on '0'? } }