graphql-php/tests/Executor/MutationsTest.php

233 lines
6.7 KiB
PHP
Raw Normal View History

2015-07-15 20:05:46 +03:00
<?php
2016-04-09 10:36:53 +03:00
namespace GraphQL\Tests\Executor;
2015-07-15 20:05:46 +03:00
2016-12-03 00:23:21 +03:00
use GraphQL\Deferred;
2016-11-26 22:48:49 +03:00
use GraphQL\Executor\ExecutionResult;
2016-04-09 10:36:53 +03:00
use GraphQL\Executor\Executor;
use GraphQL\Error\FormattedError;
2015-07-15 20:05:46 +03:00
use GraphQL\Language\Parser;
use GraphQL\Language\SourceLocation;
use GraphQL\Schema;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
class MutationsTest extends \PHPUnit_Framework_TestCase
{
// Execute: Handles mutation execution ordering
/**
* @it evaluates mutations serially
*/
2015-07-15 20:05:46 +03:00
public function testEvaluatesMutationsSerially()
{
$doc = 'mutation M {
first: immediatelyChangeTheNumber(newNumber: 1) {
theNumber
},
second: promiseToChangeTheNumber(newNumber: 2) {
theNumber
},
third: immediatelyChangeTheNumber(newNumber: 3) {
theNumber
}
fourth: promiseToChangeTheNumber(newNumber: 4) {
theNumber
},
fifth: immediatelyChangeTheNumber(newNumber: 5) {
theNumber
}
}';
$ast = Parser::parse($doc);
$mutationResult = Executor::execute($this->schema(), $ast, new Root(6));
2015-07-15 20:05:46 +03:00
$expected = [
'data' => [
'first' => [
'theNumber' => 1
],
'second' => [
'theNumber' => 2
],
'third' => [
'theNumber' => 3
],
'fourth' => [
'theNumber' => 4
],
'fifth' => [
'theNumber' => 5
]
]
];
2016-12-03 00:23:21 +03:00
$this->assertEquals($expected, $mutationResult->toArray());
2015-07-15 20:05:46 +03:00
}
/**
* @it evaluates mutations correctly in the presense of a failed mutation
*/
2015-07-15 20:05:46 +03:00
public function testEvaluatesMutationsCorrectlyInThePresenseOfAFailedMutation()
{
$doc = 'mutation M {
first: immediatelyChangeTheNumber(newNumber: 1) {
theNumber
},
second: promiseToChangeTheNumber(newNumber: 2) {
theNumber
},
third: failToChangeTheNumber(newNumber: 3) {
theNumber
}
fourth: promiseToChangeTheNumber(newNumber: 4) {
theNumber
},
fifth: immediatelyChangeTheNumber(newNumber: 5) {
theNumber
}
sixth: promiseAndFailToChangeTheNumber(newNumber: 6) {
theNumber
}
}';
$ast = Parser::parse($doc);
$mutationResult = Executor::execute($this->schema(), $ast, new Root(6));
2015-07-15 20:05:46 +03:00
$expected = [
'data' => [
'first' => [
'theNumber' => 1
],
'second' => [
'theNumber' => 2
],
'third' => null,
'fourth' => [
'theNumber' => 4
],
'fifth' => [
'theNumber' => 5
],
'sixth' => null,
],
'errors' => [
[
'debugMessage' => 'Cannot change the number',
'locations' => [['line' => 8, 'column' => 7]]
],
[
'debugMessage' => 'Cannot change the number',
'locations' => [['line' => 17, 'column' => 7]]
]
2015-07-15 20:05:46 +03:00
]
];
$this->assertArraySubset($expected, $mutationResult->toArray(true));
2015-07-15 20:05:46 +03:00
}
private function schema()
{
$numberHolderType = new ObjectType([
'fields' => [
'theNumber' => ['type' => Type::int()],
],
'name' => 'NumberHolder',
]);
$schema = new Schema([
'query' => new ObjectType([
2015-07-15 20:05:46 +03:00
'fields' => [
'numberHolder' => ['type' => $numberHolderType],
],
'name' => 'Query',
]),
'mutation' => new ObjectType([
2015-07-15 20:05:46 +03:00
'fields' => [
'immediatelyChangeTheNumber' => [
'type' => $numberHolderType,
'args' => ['newNumber' => ['type' => Type::int()]],
'resolve' => (function (Root $obj, $args) {
return $obj->immediatelyChangeTheNumber($args['newNumber']);
})
],
'promiseToChangeTheNumber' => [
'type' => $numberHolderType,
'args' => ['newNumber' => ['type' => Type::int()]],
'resolve' => (function (Root $obj, $args) {
return $obj->promiseToChangeTheNumber($args['newNumber']);
})
],
'failToChangeTheNumber' => [
'type' => $numberHolderType,
'args' => ['newNumber' => ['type' => Type::int()]],
'resolve' => (function (Root $obj, $args) {
return $obj->failToChangeTheNumber($args['newNumber']);
})
],
'promiseAndFailToChangeTheNumber' => [
'type' => $numberHolderType,
'args' => ['newNumber' => ['type' => Type::int()]],
'resolve' => (function (Root $obj, $args) {
return $obj->promiseAndFailToChangeTheNumber($args['newNumber']);
})
]
],
'name' => 'Mutation',
])
]);
2015-07-15 20:05:46 +03:00
return $schema;
}
}
class NumberHolder
{
public $theNumber;
public function __construct($originalNumber)
{
$this->theNumber = $originalNumber;
}
}
class Root {
public $numberHolder;
public function __construct($originalNumber)
{
$this->numberHolder = new NumberHolder($originalNumber);
}
/**
* @param $newNumber
* @return NumberHolder
*/
public function immediatelyChangeTheNumber($newNumber)
{
$this->numberHolder->theNumber = $newNumber;
return $this->numberHolder;
}
/**
* @param $newNumber
2016-11-26 22:48:49 +03:00
*
2016-12-03 00:23:21 +03:00
* @return Deferred
2015-07-15 20:05:46 +03:00
*/
public function promiseToChangeTheNumber($newNumber)
{
2016-12-03 00:23:21 +03:00
return new Deferred(function () use ($newNumber) {
return $this->immediatelyChangeTheNumber($newNumber);
2016-11-26 22:48:49 +03:00
});
2015-07-15 20:05:46 +03:00
}
/**
* @throws \Exception
*/
public function failToChangeTheNumber()
{
throw new \Exception('Cannot change the number');
}
/**
2016-12-03 00:23:21 +03:00
* @return Deferred
2015-07-15 20:05:46 +03:00
*/
public function promiseAndFailToChangeTheNumber()
{
2016-12-03 00:23:21 +03:00
return new Deferred(function () {
throw new \Exception("Cannot change the number");
2016-11-26 22:48:49 +03:00
});
2015-07-15 20:05:46 +03:00
}
}