7
7
use GraphQL \Language \AST \InterfaceTypeDefinitionNode ;
8
8
use GraphQL \Language \AST \NodeKind ;
9
9
use GraphQL \Language \AST \ObjectTypeDefinitionNode ;
10
+ use GraphQL \Language \AST \ScalarTypeDefinitionNode ;
10
11
use GraphQL \Language \AST \UnionTypeDefinitionNode ;
11
12
use Illuminate \Support \Collection ;
12
13
use Nuwave \Lighthouse \Exceptions \DefinitionException ;
13
14
use Nuwave \Lighthouse \Schema \AST \ASTBuilder ;
14
15
use Nuwave \Lighthouse \Schema \AST \ASTHelper ;
16
+ use Nuwave \Lighthouse \Schema \DirectiveLocator ;
17
+ use Nuwave \Lighthouse \Schema \Directives \BaseDirective ;
15
18
use Nuwave \Lighthouse \Schema \RootType ;
16
19
use Tests \TestCase ;
17
20
@@ -49,6 +52,35 @@ public function testMergeTypeExtensionFields(): void
49
52
$ this ->assertCount (3 , $ queryType ->fields );
50
53
}
51
54
55
+ public function testMergeTypeExtensionDirectives (): void
56
+ {
57
+ $ directive = new class () extends BaseDirective {
58
+ public static function definition (): string
59
+ {
60
+ return /** @lang GraphQL */ 'directive @foo repeatable on OBJECT ' ;
61
+ }
62
+ };
63
+
64
+ $ directiveLocator = $ this ->app ->make (DirectiveLocator::class);
65
+ $ directiveLocator ->setResolved ('foo ' , $ directive ::class);
66
+
67
+ $ this ->schema = /** @lang GraphQL */ '
68
+ type MyType {
69
+ field: String
70
+ }
71
+
72
+ extend type MyType @foo
73
+
74
+ extend type MyType @foo
75
+ ' ;
76
+ $ documentAST = $ this ->astBuilder ->documentAST ();
77
+
78
+ $ myType = $ documentAST ->types ['MyType ' ];
79
+ assert ($ myType instanceof ObjectTypeDefinitionNode);
80
+
81
+ $ this ->assertCount (2 , $ myType ->directives );
82
+ }
83
+
52
84
public function testAllowsExtendingUndefinedRootTypes (): void
53
85
{
54
86
$ this ->schema = /** @lang GraphQL */ '
@@ -105,6 +137,35 @@ public function testMergeInputExtensionFields(): void
105
137
$ this ->assertCount (3 , $ inputs ->fields );
106
138
}
107
139
140
+ public function testMergeInputExtensionDirectives (): void
141
+ {
142
+ $ directive = new class () extends BaseDirective {
143
+ public static function definition (): string
144
+ {
145
+ return /** @lang GraphQL */ 'directive @foo repeatable on INPUT_OBJECT ' ;
146
+ }
147
+ };
148
+
149
+ $ directiveLocator = $ this ->app ->make (DirectiveLocator::class);
150
+ $ directiveLocator ->setResolved ('foo ' , $ directive ::class);
151
+
152
+ $ this ->schema = /** @lang GraphQL */ '
153
+ input MyInput {
154
+ field: String
155
+ }
156
+
157
+ extend input MyInput @foo
158
+
159
+ extend input MyInput @foo
160
+ ' ;
161
+ $ documentAST = $ this ->astBuilder ->documentAST ();
162
+
163
+ $ myInput = $ documentAST ->types ['MyInput ' ];
164
+ assert ($ myInput instanceof InputObjectTypeDefinitionNode);
165
+
166
+ $ this ->assertCount (2 , $ myInput ->directives );
167
+ }
168
+
108
169
public function testMergeInterfaceExtensionFields (): void
109
170
{
110
171
$ this ->schema = /** @lang GraphQL */ '
@@ -128,6 +189,62 @@ interface Named {
128
189
$ this ->assertCount (3 , $ named ->fields );
129
190
}
130
191
192
+ public function testMergeInterfaceExtensionDirectives (): void
193
+ {
194
+ $ directive = new class () extends BaseDirective {
195
+ public static function definition (): string
196
+ {
197
+ return /** @lang GraphQL */ 'directive @foo repeatable on INTERFACE ' ;
198
+ }
199
+ };
200
+
201
+ $ directiveLocator = $ this ->app ->make (DirectiveLocator::class);
202
+ $ directiveLocator ->setResolved ('foo ' , $ directive ::class);
203
+
204
+ $ this ->schema = /** @lang GraphQL */ '
205
+ interface MyInterface {
206
+ field: String
207
+ }
208
+
209
+ extend interface MyInterface @foo
210
+
211
+ extend interface MyInterface @foo
212
+ ' ;
213
+ $ documentAST = $ this ->astBuilder ->documentAST ();
214
+
215
+ $ myInterface = $ documentAST ->types ['MyInterface ' ];
216
+ assert ($ myInterface instanceof InterfaceTypeDefinitionNode);
217
+
218
+ $ this ->assertCount (2 , $ myInterface ->directives );
219
+ }
220
+
221
+ public function testMergeScalarExtensionDirectives (): void
222
+ {
223
+ $ directive = new class () extends BaseDirective {
224
+ public static function definition (): string
225
+ {
226
+ return /** @lang GraphQL */ 'directive @foo repeatable on SCALAR ' ;
227
+ }
228
+ };
229
+
230
+ $ directiveLocator = $ this ->app ->make (DirectiveLocator::class);
231
+ $ directiveLocator ->setResolved ('foo ' , $ directive ::class);
232
+
233
+ $ this ->schema = /** @lang GraphQL */ '
234
+ scalar MyScalar
235
+
236
+ extend scalar MyScalar @foo
237
+
238
+ extend scalar MyScalar @foo
239
+ ' ;
240
+ $ documentAST = $ this ->astBuilder ->documentAST ();
241
+
242
+ $ myScalar = $ documentAST ->types ['MyScalar ' ];
243
+ assert ($ myScalar instanceof ScalarTypeDefinitionNode);
244
+
245
+ $ this ->assertCount (2 , $ myScalar ->directives );
246
+ }
247
+
131
248
public function testMergeEnumExtensionFields (): void
132
249
{
133
250
$ this ->schema = /** @lang GraphQL */ '
@@ -152,6 +269,36 @@ enum MyEnum {
152
269
$ this ->assertCount (4 , $ myEnum ->values );
153
270
}
154
271
272
+ public function testMergeEnumExtensionDirectives (): void
273
+ {
274
+ $ directive = new class () extends BaseDirective {
275
+ public static function definition (): string
276
+ {
277
+ return /** @lang GraphQL */ 'directive @foo repeatable on ENUM ' ;
278
+ }
279
+ };
280
+
281
+ $ directiveLocator = $ this ->app ->make (DirectiveLocator::class);
282
+ $ directiveLocator ->setResolved ('foo ' , $ directive ::class);
283
+
284
+ $ this ->schema = /** @lang GraphQL */ '
285
+ enum MyEnum {
286
+ ONE
287
+ TWO
288
+ }
289
+
290
+ extend enum MyEnum @foo
291
+
292
+ extend enum MyEnum @foo
293
+ ' ;
294
+ $ documentAST = $ this ->astBuilder ->documentAST ();
295
+
296
+ $ myEnum = $ documentAST ->types ['MyEnum ' ];
297
+ assert ($ myEnum instanceof EnumTypeDefinitionNode);
298
+
299
+ $ this ->assertCount (2 , $ myEnum ->directives );
300
+ }
301
+
155
302
public function testMergeUnionExtensionFields (): void
156
303
{
157
304
$ this ->schema = /** @lang GraphQL */ '
@@ -173,6 +320,26 @@ public function testMergeUnionExtensionFields(): void
173
320
$ this ->assertCount (3 , $ myUnion ->types );
174
321
}
175
322
323
+ public function testDoesNotAllowExtendingUndefinedScalar (): void
324
+ {
325
+ $ directive = new class () extends BaseDirective {
326
+ public static function definition (): string
327
+ {
328
+ return /** @lang GraphQL */ 'directive @foo repeatable on SCALAR ' ;
329
+ }
330
+ };
331
+
332
+ $ directiveLocator = $ this ->app ->make (DirectiveLocator::class);
333
+ $ directiveLocator ->setResolved ('foo ' , $ directive ::class);
334
+
335
+ $ this ->schema = /** @lang GraphQL */ '
336
+ extend scalar MyScalar @foo
337
+ ' ;
338
+
339
+ $ this ->expectExceptionObject (new DefinitionException ('Could not find a base definition MyScalar of kind ' . NodeKind::SCALAR_TYPE_EXTENSION . ' to extend. ' ));
340
+ $ this ->astBuilder ->documentAST ();
341
+ }
342
+
176
343
public function testDoesNotAllowExtendingUndefinedTypes (): void
177
344
{
178
345
$ this ->schema = /** @lang GraphQL */ '
0 commit comments