Skip to content

Commit 062a848

Browse files
feat: Adds LoneSchemaDefinitionRule
1 parent 4544619 commit 062a848

File tree

3 files changed

+203
-1
lines changed

3 files changed

+203
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
/**
3+
* Lone Schema definition
4+
*
5+
* A GraphQL document is only valid if it contains only one schema definition.
6+
*/
7+
func LoneSchemaDefinitionRule(context: SDLValidationContext) -> Visitor {
8+
let oldSchema = context.getSchema()
9+
let alreadyDefined =
10+
oldSchema?.astNode != nil ||
11+
oldSchema?.queryType != nil ||
12+
oldSchema?.mutationType != nil ||
13+
oldSchema?.subscriptionType != nil
14+
15+
var schemaDefinitionsCount = 0
16+
return Visitor(
17+
enter: { node, _, _, _, _ in
18+
if let node = node as? SchemaDefinition {
19+
if alreadyDefined {
20+
context.report(
21+
error: GraphQLError(
22+
message: "Cannot define a new schema within a schema extension.",
23+
nodes: [node]
24+
)
25+
)
26+
}
27+
28+
if schemaDefinitionsCount > 0 {
29+
context.report(
30+
error: GraphQLError(
31+
message: "Must provide only one schema definition.",
32+
nodes: [node]
33+
)
34+
)
35+
}
36+
37+
schemaDefinitionsCount = schemaDefinitionsCount + 1
38+
}
39+
return .continue
40+
}
41+
)
42+
}

Sources/GraphQL/Validation/SpecifiedRules.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public let specifiedRules: [(ValidationContext) -> Visitor] = [
3737
* @internal
3838
*/
3939
public let specifiedSDLRules: [SDLValidationRule] = [
40-
// LoneSchemaDefinitionRule,
40+
LoneSchemaDefinitionRule,
4141
// UniqueOperationTypesRule,
4242
// UniqueTypeNamesRule,
4343
// UniqueEnumValueNamesRule,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
@testable import GraphQL
2+
import XCTest
3+
4+
class LoneSchemaDefinitionRuleTests: SDLValidationTestCase {
5+
override func setUp() {
6+
rule = LoneSchemaDefinitionRule
7+
}
8+
9+
func testNoSchema() throws {
10+
try assertValidationErrors(
11+
"""
12+
type Query {
13+
foo: String
14+
}
15+
""",
16+
[]
17+
)
18+
}
19+
20+
func testOneSchemaDefinition() throws {
21+
try assertValidationErrors(
22+
"""
23+
schema {
24+
query: Foo
25+
}
26+
27+
type Foo {
28+
foo: String
29+
}
30+
""",
31+
[]
32+
)
33+
}
34+
35+
func testMultipleSchemaDefinitions() throws {
36+
try assertValidationErrors(
37+
"""
38+
schema {
39+
query: Foo
40+
}
41+
42+
type Foo {
43+
foo: String
44+
}
45+
46+
schema {
47+
mutation: Foo
48+
}
49+
50+
schema {
51+
subscription: Foo
52+
}
53+
""",
54+
[
55+
GraphQLError(
56+
message: "Must provide only one schema definition.",
57+
locations: [.init(line: 9, column: 1)]
58+
),
59+
GraphQLError(
60+
message: "Must provide only one schema definition.",
61+
locations: [.init(line: 13, column: 1)]
62+
),
63+
]
64+
)
65+
}
66+
67+
func testDefineSchemaInSchemaExtension() throws {
68+
let schema = try buildSchema(source: """
69+
type Foo {
70+
foo: String
71+
}
72+
""")
73+
74+
try assertValidationErrors(
75+
"""
76+
schema {
77+
query: Foo
78+
}
79+
""",
80+
schema: schema,
81+
[]
82+
)
83+
}
84+
85+
func testRedefineSchemaInSchemaExtension() throws {
86+
let schema = try buildSchema(source: """
87+
schema {
88+
query: Foo
89+
}
90+
91+
type Foo {
92+
foo: String
93+
}
94+
""")
95+
96+
try assertValidationErrors(
97+
"""
98+
schema {
99+
mutation: Foo
100+
}
101+
""",
102+
schema: schema,
103+
[
104+
GraphQLError(
105+
message: "Cannot define a new schema within a schema extension.",
106+
locations: [.init(line: 1, column: 1)]
107+
),
108+
]
109+
)
110+
}
111+
112+
func testRedefineImplicitSchemaInSchemaExtension() throws {
113+
let schema = try buildSchema(source: """
114+
type Query {
115+
fooField: Foo
116+
}
117+
118+
type Foo {
119+
foo: String
120+
}
121+
""")
122+
123+
try assertValidationErrors(
124+
"""
125+
schema {
126+
mutation: Foo
127+
}
128+
""",
129+
schema: schema,
130+
[
131+
GraphQLError(
132+
message: "Cannot define a new schema within a schema extension.",
133+
locations: [.init(line: 1, column: 1)]
134+
),
135+
]
136+
)
137+
}
138+
139+
func testExtendSchemaInSchemaExtension() throws {
140+
let schema = try buildSchema(source: """
141+
type Query {
142+
fooField: Foo
143+
}
144+
145+
type Foo {
146+
foo: String
147+
}
148+
""")
149+
150+
try assertValidationErrors(
151+
"""
152+
extend schema {
153+
mutation: Foo
154+
}
155+
""",
156+
schema: schema,
157+
[]
158+
)
159+
}
160+
}

0 commit comments

Comments
 (0)