Breaking change when returning Closure from resolver: this closure is expected to have different signature now (shouldn't affect most of the users)

This commit is contained in:
vladar 2016-10-18 22:20:51 +07:00
parent a94640f9d2
commit 89eb6dede9
3 changed files with 63 additions and 5 deletions

View File

@ -8,17 +8,56 @@ and methods.
Example before the change: Example before the change:
```php ```php
GraphQL\Schema::$_queryType GraphQL\Schema::$_queryType;
``` ```
Correct usage after the change: Correct usage after the change:
```php ```php
GraphQL\Schema::$queryType GraphQL\Schema::$queryType;
``` ```
So if you rely on any protected properties or methods of any GraphQL class, make sure to So if you rely on any protected properties or methods of any GraphQL class, make sure to
delete leading underscores. 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 ## Upgrade v0.6.x > v0.7.x

View File

@ -649,12 +649,11 @@ class Executor
throw new \RuntimeException("Cannot complete value of unexpected type \"{$returnType}\"."); throw new \RuntimeException("Cannot complete value of unexpected type \"{$returnType}\".");
} }
/** /**
* If a resolve function is not given, then a default resolve behavior is used * 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 * 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 * 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) 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;
} }
/** /**

View File

@ -6,6 +6,8 @@ use GraphQL\Schema;
use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
require_once __DIR__ . '/TestClasses.php';
class ResolveTest extends \PHPUnit_Framework_TestCase class ResolveTest extends \PHPUnit_Framework_TestCase
{ {
// Execute: resolve function // 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 * @it uses provided resolve function
*/ */