Skip to content

Commit 3cecede

Browse files
fix: Fixes KnownDirectivesRule for SDL
1 parent e5b0ff8 commit 3cecede

File tree

2 files changed

+259
-24
lines changed

2 files changed

+259
-24
lines changed

Sources/GraphQL/Validation/Rules/KnownDirectivesRule.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func getDirectiveLocationForASTPath(_ ancestors: [NodeResult]) -> DirectiveLocat
7474
return DirectiveLocation.fragmentDefinition
7575
case is VariableDefinition:
7676
return DirectiveLocation.variableDefinition
77-
case is SchemaDefinition:
77+
case is SchemaDefinition, is SchemaExtensionDefinition:
7878
return DirectiveLocation.schema
7979
case is ScalarTypeDefinition, is ScalarExtensionDefinition:
8080
return DirectiveLocation.scalar

Tests/GraphQLTests/ValidationTests/KnownDirectivesRuleTests.swift

Lines changed: 258 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -246,28 +246,263 @@ class KnownDirectivesRuleTests: ValidationTestCase {
246246
return directives
247247
}()
248248
)
249+
}
250+
251+
class KnownDirectivesRuleSDLTests: SDLValidationTestCase {
252+
override func setUp() {
253+
rule = KnownDirectivesRule
254+
}
255+
256+
func testWithDirectiveDefinedInsideSDL() throws {
257+
try assertValidationErrors(
258+
"""
259+
type Query {
260+
foo: String @test
261+
}
262+
263+
directive @test on FIELD_DEFINITION
264+
""",
265+
[]
266+
)
267+
}
268+
269+
func testWithStandardDirective() throws {
270+
try assertValidationErrors(
271+
"""
272+
type Query {
273+
foo: String @deprecated
274+
}
275+
""",
276+
[]
277+
)
278+
}
279+
280+
func testWithOverriddenStandardDirective() throws {
281+
try assertValidationErrors(
282+
"""
283+
schema @deprecated {
284+
query: Query
285+
}
286+
directive @deprecated on SCHEMA
287+
""",
288+
[]
289+
)
290+
}
291+
292+
func testWithDirectiveDefinedInSchemaExtension() throws {
293+
let schema = try buildSchema(source: """
294+
type Query {
295+
foo: String
296+
}
297+
""")
298+
let sdl = """
299+
directive @test on OBJECT
300+
301+
extend type Query @test
302+
"""
303+
try assertValidationErrors(sdl, schema: schema, [])
304+
}
305+
306+
func testWithDirectiveUsedInSchemaExtension() throws {
307+
let schema = try buildSchema(source: """
308+
directive @test on OBJECT
309+
310+
type Query {
311+
foo: String
312+
}
313+
""")
314+
let sdl = """
315+
extend type Query @test
316+
"""
317+
try assertValidationErrors(sdl, schema: schema, [])
318+
}
319+
320+
func testWithUnknownDirectiveInSchemaExtension() throws {
321+
let schema = try buildSchema(source: """
322+
type Query {
323+
foo: String
324+
}
325+
""")
326+
let sdl = """
327+
extend type Query @unknown
328+
"""
329+
try assertValidationErrors(
330+
sdl,
331+
schema: schema,
332+
[
333+
GraphQLError(
334+
message: #"Unknown directive "@unknown"."#,
335+
locations: [.init(line: 1, column: 19)]
336+
),
337+
]
338+
)
339+
}
340+
341+
func testWithWellPlacedDirectives() throws {
342+
try assertValidationErrors(
343+
"""
344+
type MyObj implements MyInterface @onObject {
345+
myField(myArg: Int @onArgumentDefinition): String @onFieldDefinition
346+
}
347+
348+
extend type MyObj @onObject
349+
350+
scalar MyScalar @onScalar
351+
352+
extend scalar MyScalar @onScalar
353+
354+
interface MyInterface @onInterface {
355+
myField(myArg: Int @onArgumentDefinition): String @onFieldDefinition
356+
}
357+
358+
extend interface MyInterface @onInterface
359+
360+
union MyUnion @onUnion = MyObj | Other
361+
362+
extend union MyUnion @onUnion
363+
364+
enum MyEnum @onEnum {
365+
MY_VALUE @onEnumValue
366+
}
367+
368+
extend enum MyEnum @onEnum
369+
370+
input MyInput @onInputObject {
371+
myField: Int @onInputFieldDefinition
372+
}
249373
250-
// TODO: Add SDL tests
251-
252-
// let schemaWithSDLDirectives = try! GraphQLSchema(
253-
// directives: {
254-
// var directives = specifiedDirectives
255-
// directives.append(contentsOf: [
256-
// try! GraphQLDirective(name: "onSchema", locations: [.schema]),
257-
// try! GraphQLDirective(name: "onScalar", locations: [.scalar]),
258-
// try! GraphQLDirective(name: "onObject", locations: [.object]),
259-
// try! GraphQLDirective(name: "onFieldDefinition", locations: [.fieldDefinition]),
260-
// try! GraphQLDirective(name: "onArgumentDefinition", locations:
261-
// [.argumentDefinition]),
262-
// try! GraphQLDirective(name: "onInterface", locations: [.interface]),
263-
// try! GraphQLDirective(name: "onUnion", locations: [.union]),
264-
// try! GraphQLDirective(name: "onEnum", locations: [.enum]),
265-
// try! GraphQLDirective(name: "onEnumValue", locations: [.enumValue]),
266-
// try! GraphQLDirective(name: "onInputObject", locations: [.inputObject]),
267-
// try! GraphQLDirective(name: "onInputFieldDefinition", locations:
268-
// [.inputFieldDefinition]),
269-
// ])
270-
// return directives
271-
// }()
272-
// )
374+
extend input MyInput @onInputObject
375+
376+
schema @onSchema {
377+
query: MyQuery
378+
}
379+
380+
directive @myDirective(arg:String) on ARGUMENT_DEFINITION
381+
directive @myDirective2(arg:String @myDirective) on FIELD
382+
383+
extend schema @onSchema
384+
""",
385+
schema: schemaWithSDLDirectives,
386+
[]
387+
)
388+
}
389+
390+
func testWithMisplacedDirectives() throws {
391+
try assertValidationErrors(
392+
"""
393+
type MyObj implements MyInterface @onInterface {
394+
myField(myArg: Int @onInputFieldDefinition): String @onInputFieldDefinition
395+
}
396+
397+
scalar MyScalar @onEnum
398+
399+
interface MyInterface @onObject {
400+
myField(myArg: Int @onInputFieldDefinition): String @onInputFieldDefinition
401+
}
402+
403+
union MyUnion @onEnumValue = MyObj | Other
404+
405+
enum MyEnum @onScalar {
406+
MY_VALUE @onUnion
407+
}
408+
409+
input MyInput @onEnum {
410+
myField: Int @onArgumentDefinition
411+
}
412+
413+
schema @onObject {
414+
query: MyQuery
415+
}
416+
417+
extend schema @onObject
418+
""",
419+
schema: schemaWithSDLDirectives,
420+
[
421+
GraphQLError(
422+
message: #"Directive "@onInterface" may not be used on OBJECT."#,
423+
locations: [.init(line: 1, column: 35)]
424+
),
425+
GraphQLError(
426+
message: #"Directive "@onInputFieldDefinition" may not be used on ARGUMENT_DEFINITION."#,
427+
locations: [.init(line: 2, column: 22)]
428+
),
429+
GraphQLError(
430+
message: #"Directive "@onInputFieldDefinition" may not be used on FIELD_DEFINITION."#,
431+
locations: [.init(line: 2, column: 55)]
432+
),
433+
GraphQLError(
434+
message: #"Directive "@onEnum" may not be used on SCALAR."#,
435+
locations: [.init(line: 5, column: 17)]
436+
),
437+
GraphQLError(
438+
message: #"Directive "@onObject" may not be used on INTERFACE."#,
439+
locations: [.init(line: 7, column: 23)]
440+
),
441+
GraphQLError(
442+
message: #"Directive "@onInputFieldDefinition" may not be used on ARGUMENT_DEFINITION."#,
443+
locations: [.init(line: 8, column: 22)]
444+
),
445+
GraphQLError(
446+
message: #"Directive "@onInputFieldDefinition" may not be used on FIELD_DEFINITION."#,
447+
locations: [.init(line: 8, column: 55)]
448+
),
449+
GraphQLError(
450+
message: #"Directive "@onEnumValue" may not be used on UNION."#,
451+
locations: [.init(line: 11, column: 15)]
452+
),
453+
GraphQLError(
454+
message: #"Directive "@onScalar" may not be used on ENUM."#,
455+
locations: [.init(line: 13, column: 13)]
456+
),
457+
GraphQLError(
458+
message: #"Directive "@onUnion" may not be used on ENUM_VALUE."#,
459+
locations: [.init(line: 14, column: 12)]
460+
),
461+
GraphQLError(
462+
message: #"Directive "@onEnum" may not be used on INPUT_OBJECT."#,
463+
locations: [.init(line: 17, column: 15)]
464+
),
465+
GraphQLError(
466+
message: #"Directive "@onArgumentDefinition" may not be used on INPUT_FIELD_DEFINITION."#,
467+
locations: [.init(line: 18, column: 16)]
468+
),
469+
GraphQLError(
470+
message: #"Directive "@onObject" may not be used on SCHEMA."#,
471+
locations: [.init(line: 21, column: 8)]
472+
),
473+
GraphQLError(
474+
message: #"Directive "@onObject" may not be used on SCHEMA."#,
475+
locations: [.init(line: 25, column: 15)]
476+
),
477+
]
478+
)
479+
}
480+
481+
let schemaWithSDLDirectives = try! GraphQLSchema(
482+
directives: {
483+
var directives = specifiedDirectives
484+
directives.append(contentsOf: [
485+
try! GraphQLDirective(name: "onSchema", locations: [.schema]),
486+
try! GraphQLDirective(name: "onScalar", locations: [.scalar]),
487+
try! GraphQLDirective(name: "onObject", locations: [.object]),
488+
try! GraphQLDirective(name: "onFieldDefinition", locations: [.fieldDefinition]),
489+
try! GraphQLDirective(
490+
name: "onArgumentDefinition",
491+
locations:
492+
[.argumentDefinition]
493+
),
494+
try! GraphQLDirective(name: "onInterface", locations: [.interface]),
495+
try! GraphQLDirective(name: "onUnion", locations: [.union]),
496+
try! GraphQLDirective(name: "onEnum", locations: [.enum]),
497+
try! GraphQLDirective(name: "onEnumValue", locations: [.enumValue]),
498+
try! GraphQLDirective(name: "onInputObject", locations: [.inputObject]),
499+
try! GraphQLDirective(
500+
name: "onInputFieldDefinition",
501+
locations:
502+
[.inputFieldDefinition]
503+
),
504+
])
505+
return directives
506+
}()
507+
)
273508
}

0 commit comments

Comments
 (0)