Skip to content

Commit 68d8681

Browse files
committed
#30 Fixed recursion bug in ResolveInfo::getFieldSelection()
1 parent 6fc46be commit 68d8681

File tree

2 files changed

+157
-1
lines changed

2 files changed

+157
-1
lines changed

src/Type/Definition/ResolveInfo.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ private function foldSelectionSet(SelectionSet $selectionSet, $descend)
107107
foreach ($selectionSet->selections as $selectionAST) {
108108
if ($selectionAST instanceof Field) {
109109
$fields[$selectionAST->name->value] = $descend > 0 && !empty($selectionAST->selectionSet)
110-
? $this->foldSelectionSet($selectionAST->selectionSet, --$descend)
110+
? $this->foldSelectionSet($selectionAST->selectionSet, $descend - 1)
111111
: true;
112112
} else if ($selectionAST instanceof FragmentSpread) {
113113
$spreadName = $selectionAST->name->value;

tests/Type/ResolveInfoTest.php

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<?php
2+
namespace GraphQL\Type;
3+
4+
use GraphQL\GraphQL;
5+
use GraphQL\Schema;
6+
use GraphQL\Type\Definition\ObjectType;
7+
use GraphQL\Type\Definition\ResolveInfo;
8+
use GraphQL\Type\Definition\Type;
9+
10+
class ResolveInfoTest extends \PHPUnit_Framework_TestCase
11+
{
12+
public function testFieldSelection()
13+
{
14+
$image = new ObjectType([
15+
'name' => 'Image',
16+
'fields' => [
17+
'url' => ['type' => Type::string()],
18+
'width' => ['type' => Type::int()],
19+
'height' => ['type' => Type::int()]
20+
]
21+
]);
22+
23+
$article = null;
24+
25+
$author = new ObjectType([
26+
'name' => 'Author',
27+
'fields' => function() use ($image, &$article) {
28+
return [
29+
'id' => ['type' => Type::string()],
30+
'name' => ['type' => Type::string()],
31+
'pic' => [ 'type' => $image, 'args' => [
32+
'width' => ['type' => Type::int()],
33+
'height' => ['type' => Type::int()]
34+
]],
35+
'recentArticle' => ['type' => $article],
36+
];
37+
},
38+
]);
39+
40+
$reply = new ObjectType([
41+
'name' => 'Reply',
42+
'fields' => [
43+
'author' => ['type' => $author],
44+
'body' => ['type' => Type::string()]
45+
]
46+
]);
47+
48+
$article = new ObjectType([
49+
'name' => 'Article',
50+
'fields' => [
51+
'id' => ['type' => Type::string()],
52+
'isPublished' => ['type' => Type::boolean()],
53+
'author' => ['type' => $author],
54+
'title' => ['type' => Type::string()],
55+
'body' => ['type' => Type::string()],
56+
'image' => ['type' => $image],
57+
'replies' => ['type' => Type::listOf($reply)]
58+
]
59+
]);
60+
61+
$doc = '
62+
query Test {
63+
article {
64+
author {
65+
name
66+
pic {
67+
url
68+
width
69+
}
70+
}
71+
image {
72+
width
73+
height
74+
}
75+
replies {
76+
body
77+
author {
78+
id
79+
name
80+
pic {
81+
url
82+
width
83+
}
84+
recentArticle {
85+
id
86+
title
87+
body
88+
}
89+
}
90+
}
91+
}
92+
}
93+
';
94+
$expectedDefaultSelection = [
95+
'author' => true,
96+
'image' => true,
97+
'replies' => true
98+
];
99+
$expectedDeepSelection = [
100+
'author' => [
101+
'name' => true,
102+
'pic' => [
103+
'url' => true,
104+
'width' => true
105+
]
106+
],
107+
'image' => [
108+
'width' => true,
109+
'height' => true
110+
],
111+
'replies' => [
112+
'body' => true,
113+
'author' => [
114+
'id' => true,
115+
'name' => true,
116+
'pic' => [
117+
'url' => true,
118+
'width' => true
119+
],
120+
'recentArticle' => [
121+
'id' => true,
122+
'title' => true,
123+
'body' => true
124+
]
125+
]
126+
]
127+
];
128+
129+
$hasCalled = false;
130+
$actualDefaultSelection = null;
131+
$actualDeepSelection = null;
132+
133+
$blogQuery = new ObjectType([
134+
'name' => 'Query',
135+
'fields' => [
136+
'article' => [
137+
'type' => $article,
138+
'resolve' => function($value, $args, ResolveInfo $info) use (&$hasCalled, &$actualDefaultSelection, &$actualDeepSelection) {
139+
$hasCalled = true;
140+
$actualDefaultSelection = $info->getFieldSelection();
141+
$actualDeepSelection = $info->getFieldSelection(5);
142+
return null;
143+
}
144+
]
145+
]
146+
]);
147+
148+
$schema = new Schema($blogQuery);
149+
$result = GraphQL::execute($schema, $doc);
150+
151+
$this->assertTrue($hasCalled);
152+
$this->assertEquals(['data' => ['article' => null]], $result);
153+
$this->assertEquals($expectedDefaultSelection, $actualDefaultSelection);
154+
$this->assertEquals($expectedDeepSelection, $actualDeepSelection);
155+
}
156+
}

0 commit comments

Comments
 (0)