def _compile_property_ast(schema, current_schema_type, ast, location, context,
                          unique_local_directives):
    """Process property directives at this AST node, updating the query context as appropriate.

    Args:
        schema: GraphQL schema object, obtained from the graphql library
        current_schema_type: GraphQLType, the schema type at the current location
        ast: GraphQL AST node, obtained from the graphql library. Only for function signature
             uniformity at the moment -- it is currently not used.
        location: Location object representing the current location in the query
        context: dict, various per-compilation data (e.g. declared tags, whether the current block
                 is optional, etc.). May be mutated in-place in this function!
        unique_local_directives: dict, directive name string -> directive object, containing
                                 unique directives present on the current AST node *only*
    """
    validate_property_directives(unique_local_directives)

    # step P-2: process property-only directives
    tag_directive = unique_local_directives.get('tag', None)
    if tag_directive:
        if is_in_fold_scope(context):
            raise GraphQLCompilationError(
                u'Tagging values within a @fold vertex field is '
                u'not allowed! Location: {}'.format(location))

        # Schema validation has ensured that the fields below exist.
        tag_name = tag_directive.arguments[0].value.value
        if tag_name in context['tags']:
            raise GraphQLCompilationError(
                u'Cannot reuse tag name: {}'.format(tag_name))
        validate_safe_string(tag_name)
        context['tags'][tag_name] = {
            'location': location,
            'optional': is_in_optional_scope(context),
            'type': strip_non_null_from_type(current_schema_type),
        }

    output_directive = unique_local_directives.get('output', None)
    if output_directive:
        # Schema validation has ensured that the fields below exist.
        output_name = output_directive.arguments[0].value.value
        if output_name in context['outputs']:
            raise GraphQLCompilationError(u'Cannot reuse output name: '
                                          u'{}, {}'.format(
                                              output_name, context))
        validate_safe_string(output_name)

        graphql_type = strip_non_null_from_type(current_schema_type)
        if is_in_fold_scope(context):
            graphql_type = GraphQLList(graphql_type)
            # Fold outputs are only allowed at the last level of traversal
            context['fold_innermost_scope'] = None

        context['outputs'][output_name] = {
            'location': location,
            'optional': is_in_optional_scope(context),
            'type': graphql_type,
            'fold': context.get('fold', None),
        }
Example #2
0
def test_is_type_of_used_to_resolve_runtime_type_for_interface():
    PetType = GraphQLInterfaceType(
        name='Pet',
        fields={
            'name': GraphQLField(GraphQLString)
        }
    )

    DogType = GraphQLObjectType(
        name='Dog',
        interfaces=[PetType],
        is_type_of=is_type_of(Dog),
        fields={
            'name': GraphQLField(GraphQLString),
            'woofs': GraphQLField(GraphQLBoolean)
        }
    )

    CatType = GraphQLObjectType(
        name='Cat',
        interfaces=[PetType],
        is_type_of=is_type_of(Cat),
        fields={
            'name': GraphQLField(GraphQLString),
            'meows': GraphQLField(GraphQLBoolean)
        }
    )

    schema = GraphQLSchema(
        query=GraphQLObjectType(
            name='Query',
            fields={
                'pets': GraphQLField(
                    GraphQLList(PetType),
                    resolver=lambda *_: [Dog('Odie', True), Cat('Garfield', False)]
                )
            }
        ),
        types=[CatType, DogType]
    )

    query = '''
    {
        pets {
            name
            ... on Dog {
                woofs
            }
            ... on Cat {
                meows
            }
        }
    }
    '''

    result = graphql(schema, query)
    assert not result.errors
    assert result.data == {'pets': [{'woofs': True, 'name': 'Odie'}, {'name': 'Garfield', 'meows': False}]}
Example #3
0
def test_is_type_of_used_to_resolve_runtime_type_for_interface():
    # type: () -> None
    PetType = GraphQLInterfaceType(
        name="Pet", fields={"name": GraphQLField(GraphQLString)}
    )

    DogType = GraphQLObjectType(
        name="Dog",
        interfaces=[PetType],
        is_type_of=is_type_of(Dog),
        fields={
            "name": GraphQLField(GraphQLString),
            "woofs": GraphQLField(GraphQLBoolean),
        },
    )

    CatType = GraphQLObjectType(
        name="Cat",
        interfaces=[PetType],
        is_type_of=is_type_of(Cat),
        fields={
            "name": GraphQLField(GraphQLString),
            "meows": GraphQLField(GraphQLBoolean),
        },
    )

    schema = GraphQLSchema(
        query=GraphQLObjectType(
            name="Query",
            fields={
                "pets": GraphQLField(
                    GraphQLList(PetType),
                    resolver=lambda *_: [Dog("Odie", True), Cat("Garfield", False)],
                )
            },
        ),
        types=[CatType, DogType],
    )

    query = """
    {
        pets {
            name
            ... on Dog {
                woofs
            }
            ... on Cat {
                meows
            }
        }
    }
    """

    result = graphql(schema, query)
    assert not result.errors
    assert result.data == {
        "pets": [{"woofs": True, "name": "Odie"}, {"name": "Garfield", "meows": False}]
    }
Example #4
0
def test_resolve_type_on_union_yields_useful_error():
    DogType = GraphQLObjectType(name='Dog',
                                fields={
                                    'name': GraphQLField(GraphQLString),
                                    'woofs': GraphQLField(GraphQLBoolean)
                                })

    HumanType = GraphQLObjectType(name='Human',
                                  fields={
                                      'name': GraphQLField(GraphQLString),
                                  })

    CatType = GraphQLObjectType(name='Cat',
                                fields={
                                    'name': GraphQLField(GraphQLString),
                                    'meows': GraphQLField(GraphQLBoolean)
                                })

    PetType = GraphQLUnionType(
        name='Pet',
        types=[DogType, CatType],
        resolve_type=make_type_resolver(
            lambda: [(Dog, DogType), (Cat, CatType), (Human, HumanType)]))

    schema = GraphQLSchema(
        query=GraphQLObjectType(name='Query',
                                fields={
                                    'pets':
                                    GraphQLField(GraphQLList(PetType),
                                                 resolver=lambda *_: [
                                                     Dog('Odie', True),
                                                     Cat('Garfield', False),
                                                     Human('Jon')
                                                 ])
                                }))

    query = '''
    {
        pets {
            ... on Dog {
                name
                woofs
            }
            ... on Cat {
                name
                meows
            }
        }
    }
    '''

    result = graphql(schema, query)
    assert result.errors[
        0].message == 'Runtime Object type "Human" is not a possible type for "Pet".'
    assert result.data == {
        'pets': [{
            'woofs': True,
            'name': 'Odie'
        }, {
            'name': 'Garfield',
            'meows': False
        }, None]
    }
Example #5
0
def test_resolve_type_can_use_type_string():
    def type_string_resolver(obj, *_):
        if isinstance(obj, Dog):
            return 'Dog'
        if isinstance(obj, Cat):
            return 'Cat'

    PetType = GraphQLInterfaceType(
        name='Pet',
        fields={'name': GraphQLField(GraphQLString)},
        resolve_type=type_string_resolver)

    DogType = GraphQLObjectType(name='Dog',
                                interfaces=[PetType],
                                fields={
                                    'name': GraphQLField(GraphQLString),
                                    'woofs': GraphQLField(GraphQLBoolean)
                                })

    CatType = GraphQLObjectType(name='Cat',
                                interfaces=[PetType],
                                fields={
                                    'name': GraphQLField(GraphQLString),
                                    'meows': GraphQLField(GraphQLBoolean)
                                })

    schema = GraphQLSchema(query=GraphQLObjectType(
        name='Query',
        fields={
            'pets':
            GraphQLField(
                GraphQLList(PetType),
                resolver=lambda *_:
                [Dog('Odie', True), Cat('Garfield', False)])
        }),
                           types=[CatType, DogType])

    query = '''
    {
        pets {
            name
            ... on Dog {
                woofs
            }
            ... on Cat {
                meows
            }
        }
    }
    '''

    result = graphql(schema, query)
    assert not result.errors
    assert result.data == {
        'pets': [{
            'woofs': True,
            'name': 'Odie'
        }, {
            'name': 'Garfield',
            'meows': False
        }]
    }
SomeBox = GraphQLInterfaceType(
    "SomeBox",
    fields=lambda: {
        "deepBox": GraphQLField(SomeBox),
        "unrelatedField": GraphQLField(GraphQLString),
    },
    resolve_type=lambda *_: StringBox,
)

StringBox = GraphQLObjectType(
    "StringBox",
    fields=lambda: {
        "scalar": GraphQLField(GraphQLString),
        "deepBox": GraphQLField(StringBox),
        "unrelatedField": GraphQLField(GraphQLString),
        "listStringBox": GraphQLField(GraphQLList(StringBox)),
        "stringBox": GraphQLField(StringBox),
        "intBox": GraphQLField(IntBox),
    },
    interfaces=[SomeBox],
)

IntBox = GraphQLObjectType(
    "IntBox",
    fields=lambda: {
        "scalar": GraphQLField(GraphQLInt),
        "deepBox": GraphQLField(IntBox),
        "unrelatedField": GraphQLField(GraphQLString),
        "listStringBox": GraphQLField(GraphQLList(StringBox)),
        "stringBox": GraphQLField(StringBox),
        "intBox": GraphQLField(IntBox),
        "name": GraphQLString,
        "value": GraphQLString
    }
)

QueryRootType = GraphQLObjectType(
    name="QueryRoot",
    fields={
        "thrower": GraphQLField(GraphQLNonNull(GraphQLString), resolve=resolve_raises),
        "request": GraphQLField(
            GraphQLNonNull(GraphQLString),
            resolve=lambda obj, info: info.context["request"].args.get("q"),
        ),
        "movies": GraphQLField(
            description="This is a list of books",
            type_=GraphQLList(MovieType),
            resolve=lambda x, y: movies
        ),
        "groverZeroZero": GraphQLField(
            description="Grover search alg 00",
            type_=GroverType,
            resolve=lambda x, y: GroverTwo()
        ),
        "context": GraphQLField(
            GraphQLObjectType(
                name="context",
                fields={
                    "session": GraphQLField(GraphQLString),
                    "request": GraphQLField(
                        GraphQLNonNull(GraphQLString),
                        resolve=lambda obj, info: info.context["request"],
def test_converts_list_singletons():
    assert ast_from_value("FOO", GraphQLList(my_enum)) == ast.EnumValue("FOO")
Example #9
0
def test_resolve_type_can_use_type_string():
    # type: () -> None

    def type_string_resolver(obj, *_):
        # type: (Union[Cat, Dog], *ResolveInfo) -> str
        if isinstance(obj, Dog):
            return "Dog"
        if isinstance(obj, Cat):
            return "Cat"

    PetType = GraphQLInterfaceType(
        name="Pet",
        fields={"name": GraphQLField(GraphQLString)},
        resolve_type=type_string_resolver,
    )

    DogType = GraphQLObjectType(
        name="Dog",
        interfaces=[PetType],
        fields={
            "name": GraphQLField(GraphQLString),
            "woofs": GraphQLField(GraphQLBoolean),
        },
    )

    CatType = GraphQLObjectType(
        name="Cat",
        interfaces=[PetType],
        fields={
            "name": GraphQLField(GraphQLString),
            "meows": GraphQLField(GraphQLBoolean),
        },
    )

    schema = GraphQLSchema(
        query=GraphQLObjectType(
            name="Query",
            fields={
                "pets": GraphQLField(
                    GraphQLList(PetType),
                    resolver=lambda *_: [Dog("Odie", True), Cat("Garfield", False)],
                )
            },
        ),
        types=[CatType, DogType],
    )

    query = """
    {
        pets {
            name
            ... on Dog {
                woofs
            }
            ... on Cat {
                meows
            }
        }
    }
    """

    result = graphql(schema, query)
    assert not result.errors
    assert result.data == {
        "pets": [{"woofs": True, "name": "Odie"}, {"name": "Garfield", "meows": False}]
    }
Example #10
0
def test_resolve_type_on_union_yields_useful_error():
    # type: () -> None
    DogType = GraphQLObjectType(
        name="Dog",
        fields={
            "name": GraphQLField(GraphQLString),
            "woofs": GraphQLField(GraphQLBoolean),
        },
    )

    HumanType = GraphQLObjectType(
        name="Human", fields={"name": GraphQLField(GraphQLString)}
    )

    CatType = GraphQLObjectType(
        name="Cat",
        fields={
            "name": GraphQLField(GraphQLString),
            "meows": GraphQLField(GraphQLBoolean),
        },
    )

    PetType = GraphQLUnionType(
        name="Pet",
        types=[DogType, CatType],
        resolve_type=make_type_resolver(
            lambda: [(Dog, DogType), (Cat, CatType), (Human, HumanType)]
        ),
    )

    schema = GraphQLSchema(
        query=GraphQLObjectType(
            name="Query",
            fields={
                "pets": GraphQLField(
                    GraphQLList(PetType),
                    resolver=lambda *_: [
                        Dog("Odie", True),
                        Cat("Garfield", False),
                        Human("Jon"),
                    ],
                )
            },
        )
    )

    query = """
    {
        pets {
            ... on Dog {
                name
                woofs
            }
            ... on Cat {
                name
                meows
            }
        }
    }
    """

    result = graphql(schema, query)
    assert (
            result.errors[0].message
            == 'Runtime Object type "Human" is not a possible type for "Pet".'
    )
    assert result.data == {
        "pets": [
            {"woofs": True, "name": "Odie"},
            {"name": "Garfield", "meows": False},
            None,
        ]
    }
Example #11
0
SomeBox = GraphQLInterfaceType(
    'SomeBox',
    fields=lambda: {
        'deepBox': GraphQLField(SomeBox),
        'unrelatedField': GraphQLField(GraphQLString)
    },
    resolve_type=lambda *_: StringBox
)

StringBox = GraphQLObjectType(
    'StringBox',
    fields=lambda: {
        'scalar': GraphQLField(GraphQLString),
        'deepBox': GraphQLField(StringBox),
        'unrelatedField': GraphQLField(GraphQLString),
        'listStringBox': GraphQLField(GraphQLList(StringBox)),
        'stringBox': GraphQLField(StringBox),
        'intBox': GraphQLField(IntBox),
    },
    interfaces=[SomeBox]
)

IntBox = GraphQLObjectType(
    'IntBox',
    fields=lambda: {
        'scalar': GraphQLField(GraphQLInt),
        'deepBox': GraphQLField(IntBox),
        'unrelatedField': GraphQLField(GraphQLString),
        'listStringBox': GraphQLField(GraphQLList(StringBox)),
        'stringBox': GraphQLField(StringBox),
        'intBox': GraphQLField(IntBox),