Example #1
0
def tesst_allows_non_keywords_anywhere_a_name_is_allowed():
    non_keywords = [
        'on',
        'fragment',
        'query',
        'mutation',
        'true',
        'false'
    ]

    query_template = '''
    query {keyword} {
        ... {fragment_name}
        ... on {keyword} { field }
    }
    fragment {fragment_name} on Type {
        {keyword}({keyword}: ${keyword}) @{keyword}({keyword}: {keyword})
    }
    '''

    for keyword in non_keywords:
        fragment_name = keyword
        if keyword == 'on':
            fragment_name = 'a'

        parse(query_template.format(fragment_name=fragment_name, keyword=keyword))
Example #2
0
def test_parse_provides_useful_errors():
    with raises(LanguageError) as excinfo:
        parse("""{""")
    assert (
               u'Syntax Error GraphQL (1:2) Expected Name, found EOF\n'
               u'\n'
               u'1: {\n'
               u'    ^\n'
               u''
           ) == excinfo.value.message

    assert excinfo.value.positions == [1]
    assert excinfo.value.locations == [SourceLocation(line=1, column=2)]

    with raises(LanguageError) as excinfo:
        parse("""{ ...MissingOn }
fragment MissingOn Type
""")
    assert 'Syntax Error GraphQL (2:20) Expected "on", found Name "Type"' in str(excinfo.value)

    with raises(LanguageError) as excinfo:
        parse('{ field: {} }')
    assert 'Syntax Error GraphQL (1:10) Expected Name, found {' in str(excinfo.value)

    with raises(LanguageError) as excinfo:
        parse('notanoperation Foo { field }')
    assert 'Syntax Error GraphQL (1:1) Unexpected Name "notanoperation"' in str(excinfo.value)

    with raises(LanguageError) as excinfo:
        parse('...')
    assert 'Syntax Error GraphQL (1:1) Unexpected ...' in str(excinfo.value)
def test_visits_in_pararell_allows_for_editing_on_leave():
    visited = []
    ast = parse('{ a, b, c { a, b, c } }', no_location=True)

    class TestVisitor1(Visitor):

        def leave(self, node, key, parent, *args):
            if type(node).__name__ == 'Field' and node.name.value == 'b':
                return REMOVE

    class TestVisitor2(Visitor):

        def enter(self, node, key, parent, *args):
            visited.append(
                ['enter', type(node).__name__, getattr(node, 'value', None)])

        def leave(self, node, key, parent, *args):
            visited.append(
                ['leave', type(node).__name__, getattr(node, 'value', None)])

    edited_ast = visit(ast, ParallelVisitor([TestVisitor1(), TestVisitor2()]))

    assert ast == parse('{ a, b, c { a, b, c } }', no_location=True)
    assert edited_ast == parse('{ a,    c { a,    c } }', no_location=True)

    assert visited == [
        ['enter', 'Document', None],
        ['enter', 'OperationDefinition', None],
        ['enter', 'SelectionSet', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'a'],
        ['leave', 'Name', 'a'],
        ['leave', 'Field', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'b'],
        ['leave', 'Name', 'b'],
        ['enter', 'Field', None],
        ['enter', 'Name', 'c'],
        ['leave', 'Name', 'c'],
        ['enter', 'SelectionSet', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'a'],
        ['leave', 'Name', 'a'],
        ['leave', 'Field', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'b'],
        ['leave', 'Name', 'b'],
        ['enter', 'Field', None],
        ['enter', 'Name', 'c'],
        ['leave', 'Name', 'c'],
        ['leave', 'Field', None],
        ['leave', 'SelectionSet', None],
        ['leave', 'Field', None],
        ['leave', 'SelectionSet', None],
        ['leave', 'OperationDefinition', None],
        ['leave', 'Document', None]
    ]
Example #4
0
def test_allows_for_editing_on_enter():
    ast = parse('{ a, b, c { a, b, c } }', no_location=True)

    class TestVisitor(Visitor):
        def enter(self, node, *args):
            if isinstance(node, Field) and node.name.value == 'b':
                return REMOVE
    edited_ast = visit(ast, TestVisitor())

    assert ast == parse('{ a, b, c { a, b, c } }', no_location=True)
    assert edited_ast == parse('{ a,   c { a,   c } }', no_location=True)
Example #5
0
def test_allows_early_exit_while_visiting():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):
        def enter(self, node, *args):
            visited.append(['enter', type(node).__name__, getattr(node, 'value', None)])
            if isinstance(node, Name) and node.value == 'x':
                return BREAK

        def leave(self, node, *args):
            visited.append(['leave', type(node).__name__, getattr(node, 'value', None)])

    visit(ast, TestVisitor())

    assert visited == [
        ['enter', 'Document', None],
        ['enter', 'OperationDefinition', None],
        ['enter', 'SelectionSet', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'a'],
        ['leave', 'Name', 'a'],
        ['leave', 'Field', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'b'],
        ['leave', 'Name', 'b'],
        ['enter', 'SelectionSet', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'x'],
    ]
Example #6
0
def test_allows_skipping_a_subtree():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):
        def enter(self, node, *args):
            visited.append(['enter', type(node).__name__, getattr(node, 'value', None)])
            if isinstance(node, Field) and node.name.value == 'b':
                return False

        def leave(self, node, *args):
            visited.append(['leave', type(node).__name__, getattr(node, 'value', None)])

    visit(ast, TestVisitor())

    assert visited == [
        ['enter', 'Document', None],
        ['enter', 'OperationDefinition', None],
        ['enter', 'SelectionSet', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'a'],
        ['leave', 'Name', 'a'],
        ['leave', 'Field', None],
        ['enter', 'Field', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'c'],
        ['leave', 'Name', 'c'],
        ['leave', 'Field', None],
        ['leave', 'SelectionSet', None],
        ['leave', 'OperationDefinition', None],
        ['leave', 'Document', None],
    ]
Example #7
0
def test_allows_a_named_functions_visitor_api():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):
        def enter_Name(self, node, *args):
            visited.append(['enter', type(node).__name__, getattr(node, 'value', None)])

        def enter_SelectionSet(self, node, *args):
            visited.append(['enter', type(node).__name__, getattr(node, 'value', None)])

        def leave_SelectionSet(self, node, *args):
            visited.append(['leave', type(node).__name__, getattr(node, 'value', None)])

    visit(ast, TestVisitor())

    assert visited == [
        ['enter', 'SelectionSet', None],
        ['enter', 'Name', 'a'],
        ['enter', 'Name', 'b'],
        ['enter', 'SelectionSet', None],
        ['enter', 'Name', 'x'],
        ['leave', 'SelectionSet', None],
        ['enter', 'Name', 'c'],
        ['leave', 'SelectionSet', None],
    ]
Example #8
0
def test_visits_edited_node():
    added_field = Field(loc=None,
                        name=Name(loc=None, value='__typename'),
                        alias=None,
                        arguments=None,
                        directives=None,
                        selection_set=None)
    ast = parse('{ a { x } }')

    class TestVisitor(Visitor):
        def __init__(self):
            self.did_visit_added_field = False

        def enter(self, node, *args):
            if isinstance(node, Field) and node.name.value == 'a':
                selection_set = node.selection_set
                selections = []
                if selection_set:
                    selections = selection_set.selections
                new_selection_set = SelectionSet(loc=None,
                                                 selections=[added_field] +
                                                 selections)
                return Field(loc=None,
                             name=None,
                             alias=None,
                             arguments=None,
                             directives=None,
                             selection_set=new_selection_set)
            if node is added_field:
                self.did_visit_added_field = True

    visitor = TestVisitor()
    visit(ast, visitor)
    assert visitor.did_visit_added_field
def test_nulls_out_error_subtrees():
    doc = '''{
        ok,
        error
    }'''

    class Data(object):

        def ok(self):
            return 'ok'

        def error(self):
            raise Exception('Error getting error')

    doc_ast = parse(doc)

    Type = GraphQLObjectType('Type', {
        'ok': GraphQLField(GraphQLString),
        'error': GraphQLField(GraphQLString),
    })

    result = execute(GraphQLSchema(Type), Data(), doc_ast)
    assert result.data == {'ok': 'ok', 'error': None}
    assert len(result.errors) == 1
    assert result.errors[0].message == 'Error getting error'
Example #10
0
def test_parses_multi_byte_characters():
    result = parse(u'''
        # This comment has a \u0A0A multi-byte character.
        { field(arg: "Has a \u0A0A multi-byte character.") }
    ''',
                   no_location=True,
                   no_source=True)
    assert result == ast.Document(definitions=[
        ast.OperationDefinition(
            operation='query',
            name=None,
            variable_definitions=None,
            directives=[],
            selection_set=ast.SelectionSet(selections=[
                ast.Field(
                    alias=None,
                    name=ast.Name(value=u'field'),
                    arguments=[
                        ast.Argument(
                            name=ast.
                            Name(value=u'arg'),
                            value=ast
                            .StringValue(
                                value=u'Has a \u0a0a multi-byte character.'))
                    ],
                    directives=[],
                    selection_set=None)
            ]))
    ])
Example #11
0
def test_gets_execution_info_in_resolver():
    encountered_schema = [None]
    encountered_root_value = [None]

    def resolve_type(obj, info):
        encountered_schema[0] = info.schema
        encountered_root_value[0] = info.root_value
        return PersonType2

    NamedType2 = GraphQLInterfaceType(
        name='Named',
        fields={'name': GraphQLField(GraphQLString)},
        resolve_type=resolve_type)

    PersonType2 = GraphQLObjectType(name='Person',
                                    interfaces=[NamedType2],
                                    fields={
                                        'name':
                                        GraphQLField(GraphQLString),
                                        'friends':
                                        GraphQLField(GraphQLList(NamedType2))
                                    })

    schema2 = GraphQLSchema(query=PersonType2)
    john2 = Person('John', [], [liz])
    ast = parse('''{ name, friends { name } }''')

    result = execute(schema2, john2, ast)
    assert result.data == {'name': 'John', 'friends': [{'name': 'Liz'}]}

    assert encountered_schema[0] == schema2
    assert encountered_root_value[0] == john2
Example #12
0
def test_executes_using_interface_types():
    # NOTE: This is an *invalid* query, but it should be an *executable* query.
    ast = parse('''
      {
        __typename
        name
        friends {
          __typename
          name
          barks
          meows
        }
      }
    ''')
    result = execute(schema, john, ast)
    assert not result.errors
    assert result.data == {
        '__typename':
        'Person',
        'name':
        'John',
        'friends': [{
            '__typename': 'Person',
            'name': 'Liz'
        }, {
            '__typename': 'Dog',
            'name': 'Odie',
            'barks': True
        }]
    }
Example #13
0
def test_executes_using_union_types():
    # NOTE: This is an *invalid* query, but it should be an *executable* query.
    ast = parse('''
        {
            __typename
            name
            pets {
                __typename
                name
                barks
                meows
            }
        }
    ''')
    result = execute(schema, john, ast)
    assert not result.errors
    assert result.data == {
        '__typename':
        'Person',
        'name':
        'John',
        'pets': [{
            '__typename': 'Cat',
            'name': 'Garfield',
            'meows': False
        }, {
            '__typename': 'Dog',
            'name': 'Odie',
            'barks': True
        }]
    }
Example #14
0
def test_fails_when_an_is_type_of_check_is_not_met():
    class Special(object):
        def __init__(self, value):
            self.value = value

    class NotSpecial(object):
        def __init__(self, value):
            self.value = value

    SpecialType = GraphQLObjectType(
        "SpecialType",
        fields={"value": GraphQLField(GraphQLString)},
        is_type_of=lambda obj, info: isinstance(obj, Special),
    )

    schema = GraphQLSchema(
        GraphQLObjectType(
            name="Query",
            fields={"specials": GraphQLField(GraphQLList(SpecialType), resolver=lambda root, *_: root["specials"])},
        )
    )

    query = parse("{ specials { value } }")
    value = {"specials": [Special("foo"), NotSpecial("bar")]}

    result = execute(schema, value, query)

    assert result.data == {"specials": [{"value": "foo"}, None]}

    assert 'Expected value of type "SpecialType" but got NotSpecial.' in str(result.errors)
def test_visits_in_pararell_allows_early_exit_while_visiting():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):

        def enter(self, node, key, parent, *args):
            visited.append(
                ['enter', type(node).__name__, getattr(node, 'value', None)])

        def leave(self, node, key, parent, *args):
            visited.append(
                ['leave', type(node).__name__, getattr(node, 'value', None)])
            if type(node).__name__ == 'Name' and node.value == 'x':
                return BREAK

    visit(ast, ParallelVisitor([TestVisitor()]))
    assert visited == [
        ['enter', 'Document', None],
        ['enter', 'OperationDefinition', None],
        ['enter', 'SelectionSet', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'a'],
        ['leave', 'Name', 'a'],
        ['leave', 'Field', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'b'],
        ['leave', 'Name', 'b'],
        ['enter', 'SelectionSet', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'x'],
        ['leave', 'Name', 'x']
    ]
Example #16
0
def test_fails_when_an_is_type_of_check_is_not_met():
    class Special(object):
        def __init__(self, value):
            self.value = value

    class NotSpecial(object):
        def __init__(self, value):
            self.value = value

    SpecialType = GraphQLObjectType(
        'SpecialType',
        fields={
            'value': GraphQLField(GraphQLString),
        },
        is_type_of=lambda obj, info: isinstance(obj, Special))

    schema = GraphQLSchema(
        GraphQLObjectType(name='Query',
                          fields={
                              'specials':
                              GraphQLField(
                                  GraphQLList(SpecialType),
                                  resolver=lambda root, *_: root['specials'])
                          }))

    query = parse('{ specials { value } }')
    value = {'specials': [Special('foo'), NotSpecial('bar')]}

    result = execute(schema, value, query)

    assert result.data == {'specials': [{'value': 'foo'}, None]}

    assert 'Expected value of type "SpecialType" but got NotSpecial.' in str(
        result.errors)
Example #17
0
def test_correctly_threads_arguments():
    doc = """
        query Example {
            b(numArg: 123, stringArg: "foo")
        }
    """

    def resolver(_, args, *_args):
        assert args["numArg"] == 123
        assert args["stringArg"] == "foo"
        resolver.got_here = True

    resolver.got_here = False

    doc_ast = parse(doc)

    Type = GraphQLObjectType(
        "Type",
        {
            "b": GraphQLField(
                GraphQLString,
                args={"numArg": GraphQLArgument(GraphQLInt), "stringArg": GraphQLArgument(GraphQLString)},
                resolver=resolver,
            )
        },
    )

    result = execute(GraphQLSchema(Type), None, doc_ast, "Example", {})
    assert not result.errors
    assert resolver.got_here
Example #18
0
def test_executes_union_types_with_inline_fragment():
    # This is the valid version of the query in the above test.
    ast = parse('''
      {
        __typename
        name
        pets {
          __typename
          ... on Dog {
            name
            barks
          }
          ... on Cat {
            name
            meows
          }
        }
      }
    ''')
    result = execute(schema, john, ast)
    assert not result.errors
    assert result.data == {
        '__typename': 'Person',
        'name': 'John',
        'pets': [
            {'__typename': 'Cat', 'name': 'Garfield', 'meows': False},
            {'__typename': 'Dog', 'name': 'Odie', 'barks': True}
        ]
    }
Example #19
0
def test_evaluates_mutations_serially():
    doc = '''mutation M {
      first: immediatelyChangeTheNumber(newNumber: 1) {
        theNumber
      },
      second: promiseToChangeTheNumber(newNumber: 2) {
        theNumber
      },
      third: immediatelyChangeTheNumber(newNumber: 3) {
        theNumber
      }
      fourth: promiseToChangeTheNumber(newNumber: 4) {
        theNumber
      },
      fifth: immediatelyChangeTheNumber(newNumber: 5) {
        theNumber
      }
    }'''
    ast = parse(doc)
    result = execute(schema, Root(6), ast, 'M')
    assert not result.errors
    assert result.data == \
        {
            'first': {'theNumber': 1},
            'second': {'theNumber': 2},
            'third': {'theNumber': 3},
            'fourth': {'theNumber': 4},
            'fifth': {'theNumber': 5},
        }
Example #20
0
def test_executes_interface_types_with_inline_fragment():
    # This is the valid version of the query in the above test.
    ast = parse('''
      {
        __typename
        name
        friends {
          __typename
          name
          ... on Dog {
            barks
          }
          ... on Cat {
            meows
          }
        }
      }
    ''')
    result = execute(schema, john, ast)
    assert not result.errors
    assert result.data == {
        '__typename': 'Person',
        'name': 'John',
        'friends': [
            {'__typename': 'Person', 'name': 'Liz'},
            {'__typename': 'Dog', 'name': 'Odie', 'barks': True}
        ]
    }
Example #21
0
def test_when_argument_provided_cannot_be_coerced():
    ast = parse('''{
        fieldWithDefaultArgumentValue(input: WRONG_TYPE)
    }''')
    result = execute(schema, None, ast)
    assert not result.errors
    assert result.data == {'fieldWithDefaultArgumentValue': '"Hello World"'}
Example #22
0
def test_allows_early_exit_while_visiting():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):
        def enter(self, node, *args):
            visited.append(['enter', type(node).__name__, getattr(node, 'value', None)])
            if isinstance(node, Name) and node.value == 'x':
                return BREAK

        def leave(self, node, *args):
            visited.append(['leave', type(node).__name__, getattr(node, 'value', None)])

    visit(ast, TestVisitor())

    assert visited == [
        [ 'enter', 'Document', None ],
        [ 'enter', 'OperationDefinition', None ],
        [ 'enter', 'SelectionSet', None ],
        [ 'enter', 'Field', None ],
        [ 'enter', 'Name', 'a' ],
        [ 'leave', 'Name', 'a' ],
        [ 'leave', 'Field', None ],
        [ 'enter', 'Field', None ],
        [ 'enter', 'Name', 'b' ],
        [ 'leave', 'Name', 'b' ],
        [ 'enter', 'SelectionSet', None ],
        [ 'enter', 'Field', None ],
        [ 'enter', 'Name', 'x' ],
        ]
Example #23
0
def test_allows_skipping_a_subtree():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):
        def enter(self, node, *args):
            visited.append(['enter', type(node).__name__, getattr(node, 'value', None)])
            if isinstance(node, Field) and node.name.value == 'b':
                return False

        def leave(self, node, *args):
            visited.append(['leave', type(node).__name__, getattr(node, 'value', None)])

    visit(ast, TestVisitor())

    assert visited == [
        [ 'enter', 'Document', None ],
        [ 'enter', 'OperationDefinition', None ],
        [ 'enter', 'SelectionSet', None ],
        [ 'enter', 'Field', None ],
        [ 'enter', 'Name', 'a' ],
        [ 'leave', 'Name', 'a' ],
        [ 'leave', 'Field', None ],
        [ 'enter', 'Field', None ],
        [ 'enter', 'Field', None ],
        [ 'enter', 'Name', 'c' ],
        [ 'leave', 'Name', 'c' ],
        [ 'leave', 'Field', None ],
        [ 'leave', 'SelectionSet', None ],
        [ 'leave', 'OperationDefinition', None ],
        [ 'leave', 'Document', None ],
    ]
Example #24
0
def test_executes_union_types_with_inline_fragment():
    # This is the valid version of the query in the above test.
    ast = parse('''
      {
        __typename
        name
        pets {
          __typename
          ... on Dog {
            name
            barks
          }
          ... on Cat {
            name
            meows
          }
        }
      }
    ''')
    result = execute(schema, john, ast)
    assert not result.errors
    assert result.data == {
        '__typename': 'Person',
        'name': 'John',
        'pets': [
            {'__typename': 'Cat', 'name': 'Garfield', 'meows': False},
            {'__typename': 'Dog', 'name': 'Odie', 'barks': True}
        ]
    }
Example #25
0
def test_executes_interface_types_with_inline_fragment():
    # This is the valid version of the query in the above test.
    ast = parse('''
      {
        __typename
        name
        friends {
          __typename
          name
          ... on Dog {
            barks
          }
          ... on Cat {
            meows
          }
        }
      }
    ''')
    result = execute(schema, john, ast)
    assert not result.errors
    assert result.data == {
        '__typename': 'Person',
        'name': 'John',
        'friends': [
            {'__typename': 'Person', 'name': 'Liz'},
            {'__typename': 'Dog', 'name': 'Odie', 'barks': True}
        ]
    }
Example #26
0
def test_nulls_a_complex_tree_of_nullable_fields_that_returns_null():
    doc = '''
      query Q {
        nest {
          sync
          #promise
          nest {
            sync
            #promise
          }
          #promiseNest {
          #  sync
          #  promise
          #}
        }
        #promiseNest {
        #  sync
        #  promise
        #  nest {
        #    sync
        #    promise
        #  }
        #  promiseNest {
        #    sync
        #    promise
        #  }
        #}
      }
    '''
    ast = parse(doc)
    result = execute(schema, NullingData(), ast, 'Q', {})
    assert not result.errors
    assert result.data == {'nest': {'sync': None, 'nest': {'sync': None}}}
Example #27
0
def test_correctly_threads_arguments():
    doc = '''
        query Example {
            b(numArg: 123, stringArg: "foo")
        }
    '''

    def resolver(_, args, *_args):
        assert args['numArg'] == 123
        assert args['stringArg'] == 'foo'
        resolver.got_here = True

    resolver.got_here = False

    doc_ast = parse(doc)

    Type = GraphQLObjectType('Type', {
        'b': GraphQLField(
            GraphQLString,
            args={
                'numArg': GraphQLArgument(GraphQLInt),
                'stringArg': GraphQLArgument(GraphQLString),
            },
            resolver=resolver),
    })

    result = execute(GraphQLSchema(Type), None, doc_ast, 'Example', {})
    assert not result.errors
    assert resolver.got_here
def test_supports_the_type_root_field():
    TestType = GraphQLObjectType("TestType", {"testField": GraphQLField(GraphQLString)})
    schema = GraphQLSchema(TestType)
    request = '{ __type(name: "TestType") { name } }'
    result = execute(schema, object(), parse(request))
    assert not result.errors
    assert result.data == {"__type": {"name": "TestType"}}
Example #29
0
def test_visits_edited_node():
    added_field = Field(loc=None,
                        name=Name(loc=None, value='__typename'),
                        alias=None,
                        arguments=None,
                        directives=None,
                        selection_set=None)
    ast = parse('{ a { x } }')

    class TestVisitor(Visitor):
        def __init__(self):
            self.did_visit_added_field = False

        def enter(self, node, *args):
            if isinstance(node, Field) and node.name.value == 'a':
                selection_set = node.selection_set
                selections = []
                if selection_set:
                    selections = selection_set.selections
                new_selection_set = SelectionSet(loc=None, selections=[added_field] + selections)
                return Field(loc=None,
                             name=None,
                             alias=None,
                             arguments=None,
                             directives=None,
                             selection_set=new_selection_set)
            if node is added_field:
                self.did_visit_added_field = True

    visitor = TestVisitor()
    visit(ast, visitor)
    assert visitor.did_visit_added_field
Example #30
0
def test_evaluates_mutations_serially():
    doc = '''mutation M {
      first: immediatelyChangeTheNumber(newNumber: 1) {
        theNumber
      },
      second: promiseToChangeTheNumber(newNumber: 2) {
        theNumber
      },
      third: immediatelyChangeTheNumber(newNumber: 3) {
        theNumber
      }
      fourth: promiseToChangeTheNumber(newNumber: 4) {
        theNumber
      },
      fifth: immediatelyChangeTheNumber(newNumber: 5) {
        theNumber
      }
    }'''
    ast = parse(doc)
    result = execute(schema, Root(6), ast, 'M')
    assert not result.errors
    assert result.data == \
        {
            'first': {'theNumber': 1},
            'second': {'theNumber': 2},
            'third': {'theNumber': 3},
            'fourth': {'theNumber': 4},
            'fifth': {'theNumber': 5},
        }
Example #31
0
def test_allows_a_named_functions_visitor_api():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):
        def enter_Name(self, node, *args):
            visited.append(['enter', type(node).__name__, getattr(node, 'value', None)])

        def enter_SelectionSet(self, node, *args):
            visited.append(['enter', type(node).__name__, getattr(node, 'value', None)])

        def leave_SelectionSet(self, node, *args):
            visited.append(['leave', type(node).__name__, getattr(node, 'value', None)])

    visit(ast, TestVisitor())

    assert visited == [
        [ 'enter', 'SelectionSet', None ],
        [ 'enter', 'Name', 'a' ],
        [ 'enter', 'Name', 'b' ],
        [ 'enter', 'SelectionSet', None ],
        [ 'enter', 'Name', 'x' ],
        [ 'leave', 'SelectionSet', None ],
        [ 'enter', 'Name', 'c' ],
        [ 'leave', 'SelectionSet', None ],
        ]
Example #32
0
def test_when_nullable_variable_provided():
    ast = parse('''query optionalVariable($optional: String) {
        fieldWithDefaultArgumentValue(input: $optional)
    }''')
    result = execute(schema, None, ast)
    assert not result.errors
    assert result.data == {'fieldWithDefaultArgumentValue': '"Hello World"'}
Example #33
0
def test_when_nullable_variable_provided():
    ast = parse('''query optionalVariable($optional: String) {
        fieldWithDefaultArgumentValue(input: $optional)
    }''')
    result = execute(schema, None, ast)
    assert not result.errors
    assert result.data == {'fieldWithDefaultArgumentValue': '"Hello World"'}
Example #34
0
def test_when_argument_provided_cannot_be_coerced():
    ast = parse('''{
        fieldWithDefaultArgumentValue(input: WRONG_TYPE)
    }''')
    result = execute(schema, None, ast)
    assert not result.errors
    assert result.data == {'fieldWithDefaultArgumentValue': '"Hello World"'}
Example #35
0
def test_does_not_include_illegal_fields_in_output():
    doc = "mutation M { thisIsIllegalDontIncludeMe }"
    ast = parse(doc)
    Q = GraphQLObjectType("Q", {"a": GraphQLField(GraphQLString)})
    M = GraphQLObjectType("M", {"c": GraphQLField(GraphQLString)})
    result = execute(GraphQLSchema(Q, M), None, ast)
    assert not result.errors
    assert result.data == {}
Example #36
0
def test_supports_the_type_root_field():
    TestType = GraphQLObjectType('TestType',
                                 {'testField': GraphQLField(GraphQLString)})
    schema = GraphQLSchema(TestType)
    request = '{ __type(name: "TestType") { name } }'
    result = execute(schema, object(), parse(request))
    assert not result.errors
    assert result.data == {'__type': {'name': 'TestType'}}
Example #37
0
def test_does_not_include_illegal_fields_in_output():
    doc = 'mutation M { thisIsIllegalDontIncludeMe }'
    ast = parse(doc)
    Q = GraphQLObjectType('Q', {'a': GraphQLField(GraphQLString)})
    M = GraphQLObjectType('M', {'c': GraphQLField(GraphQLString)})
    result = execute(GraphQLSchema(Q, M), None, ast)
    assert not result.errors
    assert result.data == {}
Example #38
0
def expect_invalid(schema, rules, query, expected_errors, sort_list=True):
    errors = validate(schema, parse(query), rules)
    assert errors, "Should not validate"
    if sort_list:
        assert sort_lists(list(map(format_error, errors))) == sort_lists(expected_errors)

    else:
        assert list(map(format_error, errors)) == expected_errors
Example #39
0
def test_parse_creates_ast():
    source = Source("""{
  node(id: 4) {
    id,
    name
  }
}
""")
    result = parse(source)

    assert result == \
           ast.Document(
               loc={'start': 0, 'end': 41, 'source': source},
               definitions=
               [ast.OperationDefinition(
                   loc={'start': 0, 'end': 40, 'source': source},
                   operation='query',
                   name=None,
                   variable_definitions=None,
                   directives=[],
                   selection_set=ast.SelectionSet(
                       loc={'start': 0, 'end': 40, 'source': source},
                       selections=
                       [ast.Field(
                           loc={'start': 4, 'end': 38, 'source': source},
                           alias=None,
                           name=ast.Name(
                               loc={'start': 4, 'end': 8, 'source': source},
                               value='node'),
                           arguments=[ast.Argument(
                               name=ast.Name(loc={'start': 9, 'end': 11, 'source': source},
                                             value='id'),
                               value=ast.IntValue(
                                   loc={'start': 13, 'end': 14, 'source': source},
                                   value='4'),
                               loc={'start': 9, 'end': 14, 'source': source})],
                           directives=[],
                           selection_set=ast.SelectionSet(
                               loc={'start': 16, 'end': 38, 'source': source},
                               selections=
                               [ast.Field(
                                   loc={'start': 22, 'end': 24, 'source': source},
                                   alias=None,
                                   name=ast.Name(
                                       loc={'start': 22, 'end': 24, 'source': source},
                                       value='id'),
                                   arguments=[],
                                   directives=[],
                                   selection_set=None),
                                ast.Field(
                                    loc={'start': 30, 'end': 34, 'source': source},
                                    alias=None,
                                    name=ast.Name(
                                        loc={'start': 30, 'end': 34, 'source': source},
                                        value='name'),
                                    arguments=[],
                                    directives=[],
                                    selection_set=None)]))]))])
Example #40
0
def test_parse_creates_ast():
    source = Source("""{
  node(id: 4) {
    id,
    name
  }
}
""")
    result = parse(source)

    assert result == \
           ast.Document(
               loc=Loc(0, 41, source),
               definitions=
               [ast.OperationDefinition(
                   loc=Loc(0, 40, source),
                   operation='query',
                   name=None,
                   variable_definitions=None,
                   directives=[],
                   selection_set=ast.SelectionSet(
                       loc=Loc(0, 40, source),
                       selections=
                       [ast.Field(
                           loc=Loc(4, 38, source),
                           alias=None,
                           name=ast.Name(
                               loc=Loc(4, 8, source),
                               value='node'),
                           arguments=[ast.Argument(
                               name=ast.Name(loc=Loc(9, 11, source),
                                             value='id'),
                               value=ast.IntValue(
                                   loc=Loc(13, 14, source),
                                   value='4'),
                               loc=Loc(9, 14, source))],
                           directives=[],
                           selection_set=ast.SelectionSet(
                               loc=Loc(16, 38, source),
                               selections=
                               [ast.Field(
                                   loc=Loc(22, 24, source),
                                   alias=None,
                                   name=ast.Name(
                                       loc=Loc(22, 24, source),
                                       value='id'),
                                   arguments=[],
                                   directives=[],
                                   selection_set=None),
                                   ast.Field(
                                       loc=Loc(30, 34, source),
                                       alias=None,
                                       name=ast.Name(
                                           loc=Loc(30, 34, source),
                                           value='name'),
                                       arguments=[],
                                       directives=[],
                                       selection_set=None)]))]))])
Example #41
0
def test_parse_creates_ast():
    source = Source("""{
  node(id: 4) {
    id,
    name
  }
}
""")
    result = parse(source)

    assert result == \
           ast.Document(
               loc=Loc(start=0, end=41, source=source),
               definitions=
               [ast.OperationDefinition(
                   loc=Loc(start=0, end=40, source=source),
                   operation='query',
                   name=None,
                   variable_definitions=None,
                   directives=[],
                   selection_set=ast.SelectionSet(
                       loc=Loc(start=0, end=40, source=source),
                       selections=
                       [ast.Field(
                           loc=Loc(start=4, end=38, source=source),
                           alias=None,
                           name=ast.Name(
                               loc=Loc(start=4, end=8, source=source),
                               value='node'),
                           arguments=[ast.Argument(
                               name=ast.Name(loc=Loc(start=9, end=11, source=source),
                                             value='id'),
                               value=ast.IntValue(
                                   loc=Loc(start=13, end=14, source=source),
                                   value='4'),
                               loc=Loc(start=9, end=14, source=source))],
                           directives=[],
                           selection_set=ast.SelectionSet(
                               loc=Loc(start=16, end=38, source=source),
                               selections=
                               [ast.Field(
                                   loc=Loc(start=22, end=24, source=source),
                                   alias=None,
                                   name=ast.Name(
                                       loc=Loc(start=22, end=24, source=source),
                                       value='id'),
                                   arguments=[],
                                   directives=[],
                                   selection_set=None),
                                   ast.Field(
                                       loc=Loc(start=30, end=34, source=source),
                                       alias=None,
                                       name=ast.Name(
                                           loc=Loc(start=30, end=34, source=source),
                                           value='name'),
                                       arguments=[],
                                       directives=[],
                                       selection_set=None)]))]))])
Example #42
0
def test_parse_creates_ast():
    source = Source("""{
  node(id: 4) {
    id,
    name
  }
}
""")
    result = parse(source)

    assert result == \
           ast.Document(
               loc=Loc(start=0, end=41, source=source),
               definitions=
               [ast.OperationDefinition(
                   loc=Loc(start=0, end=40, source=source),
                   operation='query',
                   name=None,
                   variable_definitions=None,
                   directives=[],
                   selection_set=ast.SelectionSet(
                       loc=Loc(start=0, end=40, source=source),
                       selections=
                       [ast.Field(
                           loc=Loc(start=4, end=38, source=source),
                           alias=None,
                           name=ast.Name(
                               loc=Loc(start=4, end=8, source=source),
                               value='node'),
                           arguments=[ast.Argument(
                               name=ast.Name(loc=Loc(start=9, end=11, source=source),
                                             value='id'),
                               value=ast.IntValue(
                                   loc=Loc(start=13, end=14, source=source),
                                   value='4'),
                               loc=Loc(start=9, end=14, source=source))],
                           directives=[],
                           selection_set=ast.SelectionSet(
                               loc=Loc(start=16, end=38, source=source),
                               selections=
                               [ast.Field(
                                   loc=Loc(start=22, end=24, source=source),
                                   alias=None,
                                   name=ast.Name(
                                       loc=Loc(start=22, end=24, source=source),
                                       value='id'),
                                   arguments=[],
                                   directives=[],
                                   selection_set=None),
                                   ast.Field(
                                       loc=Loc(start=30, end=34, source=source),
                                       alias=None,
                                       name=ast.Name(
                                           loc=Loc(start=30, end=34, source=source),
                                           value='name'),
                                       arguments=[],
                                       directives=[],
                                       selection_set=None)]))]))])
Example #43
0
def test_parse_creates_ast():
    source = Source("""{
  node(id: 4) {
    id,
    name
  }
}
""")
    result = parse(source)

    assert result == \
           ast.Document(
               loc={'start': 0, 'end': 41, 'source': source},
               definitions=
               [ast.OperationDefinition(
                   loc={'start': 0, 'end': 40, 'source': source},
                   operation='query',
                   name=None,
                   variable_definitions=None,
                   directives=[],
                   selection_set=ast.SelectionSet(
                       loc={'start': 0, 'end': 40, 'source': source},
                       selections=
                       [ast.Field(
                           loc={'start': 4, 'end': 38, 'source': source},
                           alias=None,
                           name=ast.Name(
                               loc={'start': 4, 'end': 8, 'source': source},
                               value='node'),
                           arguments=[ast.Argument(
                               name=ast.Name(loc={'start': 9, 'end': 11, 'source': source},
                                             value='id'),
                               value=ast.IntValue(
                                   loc={'start': 13, 'end': 14, 'source': source},
                                   value='4'),
                               loc={'start': 9, 'end': 14, 'source': source})],
                           directives=[],
                           selection_set=ast.SelectionSet(
                               loc={'start': 16, 'end': 38, 'source': source},
                               selections=
                               [ast.Field(
                                   loc={'start': 22, 'end': 24, 'source': source},
                                   alias=None,
                                   name=ast.Name(
                                       loc={'start': 22, 'end': 24, 'source': source},
                                       value='id'),
                                   arguments=[],
                                   directives=[],
                                   selection_set=None),
                                ast.Field(
                                    loc={'start': 30, 'end': 34, 'source': source},
                                    alias=None,
                                    name=ast.Name(
                                        loc={'start': 30, 'end': 34, 'source': source},
                                        value='name'),
                                    arguments=[],
                                    directives=[],
                                    selection_set=None)]))]))])
def test_visits_in_pararell_allows_early_exit_from_different_points():
    visited = []
    ast = parse('{ a { y }, b { x } }')

    class TestVisitor(Visitor):

        def __init__(self, name):
            self.name = name

        def enter(self, node, key, parent, *args):
            visited.append(["break-{}".format(self.name), 'enter',
                            type(node).__name__, getattr(node, 'value', None)])

        def leave(self, node, key, parent, *args):
            visited.append(["break-{}".format(self.name), 'leave',
                            type(node).__name__, getattr(node, 'value', None)])
            if type(node).__name__ == 'Field' and node.name.value == self.name:
                return BREAK

    visit(ast, ParallelVisitor([TestVisitor('a'), TestVisitor('b')]))
    assert visited == [
        ['break-a', 'enter', 'Document', None],
        ['break-b', 'enter', 'Document', None],
        ['break-a', 'enter', 'OperationDefinition', None],
        ['break-b', 'enter', 'OperationDefinition', None],
        ['break-a', 'enter', 'SelectionSet', None],
        ['break-b', 'enter', 'SelectionSet', None],
        ['break-a', 'enter', 'Field', None],
        ['break-b', 'enter', 'Field', None],
        ['break-a', 'enter', 'Name', 'a'],
        ['break-b', 'enter', 'Name', 'a'],
        ['break-a', 'leave', 'Name', 'a'],
        ['break-b', 'leave', 'Name', 'a'],
        ['break-a', 'enter', 'SelectionSet', None],
        ['break-b', 'enter', 'SelectionSet', None],
        ['break-a', 'enter', 'Field', None],
        ['break-b', 'enter', 'Field', None],
        ['break-a', 'enter', 'Name', 'y'],
        ['break-b', 'enter', 'Name', 'y'],
        ['break-a', 'leave', 'Name', 'y'],
        ['break-b', 'leave', 'Name', 'y'],
        ['break-a', 'leave', 'Field', None],
        ['break-b', 'leave', 'Field', None],
        ['break-a', 'leave', 'SelectionSet', None],
        ['break-b', 'leave', 'SelectionSet', None],
        ['break-a', 'leave', 'Field', None],
        ['break-b', 'leave', 'Field', None],
        ['break-b', 'enter', 'Field', None],
        ['break-b', 'enter', 'Name', 'b'],
        ['break-b', 'leave', 'Name', 'b'],
        ['break-b', 'enter', 'SelectionSet', None],
        ['break-b', 'enter', 'Field', None],
        ['break-b', 'enter', 'Name', 'x'],
        ['break-b', 'leave', 'Name', 'x'],
        ['break-b', 'leave', 'Field', None],
        ['break-b', 'leave', 'SelectionSet', None],
        ['break-b', 'leave', 'Field', None]
    ]
def test_supports_the_type_root_field():
    TestType = GraphQLObjectType('TestType', {
        'testField': GraphQLField(GraphQLString)
    })
    schema = GraphQLSchema(TestType)
    request = '{ __type(name: "TestType") { name } }'
    result = execute(schema, object(), parse(request))
    assert not result.errors
    assert result.data == {'__type': {'name': 'TestType'}}
Example #46
0
def test_can_introspect_on_union_and_intersection_types():
    ast = parse('''
    {
        Named: __type(name: "Named") {
            kind
            name
            fields { name }
            interfaces { name }
            possibleTypes { name }
            enumValues { name }
            inputFields { name }
        }
        Pet: __type(name: "Pet") {
            kind
            name
            fields { name }
            interfaces { name }
            possibleTypes { name }
            enumValues { name }
            inputFields { name }
        }
    }''')

    result = execute(schema, None, ast)
    assert result.data == {
        'Named': {
            'enumValues': None,
            'name': 'Named',
            'kind': 'INTERFACE',
            'interfaces': None,
            'fields': [{
                'name': 'name'
            }],
            'possibleTypes': [{
                'name': 'Dog'
            }, {
                'name': 'Cat'
            }, {
                'name': 'Person'
            }],
            'inputFields': None
        },
        'Pet': {
            'enumValues': None,
            'name': 'Pet',
            'kind': 'UNION',
            'interfaces': None,
            'fields': None,
            'possibleTypes': [{
                'name': 'Dog'
            }, {
                'name': 'Cat'
            }],
            'inputFields': None
        }
    }
Example #47
0
def test_nulls_the_top_level_if_sync_non_nullable_field_throws():
    doc = '''
        query Q { nonNullSync }
    '''
    ast = parse(doc)
    result = execute(schema, ThrowingData(), ast)
    assert result.data is None
    assert len(result.errors) == 1
    # TODO: check error location
    assert result.errors[0]['message'] == non_null_sync_error.message
Example #48
0
def test_nulls_a_nullable_field_that_returns_null():
    doc = '''
        query Q {
            sync
        }
    '''
    ast = parse(doc)
    result = execute(schema, NullingData(), ast, 'Q', {})
    assert not result.errors
    assert result.data == {'sync': None}
Example #49
0
def test_does_not_allow_non_null_lists_to_be_null():
    doc = '''
        query q($input:[String]!) {
          nnList(input: $input)
        }
    '''
    ast = parse(doc)
    with raises(GraphQLError) as excinfo:
        execute(schema, None, ast, None, {'input': None})
    e = excinfo.value
Example #50
0
def test_allows_non_null_lists_to_contain_null():
    doc = '''
        query q($input:[String]!) {
          nnList(input: $input)
        }
    '''
    ast = parse(doc)
    result = execute(schema, None, ast, None, {'input': ['A', None, 'B']})
    assert not result.errors
    assert result.data == {'nnList': '["A", null, "B"]'}
Example #51
0
def test_allows_lists_of_non_nulls_to_be_null():
    doc = '''
        query q($input:[String!]) {
          listNN(input: $input)
        }
    '''
    ast = parse(doc)
    result = execute(schema, None, ast, None, {'input': None})
    assert not result.errors
    assert result.data == {'listNN': 'null'}
Example #52
0
def test_inline_does_not_use_incorrect_value():
    doc = '''
    {
        fieldWithObjectInput(input: ["foo", "bar", "baz"])
    }
    '''
    ast = parse(doc)
    result = execute(schema, None, ast)
    assert not result.errors
    assert json.loads(result.data['fieldWithObjectInput']) is None
Example #53
0
def test_does_not_allow_non_null_lists_of_non_nulls_to_contain_null():
    doc = '''
        query q($input:[String!]!) {
          nnListNN(input: $input)
        }
    '''
    ast = parse(doc)
    with raises(GraphQLError) as excinfo:
        execute(schema, None, ast, None, {'input': ['A', None, 'B']})
    e = excinfo.value
Example #54
0
def test_does_not_allow_unknown_types_to_be_used_as_values():
    doc = '''
        query q($input: UnknownType!) {
          fieldWithObjectInput(input: $input)
        }
    '''
    ast = parse(doc)
    with raises(GraphQLError) as excinfo:
        execute(schema, None, ast)
    e = excinfo.value
Example #55
0
def test_does_not_allow_unknown_types_to_be_used_as_values():
    doc = '''
        query q($input: UnknownType!) {
          fieldWithObjectInput(input: $input)
        }
    '''
    ast = parse(doc)
    with raises(GraphQLError) as excinfo:
        execute(schema, None, ast)
    e = excinfo.value
Example #56
0
def test_does_not_allow_non_null_lists_of_non_nulls_to_contain_null():
    doc = '''
        query q($input:[String!]!) {
          nnListNN(input: $input)
        }
    '''
    ast = parse(doc)
    with raises(GraphQLError) as excinfo:
        execute(schema, None, ast, None, {'input': ['A', None, 'B']})
    e = excinfo.value
Example #57
0
def test_allows_non_null_lists_of_non_nulls_to_contain_values():
    doc = '''
        query q($input:[String!]!) {
          nnListNN(input: $input)
        }
    '''
    ast = parse(doc)
    result = execute(schema, None, ast, None, {'input': ['A']})
    assert not result.errors
    assert result.data == {'nnListNN': '["A"]'}
Example #58
0
def test_allows_non_null_lists_of_non_nulls_to_contain_values():
    doc = '''
        query q($input:[String!]!) {
          nnListNN(input: $input)
        }
    '''
    ast = parse(doc)
    result = execute(schema, None, ast, None, {'input': ['A']})
    assert not result.errors
    assert result.data == {'nnListNN': '["A"]'}
Example #59
0
def test_inline_does_not_use_incorrect_value():
    doc = '''
    {
        fieldWithObjectInput(input: ["foo", "bar", "baz"])
    }
    '''
    ast = parse(doc)
    result = execute(schema, None, ast)
    assert not result.errors
    assert json.loads(result.data['fieldWithObjectInput']) is None