@@ -193,26 +193,23 @@ class RuntimeWiringTest extends Specification {
193
193
newWiring. fieldVisibility == fieldVisibility
194
194
}
195
195
196
- def " strict mode can stop certain redefinitions" () {
196
+ def " strict mode, on by default, can stop certain redefinitions" () {
197
197
DataFetcher DF1 = env -> " x"
198
198
DataFetcher DF2 = env -> " x"
199
199
TypeResolver TR1 = env -> null
200
200
EnumValuesProvider EVP1 = name -> null
201
201
202
202
when :
203
203
RuntimeWiring . newRuntimeWiring()
204
- .strictMode()
205
204
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" foo" , DF1 ))
206
- .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" bar" , DF1 ))
207
-
205
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" foo" , DF1 )) // Cannot redefine the same field's datafetcher
208
206
209
207
then :
210
208
def e1 = thrown(StrictModeWiringException )
211
- e1. message == " The type Foo has already been defined"
209
+ e1. message == " The field foo on type Foo has already been defined"
212
210
213
211
when :
214
212
RuntimeWiring . newRuntimeWiring()
215
- .strictMode()
216
213
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). typeResolver(TR1 ))
217
214
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). typeResolver(TR1 ))
218
215
@@ -222,7 +219,6 @@ class RuntimeWiringTest extends Specification {
222
219
223
220
when :
224
221
RuntimeWiring . newRuntimeWiring()
225
- .strictMode()
226
222
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). enumValues(EVP1 ))
227
223
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). enumValues(EVP1 ))
228
224
then :
@@ -231,15 +227,13 @@ class RuntimeWiringTest extends Specification {
231
227
232
228
when :
233
229
RuntimeWiring . newRuntimeWiring()
234
- .strictMode()
235
230
.scalar(Scalars.GraphQLString )
236
231
then :
237
232
def e4 = thrown(StrictModeWiringException )
238
233
e4. message == " The scalar String is already defined"
239
234
240
235
when :
241
236
TypeRuntimeWiring . newTypeWiring(" Foo" )
242
- .strictMode()
243
237
.defaultDataFetcher(DF1 )
244
238
.defaultDataFetcher(DF2 )
245
239
@@ -248,34 +242,148 @@ class RuntimeWiringTest extends Specification {
248
242
e5. message == " The type Foo has already has a default data fetcher defined"
249
243
}
250
244
251
- def " overwrite default data fetchers if they are null" () {
252
-
245
+ def " strict mode, on by default, permits a type to be defined more than once as long as elements are not overlapping" () {
253
246
DataFetcher DF1 = env -> " x"
254
247
DataFetcher DF2 = env -> " x"
255
- DataFetcher DEFAULT_DF = env -> null
256
- DataFetcher DEFAULT_DF2 = env -> null
248
+ TypeResolver TR1 = env -> null
249
+ EnumValuesProvider EVP1 = name -> null
257
250
258
251
when :
259
- def runtimeWiring = RuntimeWiring . newRuntimeWiring()
260
- .type( TypeRuntimeWiring . newTypeWiring( " Foo " ) . defaultDataFetcher( DEFAULT_DF ) )
252
+ // Permit type wiring to be defined more than once, if child DataFetchers are for distinct fields
253
+ def runtimeWiring1 = RuntimeWiring . newRuntimeWiring( )
261
254
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" foo" , DF1 ))
262
255
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" bar" , DF2 ))
263
256
.build()
264
257
265
258
then :
266
- runtimeWiring. getDefaultDataFetcherForType(" Foo" ) == DEFAULT_DF
259
+ noExceptionThrown()
260
+ runtimeWiring1. getDataFetchers(). get(" Foo" ). get(" foo" ) == DF1
261
+ runtimeWiring1. getDataFetchers(). get(" Foo" ). get(" bar" ) == DF2
262
+
263
+ when :
264
+ // Only one type wiring is allowed per type, do not allow redefinition
265
+ RuntimeWiring . newRuntimeWiring()
266
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). typeResolver(TR1 ))
267
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). typeResolver(TR1 ))
268
+
269
+ then :
270
+ def e2 = thrown(StrictModeWiringException )
271
+ e2. message == " The type Foo already has a type resolver defined"
272
+
273
+ when :
274
+ // Only one enum values provider is allowed per type, do not allow redefinition
275
+ RuntimeWiring . newRuntimeWiring()
276
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). enumValues(EVP1 ))
277
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). enumValues(EVP1 ))
278
+
279
+ then :
280
+ def e3 = thrown(StrictModeWiringException )
281
+ e3. message == " The type Foo already has a enum provider defined"
282
+
283
+ when :
284
+ // Only one scalar wiring is allowed per scalar
285
+ RuntimeWiring . newRuntimeWiring()
286
+ .scalar(Scalars.GraphQLString )
287
+ then :
288
+ def e4 = thrown(StrictModeWiringException )
289
+ e4. message == " The scalar String is already defined"
290
+
291
+ when :
292
+ // Only one default data fetcher is allowed, do not allow redefinition
293
+ TypeRuntimeWiring . newTypeWiring(" Foo" )
294
+ .defaultDataFetcher(DF1 )
295
+ .defaultDataFetcher(DF2 )
296
+
297
+ then :
298
+ def e5 = thrown(StrictModeWiringException )
299
+ e5. message == " The type Foo has already has a default data fetcher defined"
300
+ }
301
+
302
+ def " strict mode, if set to off, won't stop certain redefinitions" () {
303
+ DataFetcher DF1 = env -> " x"
304
+ DataFetcher DF2 = env -> " x"
305
+ TypeResolver TR1 = env -> null
306
+ EnumValuesProvider EVP1 = name -> null
267
307
268
308
when :
269
- runtimeWiring = RuntimeWiring . newRuntimeWiring()
309
+ def runtimeWiring1 = RuntimeWiring . newRuntimeWiring()
310
+ .strictMode(false )
311
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" foo" , DF1 ))
312
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" foo" , DF2 ))
313
+ .build()
314
+
315
+ then :
316
+ noExceptionThrown()
317
+ runtimeWiring1. getDataFetchers(). get(" Foo" ). get(" foo" ) == DF2
318
+
319
+ when :
320
+ def runtimeWiring2 = RuntimeWiring . newRuntimeWiring()
321
+ .strictMode(false )
322
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). typeResolver(TR1 ))
323
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). typeResolver(TR1 ))
324
+ .build()
325
+
326
+ then :
327
+ noExceptionThrown()
328
+ runtimeWiring2. typeResolvers. get(" Foo" ) == TR1
329
+
330
+ when :
331
+ def runtimeWiring3 = RuntimeWiring . newRuntimeWiring()
332
+ .strictMode(false )
333
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). enumValues(EVP1 ))
334
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). enumValues(EVP1 ))
335
+ .build()
336
+
337
+ then :
338
+ noExceptionThrown()
339
+ runtimeWiring3. getEnumValuesProviders(). get(" Foo" ) == EVP1
340
+
341
+ when :
342
+ def runtimeWiring4 = RuntimeWiring . newRuntimeWiring()
343
+ .strictMode(false )
344
+ .scalar(Scalars.GraphQLString )
345
+ .build()
346
+
347
+ then :
348
+ noExceptionThrown()
349
+ runtimeWiring4. scalars. get(" String" ) == Scalars.GraphQLString
350
+
351
+ when :
352
+ def typeRuntimeWiring = TypeRuntimeWiring . newTypeWiring(" Foo" )
353
+ .strictMode(false )
354
+ .defaultDataFetcher(DF1 )
355
+ .defaultDataFetcher(DF2 )
356
+ .build()
357
+
358
+ then :
359
+ noExceptionThrown()
360
+ typeRuntimeWiring. defaultDataFetcher == DF2
361
+ }
362
+
363
+ def " when strict mode on, do not allow default data fetcher redefinition" () {
364
+ DataFetcher DF1 = env -> " w"
365
+ DataFetcher DEFAULT_DF = env -> " x"
366
+ DataFetcher DEFAULT_DF2 = env -> " y"
367
+
368
+ // Having a datafetcher and a default for the type is ok
369
+ when :
370
+ def runtimeWiring1 = RuntimeWiring . newRuntimeWiring()
270
371
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). defaultDataFetcher(DEFAULT_DF ))
271
372
.type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" foo" , DF1 ))
272
- .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). dataFetcher(" bar" , DF2 ))
273
- // we can specifically overwrite it later
274
- .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). defaultDataFetcher(DEFAULT_DF2 ))
275
373
.build()
276
374
277
375
then :
278
- runtimeWiring . getDefaultDataFetcherForType(" Foo" ) == DEFAULT_DF2
376
+ runtimeWiring1 . getDefaultDataFetcherForType(" Foo" ) == DEFAULT_DF
279
377
378
+ // Do not permit redefinition of the default datafetcher
379
+ when :
380
+ RuntimeWiring . newRuntimeWiring()
381
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). defaultDataFetcher(DEFAULT_DF ))
382
+ .type(TypeRuntimeWiring . newTypeWiring(" Foo" ). defaultDataFetcher(DEFAULT_DF2 ))
383
+ .build()
384
+
385
+ then :
386
+ def error = thrown(StrictModeWiringException )
387
+ error. message == " The type Foo already has a default data fetcher defined"
280
388
}
281
389
}
0 commit comments