Skip to content

Commit afbad07

Browse files
Merge pull request #151 from NeedleInAJayStack/fix/instrospection-defaultValue
Fixes default value introspection
2 parents e585017 + ae7983d commit afbad07

File tree

3 files changed

+289
-1
lines changed

3 files changed

+289
-1
lines changed

Sources/GraphQL/Type/Introspection.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,16 @@ let __InputValue = try! GraphQLObjectType(
370370
return nil
371371
}
372372

373-
return .string(defaultValue.description)
373+
if defaultValue == .null || defaultValue == .undefined {
374+
return defaultValue
375+
}
376+
377+
guard let literal = try astFromValue(value: defaultValue, type: inputValue.type)
378+
else {
379+
throw GraphQLError(message: "Invalid default value")
380+
}
381+
382+
return .string(print(ast: literal))
374383
}
375384
),
376385
]

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: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
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(
141+
introspection.data?["__schema"]["types"].array?
142+
.find { $0["name"] == "Query" }
143+
)
144+
145+
XCTAssertEqual(
146+
queryType,
147+
[
148+
"fields": [
149+
[
150+
"args": [
151+
[
152+
"defaultValue": "true",
153+
"name": "bool",
154+
"type": [
155+
"name": "Boolean",
156+
],
157+
],
158+
],
159+
"name": "bool",
160+
"type": [
161+
"name": "Boolean",
162+
],
163+
],
164+
[
165+
"args": [
166+
[
167+
"defaultValue": "One",
168+
"name": "enum",
169+
"type": [
170+
"name": "Enum",
171+
],
172+
],
173+
],
174+
"name": "enum",
175+
"type": [
176+
"name": "Enum",
177+
],
178+
],
179+
[
180+
"args": [
181+
[
182+
"defaultValue": "2.2",
183+
"name": "float",
184+
"type": [
185+
"name": "Float",
186+
],
187+
],
188+
],
189+
"name": "float",
190+
"type": [
191+
"name": "Float",
192+
],
193+
],
194+
[
195+
"args": [
196+
[
197+
"defaultValue": "5",
198+
"name": "id",
199+
"type": [
200+
"name": "ID",
201+
],
202+
],
203+
],
204+
"name": "id",
205+
"type": [
206+
"name": "ID",
207+
],
208+
],
209+
[
210+
"args": [
211+
[
212+
"defaultValue": "5",
213+
"name": "int",
214+
"type": [
215+
"name": "Int",
216+
],
217+
],
218+
],
219+
"name": "int",
220+
"type": [
221+
"name": "Int",
222+
],
223+
],
224+
[
225+
"args": [
226+
[
227+
"defaultValue": "[1, 2, 3]",
228+
"name": "list",
229+
"type": [
230+
"name": .null,
231+
],
232+
],
233+
],
234+
"name": "list",
235+
"type": [
236+
"name": .null,
237+
],
238+
],
239+
[
240+
"args": [
241+
[
242+
"defaultValue": "{ str: \"hello\" }",
243+
"name": "input",
244+
"type": [
245+
"name": "InputObject",
246+
],
247+
],
248+
],
249+
"name": "object",
250+
"type": [
251+
"name": "Object",
252+
],
253+
],
254+
[
255+
"args": [
256+
[
257+
"defaultValue": "\"hello\"",
258+
"name": "string",
259+
"type": [
260+
"name": "String",
261+
],
262+
],
263+
],
264+
"name": "string",
265+
"type": [
266+
"name": "String",
267+
],
268+
],
269+
],
270+
"name": "Query",
271+
]
272+
)
273+
}
274+
}

0 commit comments

Comments
 (0)