def test_duplicate_input_object_fields(): expect_fails_rule( UniqueInputFieldNames, ''' { field(arg: { f1: "value", f1: "value" }) } ''', [duplicate_field("f1", L(3, 22), L(3, 35))])
def test_no_spreading_itself_indirectly_reports_opposite_order(): expect_fails_rule(NoFragmentCycles, ''' fragment fragB on Dog { ...fragA } fragment fragA on Dog { ...fragB } ''', [ cycle_error_message('fragB', ['fragA'], L(2, 29), L(3, 29)) ])
def test_no_spreading_itself_deeply_two_paths(): # -- new rule expect_fails_rule(NoFragmentCycles, ''' fragment fragA on Dog { ...fragB, ...fragC } fragment fragB on Dog { ...fragA } fragment fragC on Dog { ...fragA } ''', [ cycle_error_message('fragA', ['fragB'], L(2, 29), L(3, 29)), cycle_error_message('fragA', ['fragC'], L(2, 39), L(4, 29)) ])
def test_no_spreading_itself_deeply_two_paths_alt_reverse_order(): expect_fails_rule( NoFragmentCycles, ''' fragment fragA on Dog { ...fragC } fragment fragB on Dog { ...fragC } fragment fragC on Dog { ...fragA, ...fragB } ''', [ cycle_error_message('fragA', ['fragC'], L(2, 29), L(4, 29)), cycle_error_message('fragC', ['fragB'], L(4, 39), L(3, 29)) ])
def test_conflicting_directive_args(): expect_fails_rule( OverlappingFieldsCanBeMerged, ''' fragment conflictingDirectiveArgs on Dog { name @include(if: true) name @include(if: false) } ''', [ fields_conflict('name', 'they have differing directives', L(3, 9), L(4, 9)) ], sort_list=False)
def test_alias_masking_direct_field_access(): expect_fails_rule( OverlappingFieldsCanBeMerged, ''' fragment aliasMaskingDirectFieldAccess on Dog { name: nickname name } ''', [ fields_conflict('name', 'nickname and name are different fields', L(3, 9), L(4, 9)) ], sort_list=False)
def test_conflicting_directives_with_matching_args(): expect_fails_rule( OverlappingFieldsCanBeMerged, ''' fragment conflictingDirectiveArgsWithMatchingArgs on Dog { doesKnowCommand(dogCommand: SIT) @include(if: true) doesKnowCommand(dogCommand: SIT) @skip(if: false) } ''', [ fields_conflict('doesKnowCommand', 'they have differing directives', L(3, 9), L(4, 9)) ], sort_list=False)
def test_conflicting_args(): expect_fails_rule( OverlappingFieldsCanBeMerged, ''' fragment conflictingArgs on Dog { doesKnowCommand(dogCommand: SIT) doesKnowCommand(dogCommand: HEEL) } ''', [ fields_conflict('doesKnowCommand', 'they have differing arguments', L(3, 9), L(4, 9)) ], sort_list=False)
def test_same_aliases_with_different_field_targets(): expect_fails_rule( OverlappingFieldsCanBeMerged, ''' fragment sameAliasesWithDifferentFieldTargets on Dog { fido: name fido: nickname } ''', [ fields_conflict('fido', 'name and nickname are different fields', L(3, 9), L(4, 9)) ], sort_list=False)
def test_no_spreading_itself_deeply(): expect_fails_rule(NoFragmentCycles, ''' fragment fragA on Dog { ...fragB } fragment fragB on Dog { ...fragC } fragment fragC on Dog { ...fragO } fragment fragX on Dog { ...fragY } fragment fragY on Dog { ...fragZ } fragment fragZ on Dog { ...fragO } fragment fragO on Dog { ...fragA, ...fragX } ''', [ cycle_error_message('fragA', ['fragB', 'fragC', 'fragO'], L(2, 29), L(3, 29), L(4, 29), L(8, 29)), cycle_error_message('fragX', ['fragY', 'fragZ', 'fragO'], L(5, 29), L(6, 29), L(7, 29), L(8, 39)) ])
def test_no_spreading_itself_indirectly_within_inline_fragment(): expect_fails_rule( NoFragmentCycles, ''' fragment fragA on Pet { ... on Dog { ...fragB } } fragment fragB on Pet { ... on Dog { ...fragA } } ''', [cycle_error_message('fragA', ['fragB'], L(4, 13), L(9, 13))])
def test_deep_conflict(): expect_fails_rule( OverlappingFieldsCanBeMerged, ''' { field { x: a } field { x: b } } ''', [ fields_conflict('field', [('x', 'a and b are different fields')], L(3, 9), L(6, 9), L(4, 13), L(7, 13)) ], sort_list=False)
def test_encounters_conflict_in_fragments(): expect_fails_rule(OverlappingFieldsCanBeMerged, ''' { ...A ...B } fragment A on Type { x: a } fragment B on Type { x: b } ''', [ fields_conflict('x', 'a and b are different fields', L(7, 9), L(10, 9)) ], sort_list=False)
def test_reports_each_conflict_once(): expect_fails_rule(OverlappingFieldsCanBeMerged, ''' { f1 { ...A ...B } f2 { ...B ...A } f3 { ...A ...B x: c } } fragment A on Type { x: a } fragment B on Type { x: b } ''', [ fields_conflict('x', 'a and b are different fields', L(18, 9), L(21, 9)), fields_conflict('x', 'a and c are different fields', L(18, 9), L(14, 13)), fields_conflict('x', 'b and c are different fields', L(21, 9), L(14, 13)) ], sort_list=False)
def test_conflicting_scalar_return_types(): expect_fails_rule_with_schema( schema, OverlappingFieldsCanBeMerged, ''' { boxUnion { ...on IntBox { scalar } ...on StringBox { scalar } } } ''', [ fields_conflict( 'scalar', 'they return differing types Int and String', L( 5, 17), L(8, 17)) ], sort_list=False)
def test_conflicting_return_types_which_potentially_overlap(): expect_fails_rule_with_schema( schema, OverlappingFieldsCanBeMerged, ''' { someBox { ...on IntBox { scalar } ...on NonNullStringBox1 { scalar } } } ''', [ fields_conflict('scalar', 'they return differing types Int and String!', L(5, 17), L(8, 17)) ], sort_list=False)
def test_reports_deep_conflict_to_nearest_common_ancestor(): expect_fails_rule(OverlappingFieldsCanBeMerged, ''' { field { deepField { x: a } deepField { x: b } }, field { deepField { y } } } ''', [ fields_conflict('deepField', [ ('x', 'a and b are different fields') ], L(4, 13), L(7, 13), L(5, 17), L(8, 17)) ], sort_list=False)
def test_no_spreading_itself_deeply_and_immediately(): expect_fails_rule( NoFragmentCycles, ''' fragment fragA on Dog { ...fragB } fragment fragB on Dog { ...fragB, ...fragC } fragment fragC on Dog { ...fragA, ...fragB } ''', [ cycle_error_message('fragB', [], L(3, 29)), cycle_error_message('fragA', ['fragB', 'fragC'], L(2, 29), L( 3, 39), L(4, 29)), cycle_error_message('fragB', ['fragC'], L(3, 39), L(4, 39)) ])
def test_deep_conflict_with_multiple_issues(): expect_fails_rule( OverlappingFieldsCanBeMerged, ''' { field { x: a y: c } field { x: b y: d } } ''', [ fields_conflict('field', [('x', 'a and b are different fields'), ('y', 'c and d are different fields')], L(3, 9), L(7, 9), L(4, 13), L(8, 13), L(5, 13), L(9, 13)) ], sort_list=False)
def test_very_deep_conflict(): expect_fails_rule( OverlappingFieldsCanBeMerged, ''' { field { deepField { x: a } }, field { deepField { x: b } } } ''', [ fields_conflict( 'field', [['deepField', [['x', 'a and b are different fields']]]], L(3, 9), L(8, 9), L(4, 13), L(9, 13), L(5, 17), L(10, 17)) ], sort_list=False)
def test_compares_deep_types_including_list(): expect_fails_rule_with_schema( schema, OverlappingFieldsCanBeMerged, ''' { connection { ...edgeID edges { node { id: name } } } } fragment edgeID on Connection { edges { node { id } } } ''', [ fields_conflict( 'edges', [['node', [['id', 'id and name are different fields']]]], L(14, 9), L(5, 13), L(15, 13), L(6, 17), L(16, 17), L(7, 21), ) ], sort_list=False)
def test_spreading_recursively_within_field_fails(): expect_fails_rule( NoFragmentCycles, ''' fragment fragA on Human { relatives { ...fragA } }, ''', [cycle_error_message('fragA', [], L(2, 43))])
def test_no_spreading_itself_directly(): expect_fails_rule(NoFragmentCycles, ''' fragment fragA on Dog { ...fragA } ''', [cycle_error_message('fragA', [], L(2, 29))])