Skip to content

Commit b9be0f8

Browse files
fix: Fixes default value introspection
Input object and boolean default values are represented correctly in introspection
1 parent e585017 commit b9be0f8

File tree

3 files changed

+285
-1
lines changed

3 files changed

+285
-1
lines changed

Sources/GraphQL/Type/Introspection.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,16 @@ let __InputValue = try! GraphQLObjectType(
369369
else {
370370
return nil
371371
}
372+
373+
if defaultValue == .null || defaultValue == .undefined {
374+
return defaultValue
375+
}
376+
377+
guard let literal = try astFromValue(value: defaultValue, type: inputValue.type) else {
378+
throw GraphQLError(message: "Invalid default value")
379+
}
372380

373-
return .string(defaultValue.description)
381+
return .string(print(ast: literal))
374382
}
375383
),
376384
]

Sources/GraphQL/Utilities/ASTFromValue.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ func astFromValue(
9797
}
9898

9999
// Others serialize based on their corresponding scalar types.
100+
if case let .bool(bool) = serialized {
101+
return BooleanValue(value: bool)
102+
}
103+
104+
// JavaScript numbers can be Int or Float values.
100105
if case let .number(number) = serialized {
101106
switch number.storageType {
102107
case .bool:
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
@testable import GraphQL
2+
import NIO
3+
import XCTest
4+
5+
class IntrospectionTests: XCTestCase {
6+
private var eventLoopGroup: EventLoopGroup!
7+
8+
override func setUp() {
9+
eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
10+
}
11+
12+
override func tearDown() {
13+
XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())
14+
}
15+
16+
func testDefaultValues() throws {
17+
let numEnum = try GraphQLEnumType(
18+
name: "Enum",
19+
values: [
20+
"One": .init(value: "One"),
21+
"Two": .init(value: "Two"),
22+
]
23+
)
24+
let inputObject = try GraphQLInputObjectType(
25+
name: "InputObject",
26+
fields: ["str": .init(type: GraphQLString)]
27+
)
28+
let outputObject = try GraphQLObjectType(
29+
name: "Object",
30+
fields: ["str": .init(type: GraphQLString)]
31+
)
32+
33+
let query = try GraphQLObjectType(
34+
name: "Query",
35+
fields: [
36+
"bool": .init(
37+
type: GraphQLBoolean,
38+
args: [
39+
"bool": .init(
40+
type: GraphQLBoolean,
41+
defaultValue: true
42+
)
43+
]
44+
),
45+
"enum": .init(
46+
type: numEnum,
47+
args: [
48+
"enum": .init(
49+
type: numEnum,
50+
defaultValue: "One"
51+
)
52+
]
53+
),
54+
"float": .init(
55+
type: GraphQLFloat,
56+
args: [
57+
"float": .init(
58+
type: GraphQLFloat,
59+
defaultValue: 2.2
60+
)
61+
]
62+
),
63+
"id": .init(
64+
type: GraphQLID,
65+
args: [
66+
"id": .init(
67+
type: GraphQLID,
68+
defaultValue: "5"
69+
)
70+
]
71+
),
72+
"int": .init(
73+
type: GraphQLInt,
74+
args: [
75+
"int": .init(
76+
type: GraphQLInt,
77+
defaultValue: 5
78+
)
79+
]
80+
),
81+
"list": .init(
82+
type: GraphQLList(GraphQLInt),
83+
args: [
84+
"list": .init(
85+
type: GraphQLList(GraphQLInt),
86+
defaultValue: [1, 2, 3]
87+
)
88+
]
89+
),
90+
"object": .init(
91+
type: outputObject,
92+
args: [
93+
"input": .init(
94+
type: inputObject,
95+
defaultValue: ["str": "hello"]
96+
)
97+
]
98+
),
99+
"string": .init(
100+
type: GraphQLString,
101+
args: [
102+
"string": .init(
103+
type: GraphQLString,
104+
defaultValue: "hello"
105+
)
106+
]
107+
),
108+
]
109+
)
110+
111+
let schema = try GraphQLSchema(query: query, types: [inputObject, outputObject])
112+
113+
let introspection = try graphql(
114+
schema: schema,
115+
request: """
116+
query IntrospectionTypeQuery {
117+
__schema {
118+
types {
119+
fields {
120+
args {
121+
defaultValue
122+
name
123+
type {
124+
name
125+
}
126+
}
127+
name
128+
type {
129+
name
130+
}
131+
}
132+
name
133+
}
134+
}
135+
}
136+
""",
137+
eventLoopGroup: eventLoopGroup
138+
).wait()
139+
140+
let queryType = try XCTUnwrap(introspection.data?["__schema"]["types"].array?.find { $0["name"] == "Query" })
141+
142+
XCTAssertEqual(
143+
queryType,
144+
[
145+
"fields": [
146+
[
147+
"args": [
148+
[
149+
"defaultValue": "true",
150+
"name": "bool",
151+
"type": [
152+
"name": "Boolean"
153+
]
154+
],
155+
],
156+
"name": "bool",
157+
"type": [
158+
"name": "Boolean"
159+
]
160+
],
161+
[
162+
"args": [
163+
[
164+
"defaultValue": "One",
165+
"name": "enum",
166+
"type": [
167+
"name": "Enum"
168+
]
169+
],
170+
],
171+
"name": "enum",
172+
"type": [
173+
"name": "Enum"
174+
]
175+
],
176+
[
177+
"args": [
178+
[
179+
"defaultValue": "2.2",
180+
"name": "float",
181+
"type": [
182+
"name": "Float"
183+
]
184+
],
185+
],
186+
"name": "float",
187+
"type": [
188+
"name": "Float"
189+
]
190+
],
191+
[
192+
"args": [
193+
[
194+
"defaultValue": "5",
195+
"name": "id",
196+
"type": [
197+
"name": "ID"
198+
]
199+
],
200+
],
201+
"name": "id",
202+
"type": [
203+
"name": "ID"
204+
]
205+
],
206+
[
207+
"args": [
208+
[
209+
"defaultValue": "5",
210+
"name": "int",
211+
"type": [
212+
"name": "Int"
213+
]
214+
],
215+
],
216+
"name": "int",
217+
"type": [
218+
"name": "Int"
219+
]
220+
],
221+
[
222+
"args": [
223+
[
224+
"defaultValue": "[1, 2, 3]",
225+
"name": "list",
226+
"type": [
227+
"name": .null
228+
]
229+
],
230+
],
231+
"name": "list",
232+
"type": [
233+
"name": .null
234+
]
235+
],
236+
[
237+
"args": [
238+
[
239+
"defaultValue": "{ str: \"hello\" }",
240+
"name": "input",
241+
"type": [
242+
"name": "InputObject"
243+
]
244+
],
245+
],
246+
"name": "object",
247+
"type": [
248+
"name": "Object"
249+
]
250+
],
251+
[
252+
"args": [
253+
[
254+
"defaultValue": "\"hello\"",
255+
"name": "string",
256+
"type": [
257+
"name": "String"
258+
]
259+
],
260+
],
261+
"name": "string",
262+
"type": [
263+
"name": "String"
264+
]
265+
],
266+
],
267+
"name": "Query"
268+
]
269+
)
270+
}
271+
}

0 commit comments

Comments
 (0)