@@ -99,6 +99,10 @@ class PartialSchemaTests: XCTestCase {
9999 func testPartialSchemaWithBuilder( ) throws {
100100 let group = MultiThreadedEventLoopGroup ( numberOfThreads: System . coreCount)
101101
102+ defer {
103+ try ? group. syncShutdownGracefully ( )
104+ }
105+
102106 let builder = SchemaBuilder ( StarWarsResolver . self, StarWarsContext . self)
103107
104108 builder. use ( partials: [ BaseSchema ( ) , SearchSchema ( ) ] )
@@ -135,6 +139,10 @@ class PartialSchemaTests: XCTestCase {
135139 func testPartialSchema( ) throws {
136140 let group = MultiThreadedEventLoopGroup ( numberOfThreads: System . coreCount)
137141
142+ defer {
143+ try ? group. syncShutdownGracefully ( )
144+ }
145+
138146 /// Double check if static func works and the types are inferred properly
139147 let schema = try Schema . create ( from: [ BaseSchema ( ) , SearchSchema ( ) ] )
140148
@@ -168,6 +176,10 @@ class PartialSchemaTests: XCTestCase {
168176 func testPartialSchemaOutOfOrder( ) throws {
169177 let group = MultiThreadedEventLoopGroup ( numberOfThreads: System . coreCount)
170178
179+ defer {
180+ try ? group. syncShutdownGracefully ( )
181+ }
182+
171183 /// Double check if ordering of partial schema doesn't matter
172184 let schema = try Schema . create ( from: [ SearchSchema ( ) , BaseSchema ( ) ] )
173185
@@ -197,4 +209,131 @@ class PartialSchemaTests: XCTestCase {
197209 ] )
198210 )
199211 }
212+
213+ func testInstancePartialSchema( ) throws {
214+ let baseSchema = PartialSchema < StarWarsResolver , StarWarsContext > (
215+ types: {
216+ Interface ( Character . self) {
217+ Field ( " id " , at: \. id)
218+ . description ( " The id of the character. " )
219+ Field ( " name " , at: \. name)
220+ . description ( " The name of the character. " )
221+ Field ( " friends " , at: \. friends, as: [ TypeReference < Character > ] . self)
222+ . description (
223+ " The friends of the character, or an empty list if they have none. "
224+ )
225+ Field ( " appearsIn " , at: \. appearsIn)
226+ . description ( " Which movies they appear in. " )
227+ Field ( " secretBackstory " , at: \. secretBackstory)
228+ . description ( " All secrets about their past. " )
229+ }
230+
231+ Enum ( Episode . self) {
232+ Value ( . newHope)
233+ . description ( " Released in 1977. " )
234+ Value ( . empire)
235+ . description ( " Released in 1980. " )
236+ Value ( . jedi)
237+ . description ( " Released in 1983. " )
238+ } . description ( " One of the films in the Star Wars Trilogy. " )
239+ } ,
240+ query: {
241+ Field ( " hero " , at: StarWarsResolver . hero, as: Character . self) {
242+ Argument ( " episode " , at: \. episode)
243+ . description (
244+ " If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode. "
245+ )
246+ } . description ( " Returns a hero based on the given episode. " )
247+ }
248+ )
249+
250+ let searchSchema = PartialSchema < StarWarsResolver , StarWarsContext > (
251+ types: {
252+ Type ( Planet . self) {
253+ Field ( " id " , at: \. id)
254+ Field ( " name " , at: \. name)
255+ Field ( " diameter " , at: \. diameter)
256+ Field ( " rotationPeriod " , at: \. rotationPeriod)
257+ Field ( " orbitalPeriod " , at: \. orbitalPeriod)
258+ Field ( " residents " , at: \. residents)
259+ } . description (
260+ " A large mass, planet or planetoid in the Star Wars Universe, at the time of 0 ABY. "
261+ )
262+ Type ( Human . self, interfaces: [ Character . self] ) {
263+ Field ( " id " , at: \. id)
264+ Field ( " name " , at: \. name)
265+ Field ( " appearsIn " , at: \. appearsIn)
266+ Field ( " homePlanet " , at: \. homePlanet)
267+ Field ( " friends " , at: Human . getFriends, as: [ Character ] . self)
268+ . description (
269+ " The friends of the human, or an empty list if they have none. "
270+ )
271+ Field ( " secretBackstory " , at: Human . getSecretBackstory)
272+ . description ( " Where are they from and how they came to be who they are. " )
273+ } . description ( " A humanoid creature in the Star Wars universe. " )
274+ Type ( Droid . self, interfaces: [ Character . self] ) {
275+ Field ( " id " , at: \. id)
276+ Field ( " name " , at: \. name)
277+ Field ( " appearsIn " , at: \. appearsIn)
278+ Field ( " primaryFunction " , at: \. primaryFunction)
279+ Field ( " friends " , at: Droid . getFriends, as: [ Character ] . self)
280+ . description (
281+ " The friends of the droid, or an empty list if they have none. "
282+ )
283+ Field ( " secretBackstory " , at: Droid . getSecretBackstory)
284+ . description ( " Where are they from and how they came to be who they are. " )
285+ } . description ( " A mechanical creature in the Star Wars universe. " )
286+ Union ( SearchResult . self, members: Planet . self, Human . self, Droid . self)
287+ } ,
288+ query: {
289+ Field ( " human " , at: StarWarsResolver . human) {
290+ Argument ( " id " , at: \. id)
291+ . description ( " Id of the human. " )
292+ }
293+ Field ( " droid " , at: StarWarsResolver . droid) {
294+ Argument ( " id " , at: \. id)
295+ . description ( " Id of the droid. " )
296+ }
297+ Field ( " search " , at: StarWarsResolver . search, as: [ SearchResult ] . self) {
298+ Argument ( " query " , at: \. query)
299+ . defaultValue ( " R2-D2 " )
300+ }
301+ }
302+ )
303+
304+ let group = MultiThreadedEventLoopGroup ( numberOfThreads: System . coreCount)
305+
306+ defer {
307+ try ? group. syncShutdownGracefully ( )
308+ }
309+
310+ /// Double check if ordering of partial schema doesn't matter
311+ let schema = try Schema . create ( from: [ searchSchema, baseSchema] )
312+
313+ struct PartialSchemaTestAPI : API {
314+ let resolver : StarWarsResolver
315+ let schema : Schema < StarWarsResolver , StarWarsContext >
316+ }
317+
318+ let api = PartialSchemaTestAPI ( resolver: StarWarsResolver ( ) , schema: schema)
319+
320+ XCTAssertEqual (
321+ try api. execute (
322+ request: """
323+ query {
324+ human(id: " 1000 " ) {
325+ name
326+ }
327+ }
328+ """ ,
329+ context: StarWarsContext ( ) ,
330+ on: group
331+ ) . wait ( ) ,
332+ GraphQLResult ( data: [
333+ " human " : [
334+ " name " : " Luke Skywalker " ,
335+ ] ,
336+ ] )
337+ )
338+ }
200339}
0 commit comments