#30 Fixed recursion bug in ResolveInfo::getFieldSelection()

This commit is contained in:
vladar 2016-04-01 16:30:52 +06:00
parent 6fc46beb3f
commit 68d8681983
2 changed files with 157 additions and 1 deletions

View File

@ -107,7 +107,7 @@ class ResolveInfo
foreach ($selectionSet->selections as $selectionAST) { foreach ($selectionSet->selections as $selectionAST) {
if ($selectionAST instanceof Field) { if ($selectionAST instanceof Field) {
$fields[$selectionAST->name->value] = $descend > 0 && !empty($selectionAST->selectionSet) $fields[$selectionAST->name->value] = $descend > 0 && !empty($selectionAST->selectionSet)
? $this->foldSelectionSet($selectionAST->selectionSet, --$descend) ? $this->foldSelectionSet($selectionAST->selectionSet, $descend - 1)
: true; : true;
} else if ($selectionAST instanceof FragmentSpread) { } else if ($selectionAST instanceof FragmentSpread) {
$spreadName = $selectionAST->name->value; $spreadName = $selectionAST->name->value;

View File

@ -0,0 +1,156 @@
<?php
namespace GraphQL\Type;
use GraphQL\GraphQL;
use GraphQL\Schema;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type;
class ResolveInfoTest extends \PHPUnit_Framework_TestCase
{
public function testFieldSelection()
{
$image = new ObjectType([
'name' => 'Image',
'fields' => [
'url' => ['type' => Type::string()],
'width' => ['type' => Type::int()],
'height' => ['type' => Type::int()]
]
]);
$article = null;
$author = new ObjectType([
'name' => 'Author',
'fields' => function() use ($image, &$article) {
return [
'id' => ['type' => Type::string()],
'name' => ['type' => Type::string()],
'pic' => [ 'type' => $image, 'args' => [
'width' => ['type' => Type::int()],
'height' => ['type' => Type::int()]
]],
'recentArticle' => ['type' => $article],
];
},
]);
$reply = new ObjectType([
'name' => 'Reply',
'fields' => [
'author' => ['type' => $author],
'body' => ['type' => Type::string()]
]
]);
$article = new ObjectType([
'name' => 'Article',
'fields' => [
'id' => ['type' => Type::string()],
'isPublished' => ['type' => Type::boolean()],
'author' => ['type' => $author],
'title' => ['type' => Type::string()],
'body' => ['type' => Type::string()],
'image' => ['type' => $image],
'replies' => ['type' => Type::listOf($reply)]
]
]);
$doc = '
query Test {
article {
author {
name
pic {
url
width
}
}
image {
width
height
}
replies {
body
author {
id
name
pic {
url
width
}
recentArticle {
id
title
body
}
}
}
}
}
';
$expectedDefaultSelection = [
'author' => true,
'image' => true,
'replies' => true
];
$expectedDeepSelection = [
'author' => [
'name' => true,
'pic' => [
'url' => true,
'width' => true
]
],
'image' => [
'width' => true,
'height' => true
],
'replies' => [
'body' => true,
'author' => [
'id' => true,
'name' => true,
'pic' => [
'url' => true,
'width' => true
],
'recentArticle' => [
'id' => true,
'title' => true,
'body' => true
]
]
]
];
$hasCalled = false;
$actualDefaultSelection = null;
$actualDeepSelection = null;
$blogQuery = new ObjectType([
'name' => 'Query',
'fields' => [
'article' => [
'type' => $article,
'resolve' => function($value, $args, ResolveInfo $info) use (&$hasCalled, &$actualDefaultSelection, &$actualDeepSelection) {
$hasCalled = true;
$actualDefaultSelection = $info->getFieldSelection();
$actualDeepSelection = $info->getFieldSelection(5);
return null;
}
]
]
]);
$schema = new Schema($blogQuery);
$result = GraphQL::execute($schema, $doc);
$this->assertTrue($hasCalled);
$this->assertEquals(['data' => ['article' => null]], $result);
$this->assertEquals($expectedDefaultSelection, $actualDefaultSelection);
$this->assertEquals($expectedDeepSelection, $actualDeepSelection);
}
}