From 89eb6dede9d8a8cbe8243372d343ee952278f306 Mon Sep 17 00:00:00 2001 From: vladar Date: Tue, 18 Oct 2016 22:20:51 +0700 Subject: [PATCH] Breaking change when returning Closure from resolver: this closure is expected to have different signature now (shouldn't affect most of the users) --- UPGRADE.md | 43 ++++++++++++++++++++++++++++++++-- src/Executor/Executor.php | 5 ++-- tests/Executor/ResolveTest.php | 20 ++++++++++++++++ 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index d875329..4ba9f44 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -8,17 +8,56 @@ and methods. Example before the change: ```php -GraphQL\Schema::$_queryType +GraphQL\Schema::$_queryType; ``` Correct usage after the change: ```php -GraphQL\Schema::$queryType +GraphQL\Schema::$queryType; ``` So if you rely on any protected properties or methods of any GraphQL class, make sure to delete leading underscores. +### 2. Returning closure from field resolver +Previously when you returned closure from any resolver, expected signature of this closure +was `function($sourceValue)`, new signature is `function($args, $context)` +(now mirrors reference graphql-js implementation) + +Before the change: +```php +new ObjectType([ + 'name' => 'Test', + 'fields' => [ + 'a' => [ + 'type' => Type::string(), + 'resolve' => function() { + return function($value) { + return 'something'; + } + } + ] + ] +]) + +``` +After the change: +```php +new ObjectType([ + 'name' => 'Test', + 'fields' => [ + 'a' => [ + 'type' => Type::string(), + 'resolve' => function() { + return function($args, $context) { + return 'something'; + } + } + ] + ] +]) +``` +(note the closure signature change) ## Upgrade v0.6.x > v0.7.x diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 831cbab..3a46f5e 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -649,12 +649,11 @@ class Executor throw new \RuntimeException("Cannot complete value of unexpected type \"{$returnType}\"."); } - /** * If a resolve function is not given, then a default resolve behavior is used * which takes the property of the source object of the same name as the field * and returns it as the result, or if it's a function, returns the result - * of calling that function. + * of calling that function while passing along args and context. */ public static function defaultResolveFn($source, $args, $context, ResolveInfo $info) { @@ -671,7 +670,7 @@ class Executor } } - return $property instanceof \Closure ? $property($source) : $property; + return $property instanceof \Closure ? $property($args, $context) : $property; } /** diff --git a/tests/Executor/ResolveTest.php b/tests/Executor/ResolveTest.php index 94fd5a2..f3f6cf4 100644 --- a/tests/Executor/ResolveTest.php +++ b/tests/Executor/ResolveTest.php @@ -6,6 +6,8 @@ use GraphQL\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; +require_once __DIR__ . '/TestClasses.php'; + class ResolveTest extends \PHPUnit_Framework_TestCase { // Execute: resolve function @@ -58,6 +60,24 @@ class ResolveTest extends \PHPUnit_Framework_TestCase ); } + /** + * @it default function passes args and context + */ + public function testDefaultFunctionPassesArgsAndContext() + { + $schema = $this->buildSchema([ + 'type' => Type::int(), + 'args' => [ + 'addend1' => [ 'type' => Type::int() ], + ], + ]); + + $source = new Adder(700); + + $result = GraphQL::execute($schema, '{ test(addend1: 80) }', $source, ['addend2' => 9]); + $this->assertEquals(['data' => ['test' => 789]], $result); + } + /** * @it uses provided resolve function */