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 conflicting types Int and String!", L(5, 17), L(8, 17), ) ], sort_list=False, )
def test_disallows_differing_return_type_nullability_despite_no_overlap(): expect_fails_rule_with_schema( schema, OverlappingFieldsCanBeMerged, """ { someBox { ... on NonNullStringBox1 { scalar } ... on StringBox { scalar } } } """, [ fields_conflict( "scalar", "they return conflicting types String! and String", L(5, 15), L(8, 15), ) ], sort_list=False, )
def test_reports_correctly_when_a_non_exclusive_follows_an_exclusive(): expect_fails_rule_with_schema( schema, OverlappingFieldsCanBeMerged, """ { someBox { ... on IntBox { deepBox { ...X } } } someBox { ... on StringBox { deepBox { ...Y } } } memoed: someBox { ... on IntBox { deepBox { ...X } } } memoed: someBox { ... on StringBox { deepBox { ...Y } } } other: someBox { ...X } other: someBox { ...Y } } fragment X on SomeBox { scalar } fragment Y on SomeBox { scalar: unrelatedField } """, [ fields_conflict( "other", [("scalar", "scalar and unrelatedField are different fields")], L(31, 11), L(39, 11), L(34, 11), L(42, 11), ) ], sort_list=False, )
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_disallows_differing_return_type_list_despite_no_overlap_1(): expect_fails_rule_with_schema( schema, OverlappingFieldsCanBeMerged, """ { someBox { ... on IntBox { box: listStringBox { scalar } } ... on StringBox { box: stringBox { scalar } } } } """, [ fields_conflict( "box", "they return conflicting types [StringBox] and StringBox", L(5, 15), L(10, 15), ) ], sort_list=False, )
def test_disallows_differing_subfields(): expect_fails_rule_with_schema( schema, OverlappingFieldsCanBeMerged, """ { someBox { ... on IntBox { box: stringBox { val: scalar val: unrelatedField } } ... on StringBox { box: stringBox { val: scalar } } } } """, [ fields_conflict( "val", "scalar and unrelatedField are different fields", L(6, 17), L(7, 17), ) ], sort_list=False, )
def test_reports_deep_conflict_to_nearest_common_ancestor_in_fragments(): expect_fails_rule(OverlappingFieldsCanBeMerged, ''' { field { ...F }, field { ...F } } fragment F on T { deepField { deeperField { x: a } deeperField { x: b } } deepField { deeperField { y } } } ''', [ fields_conflict( 'deeperField', [('x', 'a and b are different fields')], L(12, 11), L(13, 13), L(15, 11), L(16, 13) ) ], sort_list=False)
def test_disallows_differing_deep_return_types_despite_no_overlap(): expect_fails_rule_with_schema( schema, OverlappingFieldsCanBeMerged, """ { someBox { ... on IntBox { box: stringBox { scalar } } ... on StringBox { box: intBox { scalar } } } } """, [ fields_conflict( "box", [["scalar", "they return conflicting types String and Int"]], L(5, 15), L(6, 17), L(10, 15), L(11, 17), ) ], 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 { ...fragP } fragment fragP on Dog { ...fragA, ...fragX } """, [ cycle_error_message( "fragA", ["fragB", "fragC", "fragO", "fragP"], L(2, 29), L(3, 29), L(4, 29), L(8, 29), L(9, 29), ), cycle_error_message( "fragO", ["fragP", "fragX", "fragY", "fragZ"], L(8, 29), L(9, 39), L(5, 29), L(6, 29), L(7, 29), ), ], )
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(4, 13), L(6, 9), L(7, 13), ) ], 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(5, 17), L(7, 13), L(8, 17), ) ], 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_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_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_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_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_many_duplicate_input_object_fields(): expect_fails_rule( UniqueInputFieldNames, """ { field(arg: { f1: "value", f1: "value", f1: "value" }) } """, [ duplicate_field("f1", L(3, 22), L(3, 35)), duplicate_field("f1", L(3, 22), L(3, 48)), ], )
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_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(4, 13), L(6, 9), 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_diferent_args_second_missing_an_argument(): expect_fails_rule( OverlappingFieldsCanBeMerged, """ fragment conflictingArgs on Dog { doesKnowCommand(dogCommand: SIT) doesKnowCommand } """, [ fields_conflict("doesKnowCommand", "they have differing arguments", L(3, 9), L(4, 9)) ], 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_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_no_spreading_itself_directly(): expect_fails_rule( NoFragmentCycles, """ fragment fragA on Dog { ...fragA } """, [cycle_error_message("fragA", [], L(2, 29))], )
def test_disallows_differing_return_types_despite_no_overlap(): expect_fails_rule_with_schema(schema, OverlappingFieldsCanBeMerged, ''' { someBox { ... on IntBox { scalar } ... on StringBox { scalar } } } ''', [ fields_conflict( 'scalar', 'they return conflicting types Int and String', L(5, 15), L(8, 15), ) ], 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 { ...fragP } fragment fragP on Dog { ...fragA, ...fragX } ''', [ cycle_error_message('fragA', ['fragB', 'fragC', 'fragO', 'fragP'], L(2, 29), L(3, 29), L(4, 29), L(8, 29), L( 9, 29)), cycle_error_message('fragO', ['fragP', 'fragX', 'fragY', 'fragZ'], L(8, 29), L(9, 39), L(5, 29), L(6, 29), L( 7, 29)) ])
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(4, 11), L(5, 11), L(7, 9), L(8, 11), L(9, 11), ) ], sort_list=False, )
def test_reports_deep_conflict_to_nearest_common_ancestor_in_fragments(): expect_fails_rule( OverlappingFieldsCanBeMerged, """ { field { ...F }, field { ...F } } fragment F on T { deepField { deeperField { x: a } deeperField { x: b } } deepField { deeperField { y } } } """, [ fields_conflict( "deeperField", [("x", "a and b are different fields")], L(12, 11), L(13, 13), L(15, 11), L(16, 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(4, 13), L(5, 17), L(8, 9), L(9, 13), L(10, 17), ) ], sort_list=False, )