def test_it_experimental_allows_parsing_fragment_defined_variables(): with pytest.raises(GraphQLSyntaxError): parse("fragment a($v: Boolean = false) on t { f(v: $v) }") assert parse( "fragment a($v: Boolean = false) on t { f(v: $v) }", experimental_fragment_variables=True, )
def test_it_provides_useful_errors(value, error_cls, position, message): with pytest.raises(error_cls) as exc_info: parse(value) if position is not None: assert exc_info.value.position == position if message is not None: assert exc_info.value.message == message
def test_it_does_not_parses_kitchen_sink_when_allow_type_system_is_false( fixture_file, ): with pytest.raises(UnexpectedToken): parse( fixture_file("schema-kitchen-sink.graphql"), no_location=True, allow_type_system=False, )
def test_directive_with_incorrect_locations_fails(): with pytest.raises(UnexpectedToken) as exc_info: parse( """ directive @foo on FIELD | INCORRECT_LOCATION""", allow_type_system=True, ) assert exc_info.value.position == 33 assert exc_info.value.message == "Unexpected Name INCORRECT_LOCATION"
def test_extension_do_not_include_descriptions_1(): with pytest.raises(UnexpectedToken) as exc_info: parse( """ extend "Description" type Hello { world: String }""", allow_type_system=True, ) assert exc_info.value.position == 14 assert exc_info.value.message == 'Unexpected "Description"'
def test_simple_input_object_with_args_should_fail(): with pytest.raises(UnexpectedToken) as exc_info: parse( """ input Hello { world(foo: Int): String }""", allow_type_system=True, ) assert exc_info.value.position == 34 assert exc_info.value.message == 'Expected Colon but found "("'
def test_it_parses_simple_extension(): body = """ extend type Hello { world: String } """ assert_node_equal( parse(body, allow_type_system=True), _doc( (0, 39), [ _ast.ObjectTypeExtension( loc=(1, 38), name=_name((13, 18), "Hello"), interfaces=[], directives=[], fields=[ _field( (23, 36), _name((23, 28), "world"), _type((30, 36), "String"), ) ], ) ], ), )
def test_it_parses_type_with_description_multi_line_string(): body = ''' """ Description """ # Even with comments between them type Hello { world: String }''' assert_node_equal( parse(body, allow_type_system=True), _ast.Document( loc=(0, 85), definitions=[ _ast.ObjectTypeDefinition( loc=(1, 85), name=_name((60, 65), "Hello"), interfaces=[], directives=[], description=_ast.StringValue(loc=(1, 20), value="Description", block=True), fields=[ _field( (70, 83), _name((70, 75), "world"), _type((77, 83), "String"), ) ], ) ], ), )
def test_it_parses_variable_definition_with_default_and_directives(): assert_node_equal( parse("query ($foo: Int = 42 @bar @baz) { foo }", no_location=True), _ast.Document( definitions=[ _ast.OperationDefinition( "query", _ast.SelectionSet( selections=[_ast.Field(name=_ast.Name(value="foo"),)], ), variable_definitions=[ _ast.VariableDefinition( variable=_ast.Variable( name=_ast.Name(value="foo"), ), type=_ast.NamedType(name=_ast.Name(value="Int"),), default_value=_ast.IntValue(value="42"), directives=[ _ast.Directive(name=_ast.Name(value="bar")), _ast.Directive(name=_ast.Name(value="baz")), ], ) ], ) ], ), )
def test_it_parses_extension_without_fields_followed_by_extension(): assert_node_equal( parse( """ extend type Hello implements Greeting extend type Hello implements SecondGreeting """, allow_type_system=True, ), _ast.Document( loc=(0, 100), definitions=[ _ast.ObjectTypeExtension( loc=(7, 44), name=_name((19, 24), "Hello"), interfaces=[_type((36, 44), "Greeting")], fields=[], directives=[], ), _ast.ObjectTypeExtension( loc=(52, 95), name=_name((64, 69), "Hello"), interfaces=[_type((81, 95), "SecondGreeting")], fields=[], directives=[], ), ], ), )
def test_it_parses_simple_field_with_arg_with_default_value(): body = """ type Hello { world(flag: Boolean = true): String }""" assert_node_equal( parse(body, allow_type_system=True), _doc( (0, 53), [ _ast.ObjectTypeDefinition( loc=(1, 53), name=_name((6, 11), "Hello"), interfaces=[], directives=[], fields=[ _field( (16, 51), _name((16, 21), "world"), _type((45, 51), "String"), [ _input( (22, 42), _name((22, 26), "flag"), _type((28, 35), "Boolean"), _ast.BooleanValue(loc=(38, 42), value=True), ) ], ) ], ) ], ), )
def test_it_allows_early_exit(): ast = parse("{ a { b { c { d { e } } } } }", no_location=True) class _Visitor(Tracker): def enter(self, node): n = super(_Visitor, self).enter(node) if n and isinstance(n, _ast.Field) and n.name.value == "b": # Interrupt processing by raising. raise SkipNode() return n visitor = _Visitor() visitor.visit(ast) assert visitor.stack == [ ("enter", "Document"), ("enter", "OperationDefinition"), ("enter", "SelectionSet"), ("enter", "Field"), ("enter", "SelectionSet"), ("enter", "Field"), ("leave", "SelectionSet"), ("leave", "Field"), ("leave", "SelectionSet"), ("leave", "OperationDefinition"), ("leave", "Document"), ]
def test_it_parses_simple_type_inheriting_multiple_interfaces_with_leading_ampersand( ): # noqa: E501 body = "type Hello implements & Wo & rld { field: String }" assert_node_equal( parse(body, allow_type_system=True), _ast.Document( loc=(0, 50), definitions=[ _ast.ObjectTypeDefinition( loc=(0, 50), name=_name((5, 10), "Hello"), interfaces=[_type((24, 26), "Wo"), _type((29, 32), "rld")], directives=[], fields=[ _field( (35, 48), _name((35, 40), "field"), _type((42, 48), "String"), ) ], ) ], ), )
def test_it_parses_kitchen_sink(fixture_file): # assert doesn't raise assert parse( fixture_file("schema-kitchen-sink.graphql"), no_location=True, allow_type_system=True, )
def test_it_parses_github_schema(fixture_file): # assert doesn't raise assert parse( fixture_file("github-schema.graphql"), no_location=True, allow_type_system=True, )
def test_it_parses_type_with_description_string(): assert_node_equal( parse( """ "Description" type Hello { world: String }""", allow_type_system=True, ), _ast.Document( loc=(0, 45), definitions=[ _ast.ObjectTypeDefinition( loc=(1, 45), name=_name((20, 25), "Hello"), interfaces=[], directives=[], description=_ast.StringValue(loc=(1, 14), value="Description"), fields=[ _field( (30, 43), _name((30, 35), "world"), _type((37, 43), "String"), ) ], ) ], ), )
def test_it_parses_simple_type(): body = """ type Hello { world: String }""" assert_node_equal( parse(body, allow_type_system=True), _ast.Document( loc=(0, 31), definitions=[ _ast.ObjectTypeDefinition( loc=(1, 31), name=_name((6, 11), "Hello"), interfaces=[], directives=[], fields=[ _field( (16, 29), _name((16, 21), "world"), _type((23, 29), "String"), ) ], ) ], ), )
def test_it_parses_simple_interface(): body = """ interface Hello { world: String }""" assert_node_equal( parse(body, allow_type_system=True), _doc( (0, 36), [ _ast.InterfaceTypeDefinition( loc=(1, 36), name=_name((11, 16), "Hello"), directives=[], fields=[ _field( (21, 34), _name((21, 26), "world"), _type((28, 34), "String"), ) ], ) ], ), )
def test_it_parses_simple_input_object(): body = """ input Hello { world: String }""" assert_node_equal( parse(body, allow_type_system=True), _doc( (0, 32), [ _ast.InputObjectTypeDefinition( loc=(1, 32), name=_name((7, 12), "Hello"), directives=[], fields=[ _input( (17, 30), _name((17, 22), "world"), _type((24, 30), "String"), ) ], ) ], ), )
def test_it_parses_named_subscription_operations(): assert parse( """ subscription Foo { subscriptionField }""", no_location=True, )
def test_it_parses_named_mutation_operations(): assert parse( """ mutation Foo { mutationField } """, no_location=True, )
def test_it_parses_anonymous_subscription_operations(): # assert doesn't raise assert parse( """ subscription { subscriptionField } """, no_location=True, )
def test_it_parses_scalar(): assert_node_equal( parse("scalar Hello", allow_type_system=True), _doc( (0, 12), [ _ast.ScalarTypeDefinition( loc=(0, 12), name=_name((7, 12), "Hello"), directives=[]) ], ), )
def test_it_allows_non_keywords_anywhere_a_name_is_allowed(keyword): fragment_name = keyword if keyword != "on" else "a" assert parse( """ query %(keyword)s { ... %(fragment_name)s ... on %(keyword)s { field } } fragment %(fragment_name)s on Type { %(keyword)s(%(keyword)s: $%(keyword)s) @%(keyword)s(%(keyword)s: %(keyword)s) }""" % dict(keyword=keyword, fragment_name=fragment_name) )
def test_it_processes_nodes_in_the_correct_order(): ast = parse("{ a }", no_location=True) visitor = Tracker() visitor.visit(ast) assert visitor.stack == [ ("enter", "Document"), ("enter", "OperationDefinition"), ("enter", "SelectionSet"), ("enter", "Field"), ("leave", "Field"), ("leave", "SelectionSet"), ("leave", "OperationDefinition"), ("leave", "Document"), ]
def test_it_creates_ast_from_nameless_query_without_variables(): body = """query { node { id } } """ assert_node_equal( parse(body), _ast.Document( loc=(0, 30), definitions=[ _ast.OperationDefinition( loc=(0, 29), operation="query", name=None, variable_definitions=[], directives=[], selection_set=_ast.SelectionSet( loc=(6, 29), selections=[ _ast.Field( loc=(10, 27), alias=None, name=_ast.Name(loc=(10, 14), value="node"), arguments=[], directives=[], selection_set=_ast.SelectionSet( loc=(15, 27), selections=[ _ast.Field( loc=(21, 23), alias=None, name=_ast.Name( loc=(21, 23), value="id" ), arguments=[], directives=[], selection_set=None, ) ], ), ) ], ), ) ], ), )
def test_it_parses_simple_union(): assert_node_equal( parse("union Hello = World", allow_type_system=True), _doc( (0, 19), [ _ast.UnionTypeDefinition( loc=(0, 19), name=_name((6, 11), "Hello"), directives=[], types=[_type((14, 19), "World")], ) ], ), )
def test_it_parses_extension_without_fields(): assert_node_equal( parse("extend type Hello implements Greeting", allow_type_system=True), _doc( (0, 37), [ _ast.ObjectTypeExtension( loc=(0, 37), name=_name((12, 17), "Hello"), interfaces=[_type((29, 37), "Greeting")], fields=[], directives=[], ) ], ), )
def test_it_parses_union_with_two_types(): assert_node_equal( parse("union Hello = Wo | Rld", allow_type_system=True), _doc( (0, 22), [ _ast.UnionTypeDefinition( loc=(0, 22), name=_name((6, 11), "Hello"), directives=[], types=[_type((14, 16), "Wo"), _type((19, 22), "Rld")], ) ], ), )
def test_it_parses_union_with_two_types_and_leading_pipe(): assert_node_equal( parse("union Hello = | Wo | Rld", allow_type_system=True), _doc( (0, 24), [ _ast.UnionTypeDefinition( loc=(0, 24), name=_name((6, 11), "Hello"), directives=[], types=[_type((16, 18), "Wo"), _type((21, 24), "Rld")], ) ], ), )