Skip to content

Commit c5131f6

Browse files
feature: Adds KnownFragmentNamesRule
1 parent 5fad1f4 commit c5131f6

File tree

3 files changed

+103
-1
lines changed

3 files changed

+103
-1
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Foundation
2+
3+
/**
4+
* Known fragment names
5+
*
6+
* A GraphQL document is only valid if all `...Fragment` fragment spreads refer
7+
* to fragments defined in the same document.
8+
*
9+
* See https://spec.graphql.org/draft/#sec-Fragment-spread-target-defined
10+
*/
11+
func KnownFragmentNamesRule(context: ValidationContext) -> Visitor {
12+
return Visitor(
13+
enter: { node, _, _, _, _ in
14+
if let fragmentReference = node as? FragmentSpread {
15+
let fragmentName = fragmentReference.name.value
16+
let fragmentDefinition = context.getFragment(name: fragmentName)
17+
18+
if fragmentDefinition == nil {
19+
context.report(error: GraphQLError(
20+
message: "Unknown fragment \"\(fragmentName)\".",
21+
nodes: [fragmentReference.name]
22+
))
23+
}
24+
}
25+
26+
return .continue
27+
}
28+
)
29+
}

Sources/GraphQL/Validation/SpecifiedRules.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public let specifiedRules: [(ValidationContext) -> Visitor] = [
1212
ScalarLeafsRule,
1313
FieldsOnCorrectTypeRule,
1414
UniqueFragmentNamesRule,
15-
// KnownFragmentNamesRule,
15+
KnownFragmentNamesRule,
1616
NoUnusedFragmentsRule,
1717
PossibleFragmentSpreadsRule,
1818
// NoFragmentCyclesRule,
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
@testable import GraphQL
2+
import XCTest
3+
4+
class KnownFragmentNamesTests: ValidationTestCase {
5+
override func setUp() {
6+
rule = KnownFragmentNamesRule
7+
}
8+
9+
func testKnownFragmentNamesAreValid() throws {
10+
try assertValid(
11+
"""
12+
{
13+
human(id: 4) {
14+
...HumanFields1
15+
... on Human {
16+
...HumanFields2
17+
}
18+
... {
19+
name
20+
}
21+
}
22+
}
23+
fragment HumanFields1 on Human {
24+
name
25+
...HumanFields3
26+
}
27+
fragment HumanFields2 on Human {
28+
name
29+
}
30+
fragment HumanFields3 on Human {
31+
name
32+
}
33+
"""
34+
)
35+
}
36+
37+
func testUnknownFragmentNamesAreInvalid() throws {
38+
let errors = try assertInvalid(
39+
errorCount: 3,
40+
query:
41+
"""
42+
{
43+
human(id: 4) {
44+
...UnknownFragment1
45+
... on Human {
46+
...UnknownFragment2
47+
}
48+
}
49+
}
50+
fragment HumanFields on Human {
51+
name
52+
...UnknownFragment3
53+
}
54+
"""
55+
)
56+
57+
try assertValidationError(
58+
error: errors[0],
59+
locations: [(line: 3, column: 8)],
60+
message: "Unknown fragment \"UnknownFragment1\"."
61+
)
62+
try assertValidationError(
63+
error: errors[1],
64+
locations: [(line: 5, column: 10)],
65+
message: "Unknown fragment \"UnknownFragment2\"."
66+
)
67+
try assertValidationError(
68+
error: errors[2],
69+
locations: [(line: 11, column: 6)],
70+
message: "Unknown fragment \"UnknownFragment3\"."
71+
)
72+
}
73+
}

0 commit comments

Comments
 (0)