@@ -21,7 +21,7 @@ import {
2121import {
2222 GraphQLSchema ,
2323 GraphQLObjectType ,
24- GraphQLUnionType ,
24+ GraphQLInterfaceType ,
2525 GraphQLList ,
2626 GraphQLNonNull ,
2727 GraphQLInt ,
@@ -101,6 +101,21 @@ describe('Validate: Overlapping fields can be merged', () => {
101101 ] ) ;
102102 } ) ;
103103
104+ it ( 'Same aliases allowed on non-overlapping fields' , ( ) => {
105+ // This is valid since no object can be both a "Dog" and a "Cat", thus
106+ // these fields can never overlap.
107+ expectPassesRule ( OverlappingFieldsCanBeMerged , `
108+ fragment sameAliasesWithDifferentFieldTargets on Pet {
109+ ... on Dog {
110+ name
111+ }
112+ ... on Cat {
113+ name: nickname
114+ }
115+ }
116+ ` ) ;
117+ } ) ;
118+
104119 it ( 'Alias masking direct field access' , ( ) => {
105120 expectFailsRule ( OverlappingFieldsCanBeMerged , `
106121 fragment aliasMaskingDirectFieldAccess on Dog {
@@ -131,6 +146,21 @@ describe('Validate: Overlapping fields can be merged', () => {
131146 ] ) ;
132147 } ) ;
133148
149+ it ( 'allows different args where no conflict is possible' , ( ) => {
150+ // This is valid since no object can be both a "Dog" and a "Cat", thus
151+ // these fields can never overlap.
152+ expectPassesRule ( OverlappingFieldsCanBeMerged , `
153+ fragment conflictingArgs on Pet {
154+ ... on Dog {
155+ name(surname: true)
156+ }
157+ ... on Cat {
158+ name
159+ }
160+ }
161+ ` ) ;
162+ } ) ;
163+
134164 it ( 'conflicting directives' , ( ) => {
135165 expectFailsRule ( OverlappingFieldsCanBeMerged , `
136166 fragment conflictingDirectiveArgs on Dog {
@@ -353,39 +383,67 @@ describe('Validate: Overlapping fields can be merged', () => {
353383
354384 describe ( 'return types must be unambiguous' , ( ) => {
355385
386+ var SomeBox = new GraphQLInterfaceType ( {
387+ name : 'SomeBox' ,
388+ resolveType : ( ) => StringBox ,
389+ fields : {
390+ unrelatedField : { type : GraphQLString }
391+ }
392+ } ) ;
393+
394+ /* eslint-disable no-unused-vars */
356395 var StringBox = new GraphQLObjectType ( {
357396 name : 'StringBox' ,
397+ interfaces : [ SomeBox ] ,
358398 fields : {
359- scalar : { type : GraphQLString }
399+ scalar : { type : GraphQLString } ,
400+ unrelatedField : { type : GraphQLString } ,
360401 }
361402 } ) ;
362403
363404 var IntBox = new GraphQLObjectType ( {
364405 name : 'IntBox' ,
406+ interfaces : [ SomeBox ] ,
365407 fields : {
366- scalar : { type : GraphQLInt }
408+ scalar : { type : GraphQLInt } ,
409+ unrelatedField : { type : GraphQLString } ,
367410 }
368411 } ) ;
369412
370- var NonNullStringBox1 = new GraphQLObjectType ( {
413+ var NonNullStringBox1 = new GraphQLInterfaceType ( {
371414 name : 'NonNullStringBox1' ,
415+ resolveType : ( ) => StringBox ,
372416 fields : {
373417 scalar : { type : new GraphQLNonNull ( GraphQLString ) }
374418 }
375419 } ) ;
376420
377- var NonNullStringBox2 = new GraphQLObjectType ( {
421+ var NonNullStringBox1Impl = new GraphQLObjectType ( {
422+ name : 'NonNullStringBox1Impl' ,
423+ interfaces : [ SomeBox , NonNullStringBox1 ] ,
424+ fields : {
425+ scalar : { type : new GraphQLNonNull ( GraphQLString ) } ,
426+ unrelatedField : { type : GraphQLString } ,
427+ }
428+ } ) ;
429+
430+ var NonNullStringBox2 = new GraphQLInterfaceType ( {
378431 name : 'NonNullStringBox2' ,
432+ resolveType : ( ) => StringBox ,
379433 fields : {
380434 scalar : { type : new GraphQLNonNull ( GraphQLString ) }
381435 }
382436 } ) ;
383437
384- var BoxUnion = new GraphQLUnionType ( {
385- name : 'BoxUnion' ,
386- resolveType : ( ) => StringBox ,
387- types : [ StringBox , IntBox , NonNullStringBox1 , NonNullStringBox2 ]
438+ var NonNullStringBox2Impl = new GraphQLObjectType ( {
439+ name : 'NonNullStringBox2Impl' ,
440+ interfaces : [ SomeBox , NonNullStringBox2 ] ,
441+ fields : {
442+ scalar : { type : new GraphQLNonNull ( GraphQLString ) } ,
443+ unrelatedField : { type : GraphQLString } ,
444+ }
388445 } ) ;
446+ /* eslint-enable no-unused-vars */
389447
390448 var Connection = new GraphQLObjectType ( {
391449 name : 'Connection' ,
@@ -413,37 +471,57 @@ describe('Validate: Overlapping fields can be merged', () => {
413471 query : new GraphQLObjectType ( {
414472 name : 'QueryRoot' ,
415473 fields : ( ) => ( {
416- boxUnion : { type : BoxUnion } ,
474+ someBox : { type : SomeBox } ,
417475 connection : { type : Connection }
418476 } )
419477 } )
420478 } ) ;
421479
422- it ( 'conflicting scalar return types' , ( ) => {
480+ it ( 'conflicting return types which potentially overlap' , ( ) => {
481+ // This is invalid since an object could potentially be both the Object
482+ // type IntBox and the interface type NonNullStringBox1. While that
483+ // condition does not exist in the current schema, the schema could
484+ // expand in the future to allow this. Thus it is invalid.
423485 expectFailsRuleWithSchema ( schema , OverlappingFieldsCanBeMerged , `
424486 {
425- boxUnion {
487+ someBox {
426488 ...on IntBox {
427489 scalar
428490 }
429- ...on StringBox {
491+ ...on NonNullStringBox1 {
430492 scalar
431493 }
432494 }
433495 }
434496 ` , [
435497 { message : fieldsConflictMessage (
436498 'scalar' ,
437- 'they return differing types Int and String'
499+ 'they return differing types Int and String! '
438500 ) ,
439501 locations : [ { line : 5 , column : 15 } , { line : 8 , column : 15 } ] }
440502 ] ) ;
441503 } ) ;
442504
505+ it ( 'allows differing return types which cannot overlap' , ( ) => {
506+ // This is valid since an object cannot be both an IntBox and a StringBox.
507+ expectPassesRuleWithSchema ( schema , OverlappingFieldsCanBeMerged , `
508+ {
509+ someBox {
510+ ...on IntBox {
511+ scalar
512+ }
513+ ...on StringBox {
514+ scalar
515+ }
516+ }
517+ }
518+ ` ) ;
519+ } ) ;
520+
443521 it ( 'same wrapped scalar return types' , ( ) => {
444522 expectPassesRuleWithSchema ( schema , OverlappingFieldsCanBeMerged , `
445523 {
446- boxUnion {
524+ someBox {
447525 ...on NonNullStringBox1 {
448526 scalar
449527 }
@@ -505,7 +583,7 @@ describe('Validate: Overlapping fields can be merged', () => {
505583 it ( 'ignores unknown types' , ( ) => {
506584 expectPassesRuleWithSchema ( schema , OverlappingFieldsCanBeMerged , `
507585 {
508- boxUnion {
586+ someBox {
509587 ...on UnknownType {
510588 scalar
511589 }
0 commit comments