예제 #1
0
def test_collects_multiple_errors():
    iface = InterfaceType("IFace", [Field("f", ListType(String))])

    bad_name_union = UnionType("#BadNameUnion", lambda: [object_type])
    empty_union = UnionType("EmptyUnion", [])

    object_type = ObjectType(
        "SomeObject",
        [
            Field("f", String),
            Field("__f", lambda: empty_union),
            Field("g", lambda: bad_name_union),
        ],
        interfaces=[iface],
    )  # type: ObjectType

    schema = _single_type_schema(object_type)

    with pytest.raises(SchemaValidationError) as exc_info:
        validate_schema(schema)

    assert set([str(e) for e in exc_info.value.errors]) == set([
        'Invalid name "__f".',
        'Interface field "IFace.f" expects type "[String]" but "SomeObject.f" '
        'is type "String"',
        'UnionType "EmptyUnion" must at least define one member',
        'Invalid type name "#BadNameUnion"',
    ])
예제 #2
0
def test_unions():
    Foo = ObjectType("Foo", [Field("str", String)])
    Bar = ObjectType("Bar", [Field("int", Int)])
    SingleUnion = UnionType("SingleUnion", types=[Foo])
    MultiUnion = UnionType("MultiUnion", types=[Foo, Bar])
    Query = ObjectType(
        "Query", [Field("single", SingleUnion),
                  Field("multi", MultiUnion)])
    assert print_schema(Schema(Query), indent="    ") == dedent("""
        type Bar {
            int: Int
        }

        type Foo {
            str: String
        }

        union MultiUnion = Foo | Bar

        type Query {
            single: SingleUnion
            multi: MultiUnion
        }

        union SingleUnion = Foo
        """)
예제 #3
0
def test_reject_union_type_with_non_object_members():
    TypeA = ObjectType("TypeA", [Field("f", String)])
    BadUnion = UnionType("BadUnion", [TypeA, SomeScalar])  # type: ignore
    schema = _single_type_schema(BadUnion)
    with pytest.raises(SchemaError) as exc_info:
        validate_schema(schema)

    assert ('UnionType "BadUnion" expects object types but got "SomeScalar"'
            in str(exc_info.value))
예제 #4
0
def test_reject_union_type_with_duplicate_members():
    TypeA = ObjectType("TypeA", [Field("f", String)])
    BadUnion = UnionType("BadUnion", [TypeA, TypeA])
    schema = _single_type_schema(BadUnion)
    with pytest.raises(SchemaError) as exc_info:
        validate_schema(schema)

    assert 'UnionType "BadUnion" can only include type "TypeA" once' in str(
        exc_info.value)
예제 #5
0
def test_reject_union_type_with_no_member():
    EmptyUnion = UnionType("EmptyUnion", [])
    schema = _single_type_schema(EmptyUnion)

    with pytest.raises(SchemaError) as exc_info:
        validate_schema(schema)

    assert 'UnionType "EmptyUnion" must at least define one member' in str(
        exc_info.value)
예제 #6
0
async def test_type_resolution_on_union_yields_useful_error(assert_execution):
    # WARN: Different from ref implementation -> this should never happen so we crash .

    def _resolve_pet_type(value, *_):
        return {
            Dog: DogType,
            Cat: CatType,
            Human: HumanType
        }.get(type(value), None)

    HumanType = ObjectType("Human", [Field("name", String)])

    DogType = ObjectType(
        "Dog",
        [Field("name", String), Field("woofs", Boolean)])

    CatType = ObjectType(
        "Cat",
        [Field("name", String), Field("meows", Boolean)])

    PetType = UnionType("Pet", [DogType, CatType],
                        resolve_type=_resolve_pet_type)

    schema = Schema(
        ObjectType(
            "Query",
            [
                Field(
                    "pets",
                    ListType(PetType),
                    resolver=lambda *_: [
                        Dog("Odie", True),
                        Cat("Garfield", False),
                        Human("Jon"),
                    ],
                )
            ],
        ),
        types=[DogType, CatType],
    )

    await assert_execution(
        schema,
        """{
        pets {
            __typename
            ... on Dog { woofs, name }
            ... on Cat { meows, name }
        }
        }""",
        expected_exc=(
            RuntimeError,
            ('Runtime ObjectType "Human" is not a possible type for field '
             '"pets[2]" of type "Pet".'),
        ),
    )
예제 #7
0
def schema() -> Schema:
    Object = InterfaceType("Object", fields=[Field("id", NonNullType(ID))])

    Person = ObjectType(
        "Person",
        fields=[
            Field("id", NonNullType(ID)),
            Field("name", NonNullType(String)),
            Field("pets", NonNullType(ListType(lambda: Animal))),
        ],
        interfaces=[Object],
    )

    Animal = ObjectType(
        "Animal",
        fields=[
            Field("id", NonNullType(ID)),
            Field("name", NonNullType(String)),
            Field("owner", Person),
        ],
        interfaces=[Object],
    )

    LivingBeing = UnionType("LivingBeing", [Person, Animal])

    CreatePersonInput = InputObjectType(
        "CreatePersonInput",
        [InputField("id", ID),
         InputField("name", NonNullType(String))],
    )

    return Schema(
        query_type=ObjectType(
            "Query",
            fields=[
                Field("person", Person, args=[Argument("id", ID)]),
                Field("pet", Animal, args=[Argument("id", ID)]),
                Field("living_being", LivingBeing, args=[Argument("id", ID)]),
            ],
        ),
        mutation_type=ObjectType(
            "Mutation", fields=[Field("createPerson", CreatePersonInput)]),
    )
예제 #8
0
파일: conftest.py 프로젝트: lirsacc/py-gql
def schema():

    Being = InterfaceType(
        "Being", [Field("name", String, [Argument("surname", Boolean)])])

    Pet = InterfaceType(
        "Pet", [Field("name", String, [Argument("surname", Boolean)])])

    Canine = InterfaceType(
        "Canine", [Field("name", String, [Argument("surname", Boolean)])])

    DogCommand = EnumType(
        "DogCommand",
        [EnumValue("SIT", 0),
         EnumValue("HEEL", 1),
         EnumValue("DOWN", 2)],
    )

    FurColor = EnumType(
        "FurColor",
        [
            EnumValue("BROWN", 0),
            EnumValue("BLACK", 1),
            EnumValue("TAN", 2),
            EnumValue("SPOTTED", 3),
            EnumValue("NO_FUR", None),
            EnumValue("UNKNOWN", -1),
        ],
    )

    Dog = ObjectType(
        "Dog",
        [
            Field("name", String, args=[Argument("surname", Boolean)]),
            Field("nickname", String),
            Field("barkVolume", Int),
            Field("barks", Boolean),
            Field("doesKnowCommand", Boolean,
                  [Argument("dogCommand", DogCommand)]),
            Field(
                "isHousetrained",
                Boolean,
                [Argument("atOtherHomes", Boolean, True)],
            ),
            Field(
                "isAtLocation",
                Boolean,
                [Argument("x", Int), Argument("y", Int)],
            ),
        ],
        [Being, Pet, Canine],
    )

    Cat = ObjectType(
        "Cat",
        [
            Field("name", String, args=[Argument("surname", Boolean)]),
            Field("nickname", String),
            Field("meowVolume", Int),
            Field("meows", Boolean),
            Field("furColor", FurColor),
        ],
        [Being, Pet],
    )

    CatOrDog = UnionType("CatOrDog", [Dog, Cat])

    Intelligent = InterfaceType("Intelligent", [Field("iq", Int)])

    Human = ObjectType(
        "Human",
        lambda: [
            Field("name", String, args=[Argument("surname", Boolean)]),
            Field("iq", Int),
            Field("pets", ListType(Pet)),
            Field("relatives", ListType(Human)),
        ],
        [Being, Intelligent],
    )

    Alien = ObjectType(
        "Alien",
        [
            Field("name", String, args=[Argument("surname", Boolean)]),
            Field("iq", Int),
            Field("numEyes", Int),
        ],
        [Being, Intelligent],
    )

    DogOrHuman = UnionType("DogOrHuman", [Dog, Human])

    HumanOrAlien = UnionType("HumanOrAlien", [Human, Alien])

    ComplexInput = InputObjectType(
        "ComplexInput",
        [
            InputField("requiredField", NonNullType(Boolean)),
            InputField(
                "nonNullField", NonNullType(Boolean), default_value=False),
            InputField("intField", Int),
            InputField("stringField", String),
            InputField("booleanField", Boolean),
            InputField("stringListField", ListType(String)),
        ],
    )

    ComplicatedArgs = ObjectType(
        "ComplicatedArgs",
        [
            Field("intArgField", String, [Argument("intArg", Int)]),
            Field(
                "nonNullIntArgField",
                String,
                [Argument("nonNullIntArg", NonNullType(Int))],
            ),
            Field("stringArgField", String, [Argument("stringArg", String)]),
            Field("booleanArgField", String,
                  [Argument("booleanArg", Boolean)]),
            Field("enumArgField", String, [Argument("enumArg", FurColor)]),
            Field("floatArgField", String, [Argument("floatArg", Float)]),
            Field("idArgField", String, [Argument("idArg", ID)]),
            Field(
                "stringListArgField",
                String,
                [Argument("stringListArg", ListType(String))],
            ),
            Field(
                "stringListNonNullArgField",
                String,
                [
                    Argument("stringListNonNullArg",
                             ListType(NonNullType(String)))
                ],
            ),
            Field(
                "complexArgField",
                String,
                [Argument("complexArg", ComplexInput)],
            ),
            Field(
                "multipleReqs",
                String,
                [
                    Argument("req1", NonNullType(Int)),
                    Argument("req2", NonNullType(Int)),
                ],
            ),
            Field(
                "nonNullFieldWithDefault",
                String,
                [Argument("arg", NonNullType(Int), default_value=0)],
            ),
            Field(
                "multipleOpts",
                String,
                [Argument("opt1", Int, 0),
                 Argument("opt2", Int, 0)],
            ),
            Field(
                "multipleOptAndReq",
                String,
                [
                    Argument("req1", NonNullType(Int)),
                    Argument("req2", NonNullType(Int)),
                    Argument("opt1", Int, 0),
                    Argument("opt2", Int, 0),
                ],
            ),
        ],
    )

    def _invalid(*args, **kwargs):
        raise ValueError("Invalid scalar is always invalid")

    def _stringify(value):
        return str(value)

    InvalidScalar = ScalarType("Invalid", _stringify, _invalid, _invalid)
    AnyScalar = ScalarType("Any", _stringify, lambda x: x)  # type: ScalarType

    return Schema(
        ObjectType(
            "QueryRoot",
            [
                Field("human", Human, [Argument("id", ID)]),
                Field("alien", Alien),
                Field("dog", Dog),
                Field("cat", Cat),
                Field("pet", Pet),
                Field("catOrDog", CatOrDog),
                Field("dogOrHuman", DogOrHuman),
                Field("humanOrAlien", HumanOrAlien),
                Field("humanOrAlien", HumanOrAlien),
                Field("complicatedArgs", ComplicatedArgs),
                Field("invalidArg", String, [Argument("arg", InvalidScalar)]),
                Field("anydArg", String, [Argument("arg", AnyScalar)]),
            ],
        ),
        types=[Cat, Dog, Human, Alien],
        directives=[
            Directive("onQuery", ["QUERY"]),
            Directive("onMutation", ["MUTATION"]),
            Directive("onSubscription", ["SUBSCRIPTION"]),
            Directive("onField", ["FIELD"]),
            Directive("onFragmentDefinition", ["FRAGMENT_DEFINITION"]),
            Directive("onFragmentSpread", ["FRAGMENT_SPREAD"]),
            Directive("onInlineFragment", ["INLINE_FRAGMENT"]),
            Directive("onSchema", ["SCHEMA"]),
            Directive("onScalar", ["SCALAR"]),
            Directive("onObject", ["OBJECT"]),
            Directive("onFieldDefinition", ["FIELD_DEFINITION"]),
            Directive("onArgumentDefinition", ["ARGUMENT_DEFINITION"]),
            Directive("onInterface", ["INTERFACE"]),
            Directive("onUnion", ["UNION"]),
            Directive("onEnum", ["ENUM"]),
            Directive("onEnumValue", ["ENUM_VALUE"]),
            Directive("onInputObject", ["INPUT_OBJECT"]),
            Directive("onInputFieldDefinition", ["INPUT_FIELD_DEFINITION"]),
        ],
    )
예제 #9
0
CatType = ObjectType(
    "Cat",
    [Field("name", String), Field("meows", Boolean)],
    interfaces=[NamedType],
)


def _resolve_pet_type(value, *_):
    if isinstance(value, Dog):
        return DogType
    elif isinstance(value, Cat):
        return CatType


PetType = UnionType("Pet", [DogType, CatType], resolve_type=_resolve_pet_type)

PersonType = ObjectType(
    "Person",
    [
        Field("name", String),
        Field("pets", ListType(PetType)),
        Field("friends", lambda: ListType(NamedType)),
    ],
    interfaces=[NamedType],
)

_SCHEMA = Schema(PersonType)

_GARFIELD = Cat("Garfield", False)
_ODIE = Dog("Odie", True)
예제 #10
0
def test_accept_object_fields_with_union_subtype_of_interface_field():
    union = UnionType("union", [SomeObject])
    iface = InterfaceType("IFace", [Field("f", union)])
    obj = ObjectType("Obj", [Field("f", SomeObject)], interfaces=[iface])
    schema = _single_type_schema(obj)
    schema.validate()
예제 #11
0
def test_accept_union_type_with_valid_members():
    TypeA = ObjectType("TypeA", [Field("f", String)])
    TypeB = ObjectType("TypeB", [Field("f", String)])
    GoodUnion = UnionType("GoodUnion", [TypeA, TypeB])
    schema = _single_type_schema(GoodUnion)
    schema.validate()
예제 #12
0
    UnionType,
)
from py_gql.schema.validation import validate_schema

SomeScalar = ScalarType(
    "SomeScalar",
    serialize=lambda a: None,
    parse=lambda a: None,
    parse_literal=lambda a, **k: None,
)  # type: ScalarType

SomeObject = ObjectType("SomeObject", [Field("f", String)])

IncompleteObject = ObjectType("IncompleteObject", [])

SomeUnion = UnionType("SomeUnion", [SomeObject])

SomeInterface = InterfaceType("SomeInterface", [Field("f", String)])

SomeEnum = EnumType("SomeEnum", [EnumValue("ONLY")])

SomeInputObject = InputObjectType(
    "SomeInputObject", [InputField("val", String, default_value="hello")])


def _type_modifiers(t):
    return [t, ListType(t), NonNullType(t), NonNullType(ListType(t))]


def _with_modifiers(types):
    out = []  # type: List[GraphQLType]