mirror of
https://github.com/graphql-python/graphene.git
synced 2025-06-07 07:03:05 +03:00
Merge branch 'master' into ci-upload-artifact-codecov
This commit is contained in:
commit
ef0d35398e
21
.github/workflows/build.yaml
vendored
Normal file
21
.github/workflows/build.yaml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
name: 📦 Build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Python 3.10
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.10"
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install build twine
|
||||||
|
- name: Building package
|
||||||
|
run: python3 -m build
|
||||||
|
- name: Check package with Twine
|
||||||
|
run: twine check dist/*
|
4
.github/workflows/lint.yml
vendored
4
.github/workflows/lint.yml
vendored
|
@ -15,9 +15,7 @@ jobs:
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install ruff tox
|
pip install tox
|
||||||
- name: Format check using Ruff
|
|
||||||
run: ruff format --check
|
|
||||||
- name: Run lint
|
- name: Run lint
|
||||||
run: tox
|
run: tox
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -26,3 +26,4 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
|
args: [ --check ]
|
||||||
|
|
|
@ -69,43 +69,3 @@ You can also add extra keyword arguments to the ``execute`` method, such as
|
||||||
'hey': 'hello Peter!'
|
'hey': 'hello Peter!'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Snapshot testing
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
As our APIs evolve, we need to know when our changes introduce any breaking changes that might break
|
|
||||||
some of the clients of our GraphQL app.
|
|
||||||
|
|
||||||
However, writing tests and replicating the same response we expect from our GraphQL application can be a
|
|
||||||
tedious and repetitive task, and sometimes it's easier to skip this process.
|
|
||||||
|
|
||||||
Because of that, we recommend the usage of `SnapshotTest <https://github.com/syrusakbary/snapshottest/>`_.
|
|
||||||
|
|
||||||
SnapshotTest lets us write all these tests in a breeze, as it automatically creates the ``snapshots`` for us
|
|
||||||
the first time the test are executed.
|
|
||||||
|
|
||||||
|
|
||||||
Here is a simple example on how our tests will look if we use ``pytest``:
|
|
||||||
|
|
||||||
.. code:: python
|
|
||||||
|
|
||||||
def test_hey(snapshot):
|
|
||||||
client = Client(my_schema)
|
|
||||||
# This will create a snapshot dir and a snapshot file
|
|
||||||
# the first time the test is executed, with the response
|
|
||||||
# of the execution.
|
|
||||||
snapshot.assert_match(client.execute('''{ hey }'''))
|
|
||||||
|
|
||||||
|
|
||||||
If we are using ``unittest``:
|
|
||||||
|
|
||||||
.. code:: python
|
|
||||||
|
|
||||||
from snapshottest import TestCase
|
|
||||||
|
|
||||||
class APITestCase(TestCase):
|
|
||||||
def test_api_me(self):
|
|
||||||
"""Testing the API for /me"""
|
|
||||||
client = Client(my_schema)
|
|
||||||
self.assertMatchSnapshot(client.execute('''{ hey }'''))
|
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# snapshottest: v1 - https://goo.gl/zC4yUc
|
|
||||||
from snapshottest import Snapshot
|
|
||||||
|
|
||||||
snapshots = Snapshot()
|
|
||||||
|
|
||||||
snapshots["test_hero_name_query 1"] = {"data": {"hero": {"name": "R2-D2"}}}
|
|
||||||
|
|
||||||
snapshots["test_hero_name_and_friends_query 1"] = {
|
|
||||||
"data": {
|
|
||||||
"hero": {
|
|
||||||
"id": "2001",
|
|
||||||
"name": "R2-D2",
|
|
||||||
"friends": [
|
|
||||||
{"name": "Luke Skywalker"},
|
|
||||||
{"name": "Han Solo"},
|
|
||||||
{"name": "Leia Organa"},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_nested_query 1"] = {
|
|
||||||
"data": {
|
|
||||||
"hero": {
|
|
||||||
"name": "R2-D2",
|
|
||||||
"friends": [
|
|
||||||
{
|
|
||||||
"name": "Luke Skywalker",
|
|
||||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
|
||||||
"friends": [
|
|
||||||
{"name": "Han Solo"},
|
|
||||||
{"name": "Leia Organa"},
|
|
||||||
{"name": "C-3PO"},
|
|
||||||
{"name": "R2-D2"},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Han Solo",
|
|
||||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
|
||||||
"friends": [
|
|
||||||
{"name": "Luke Skywalker"},
|
|
||||||
{"name": "Leia Organa"},
|
|
||||||
{"name": "R2-D2"},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Leia Organa",
|
|
||||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
|
||||||
"friends": [
|
|
||||||
{"name": "Luke Skywalker"},
|
|
||||||
{"name": "Han Solo"},
|
|
||||||
{"name": "C-3PO"},
|
|
||||||
{"name": "R2-D2"},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_fetch_luke_query 1"] = {"data": {"human": {"name": "Luke Skywalker"}}}
|
|
||||||
|
|
||||||
snapshots["test_fetch_some_id_query 1"] = {
|
|
||||||
"data": {"human": {"name": "Luke Skywalker"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_fetch_some_id_query2 1"] = {"data": {"human": {"name": "Han Solo"}}}
|
|
||||||
|
|
||||||
snapshots["test_invalid_id_query 1"] = {"data": {"human": None}}
|
|
||||||
|
|
||||||
snapshots["test_fetch_luke_aliased 1"] = {"data": {"luke": {"name": "Luke Skywalker"}}}
|
|
||||||
|
|
||||||
snapshots["test_fetch_luke_and_leia_aliased 1"] = {
|
|
||||||
"data": {"luke": {"name": "Luke Skywalker"}, "leia": {"name": "Leia Organa"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_duplicate_fields 1"] = {
|
|
||||||
"data": {
|
|
||||||
"luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
|
|
||||||
"leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_use_fragment 1"] = {
|
|
||||||
"data": {
|
|
||||||
"luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
|
|
||||||
"leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_check_type_of_r2 1"] = {
|
|
||||||
"data": {"hero": {"__typename": "Droid", "name": "R2-D2"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_check_type_of_luke 1"] = {
|
|
||||||
"data": {"hero": {"__typename": "Human", "name": "Luke Skywalker"}}
|
|
||||||
}
|
|
|
@ -8,19 +8,19 @@ setup()
|
||||||
client = Client(schema)
|
client = Client(schema)
|
||||||
|
|
||||||
|
|
||||||
def test_hero_name_query(snapshot):
|
def test_hero_name_query():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query HeroNameQuery {
|
query HeroNameQuery {
|
||||||
hero {
|
hero {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {"data": {"hero": {"name": "R2-D2"}}}
|
||||||
|
|
||||||
|
|
||||||
def test_hero_name_and_friends_query(snapshot):
|
def test_hero_name_and_friends_query():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query HeroNameAndFriendsQuery {
|
query HeroNameAndFriendsQuery {
|
||||||
hero {
|
hero {
|
||||||
id
|
id
|
||||||
|
@ -30,12 +30,24 @@ def test_hero_name_and_friends_query(snapshot):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {
|
||||||
|
"hero": {
|
||||||
|
"id": "2001",
|
||||||
|
"name": "R2-D2",
|
||||||
|
"friends": [
|
||||||
|
{"name": "Luke Skywalker"},
|
||||||
|
{"name": "Han Solo"},
|
||||||
|
{"name": "Leia Organa"},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_nested_query(snapshot):
|
def test_nested_query():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query NestedQuery {
|
query NestedQuery {
|
||||||
hero {
|
hero {
|
||||||
name
|
name
|
||||||
|
@ -48,70 +60,113 @@ def test_nested_query(snapshot):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {
|
||||||
|
"hero": {
|
||||||
|
"name": "R2-D2",
|
||||||
|
"friends": [
|
||||||
|
{
|
||||||
|
"name": "Luke Skywalker",
|
||||||
|
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||||
|
"friends": [
|
||||||
|
{"name": "Han Solo"},
|
||||||
|
{"name": "Leia Organa"},
|
||||||
|
{"name": "C-3PO"},
|
||||||
|
{"name": "R2-D2"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Han Solo",
|
||||||
|
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||||
|
"friends": [
|
||||||
|
{"name": "Luke Skywalker"},
|
||||||
|
{"name": "Leia Organa"},
|
||||||
|
{"name": "R2-D2"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Leia Organa",
|
||||||
|
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||||
|
"friends": [
|
||||||
|
{"name": "Luke Skywalker"},
|
||||||
|
{"name": "Han Solo"},
|
||||||
|
{"name": "C-3PO"},
|
||||||
|
{"name": "R2-D2"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_fetch_luke_query(snapshot):
|
def test_fetch_luke_query():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query FetchLukeQuery {
|
query FetchLukeQuery {
|
||||||
human(id: "1000") {
|
human(id: "1000") {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {"data": {"human": {"name": "Luke Skywalker"}}}
|
||||||
|
|
||||||
|
|
||||||
def test_fetch_some_id_query(snapshot):
|
def test_fetch_some_id_query():
|
||||||
query = """
|
result = client.execute(
|
||||||
|
"""
|
||||||
query FetchSomeIDQuery($someId: String!) {
|
query FetchSomeIDQuery($someId: String!) {
|
||||||
human(id: $someId) {
|
human(id: $someId) {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""",
|
||||||
params = {"someId": "1000"}
|
variables={"someId": "1000"},
|
||||||
snapshot.assert_match(client.execute(query, variables=params))
|
)
|
||||||
|
assert result == {"data": {"human": {"name": "Luke Skywalker"}}}
|
||||||
|
|
||||||
|
|
||||||
def test_fetch_some_id_query2(snapshot):
|
def test_fetch_some_id_query2():
|
||||||
query = """
|
result = client.execute(
|
||||||
|
"""
|
||||||
query FetchSomeIDQuery($someId: String!) {
|
query FetchSomeIDQuery($someId: String!) {
|
||||||
human(id: $someId) {
|
human(id: $someId) {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""",
|
||||||
params = {"someId": "1002"}
|
variables={"someId": "1002"},
|
||||||
snapshot.assert_match(client.execute(query, variables=params))
|
)
|
||||||
|
assert result == {"data": {"human": {"name": "Han Solo"}}}
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_id_query(snapshot):
|
def test_invalid_id_query():
|
||||||
query = """
|
result = client.execute(
|
||||||
|
"""
|
||||||
query humanQuery($id: String!) {
|
query humanQuery($id: String!) {
|
||||||
human(id: $id) {
|
human(id: $id) {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""",
|
||||||
params = {"id": "not a valid id"}
|
variables={"id": "not a valid id"},
|
||||||
snapshot.assert_match(client.execute(query, variables=params))
|
)
|
||||||
|
assert result == {"data": {"human": None}}
|
||||||
|
|
||||||
|
|
||||||
def test_fetch_luke_aliased(snapshot):
|
def test_fetch_luke_aliased():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query FetchLukeAliased {
|
query FetchLukeAliased {
|
||||||
luke: human(id: "1000") {
|
luke: human(id: "1000") {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {"data": {"luke": {"name": "Luke Skywalker"}}}
|
||||||
|
|
||||||
|
|
||||||
def test_fetch_luke_and_leia_aliased(snapshot):
|
def test_fetch_luke_and_leia_aliased():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query FetchLukeAndLeiaAliased {
|
query FetchLukeAndLeiaAliased {
|
||||||
luke: human(id: "1000") {
|
luke: human(id: "1000") {
|
||||||
name
|
name
|
||||||
|
@ -120,12 +175,14 @@ def test_fetch_luke_and_leia_aliased(snapshot):
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {"luke": {"name": "Luke Skywalker"}, "leia": {"name": "Leia Organa"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_duplicate_fields(snapshot):
|
def test_duplicate_fields():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query DuplicateFields {
|
query DuplicateFields {
|
||||||
luke: human(id: "1000") {
|
luke: human(id: "1000") {
|
||||||
name
|
name
|
||||||
|
@ -136,12 +193,17 @@ def test_duplicate_fields(snapshot):
|
||||||
homePlanet
|
homePlanet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {
|
||||||
|
"luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
|
||||||
|
"leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_use_fragment(snapshot):
|
def test_use_fragment():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query UseFragment {
|
query UseFragment {
|
||||||
luke: human(id: "1000") {
|
luke: human(id: "1000") {
|
||||||
...HumanFragment
|
...HumanFragment
|
||||||
|
@ -154,29 +216,36 @@ def test_use_fragment(snapshot):
|
||||||
name
|
name
|
||||||
homePlanet
|
homePlanet
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {
|
||||||
|
"luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
|
||||||
|
"leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_check_type_of_r2(snapshot):
|
def test_check_type_of_r2():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query CheckTypeOfR2 {
|
query CheckTypeOfR2 {
|
||||||
hero {
|
hero {
|
||||||
__typename
|
__typename
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {"data": {"hero": {"__typename": "Droid", "name": "R2-D2"}}}
|
||||||
|
|
||||||
|
|
||||||
def test_check_type_of_luke(snapshot):
|
def test_check_type_of_luke():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query CheckTypeOfLuke {
|
query CheckTypeOfLuke {
|
||||||
hero(episode: EMPIRE) {
|
hero(episode: EMPIRE) {
|
||||||
__typename
|
__typename
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {"hero": {"__typename": "Human", "name": "Luke Skywalker"}}
|
||||||
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# snapshottest: v1 - https://goo.gl/zC4yUc
|
|
||||||
from snapshottest import Snapshot
|
|
||||||
|
|
||||||
snapshots = Snapshot()
|
|
||||||
|
|
||||||
snapshots["test_correct_fetch_first_ship_rebels 1"] = {
|
|
||||||
"data": {
|
|
||||||
"rebels": {
|
|
||||||
"name": "Alliance to Restore the Republic",
|
|
||||||
"ships": {
|
|
||||||
"pageInfo": {
|
|
||||||
"startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
|
||||||
"endCursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
|
||||||
"hasNextPage": True,
|
|
||||||
"hasPreviousPage": False,
|
|
||||||
},
|
|
||||||
"edges": [
|
|
||||||
{"cursor": "YXJyYXljb25uZWN0aW9uOjA=", "node": {"name": "X-Wing"}}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# snapshottest: v1 - https://goo.gl/zC4yUc
|
|
||||||
from snapshottest import Snapshot
|
|
||||||
|
|
||||||
snapshots = Snapshot()
|
|
||||||
|
|
||||||
snapshots["test_mutations 1"] = {
|
|
||||||
"data": {
|
|
||||||
"introduceShip": {
|
|
||||||
"ship": {"id": "U2hpcDo5", "name": "Peter"},
|
|
||||||
"faction": {
|
|
||||||
"name": "Alliance to Restore the Republic",
|
|
||||||
"ships": {
|
|
||||||
"edges": [
|
|
||||||
{"node": {"id": "U2hpcDox", "name": "X-Wing"}},
|
|
||||||
{"node": {"id": "U2hpcDoy", "name": "Y-Wing"}},
|
|
||||||
{"node": {"id": "U2hpcDoz", "name": "A-Wing"}},
|
|
||||||
{"node": {"id": "U2hpcDo0", "name": "Millennium Falcon"}},
|
|
||||||
{"node": {"id": "U2hpcDo1", "name": "Home One"}},
|
|
||||||
{"node": {"id": "U2hpcDo5", "name": "Peter"}},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,114 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# snapshottest: v1 - https://goo.gl/zC4yUc
|
|
||||||
from snapshottest import Snapshot
|
|
||||||
|
|
||||||
|
|
||||||
snapshots = Snapshot()
|
|
||||||
|
|
||||||
snapshots["test_correctly_fetches_id_name_rebels 1"] = {
|
|
||||||
"data": {
|
|
||||||
"rebels": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_correctly_refetches_rebels 1"] = {
|
|
||||||
"data": {"node": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_correctly_fetches_id_name_empire 1"] = {
|
|
||||||
"data": {"empire": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_correctly_refetches_empire 1"] = {
|
|
||||||
"data": {"node": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_correctly_refetches_xwing 1"] = {
|
|
||||||
"data": {"node": {"id": "U2hpcDox", "name": "X-Wing"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshots["test_str_schema 1"] = '''type Query {
|
|
||||||
rebels: Faction
|
|
||||||
empire: Faction
|
|
||||||
node(
|
|
||||||
"""The ID of the object"""
|
|
||||||
id: ID!
|
|
||||||
): Node
|
|
||||||
}
|
|
||||||
|
|
||||||
"""A faction in the Star Wars saga"""
|
|
||||||
type Faction implements Node {
|
|
||||||
"""The ID of the object"""
|
|
||||||
id: ID!
|
|
||||||
|
|
||||||
"""The name of the faction."""
|
|
||||||
name: String
|
|
||||||
|
|
||||||
"""The ships used by the faction."""
|
|
||||||
ships(before: String, after: String, first: Int, last: Int): ShipConnection
|
|
||||||
}
|
|
||||||
|
|
||||||
"""An object with an ID"""
|
|
||||||
interface Node {
|
|
||||||
"""The ID of the object"""
|
|
||||||
id: ID!
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShipConnection {
|
|
||||||
"""Pagination data for this connection."""
|
|
||||||
pageInfo: PageInfo!
|
|
||||||
|
|
||||||
"""Contains the nodes in this connection."""
|
|
||||||
edges: [ShipEdge]!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
|
|
||||||
"""
|
|
||||||
type PageInfo {
|
|
||||||
"""When paginating forwards, are there more items?"""
|
|
||||||
hasNextPage: Boolean!
|
|
||||||
|
|
||||||
"""When paginating backwards, are there more items?"""
|
|
||||||
hasPreviousPage: Boolean!
|
|
||||||
|
|
||||||
"""When paginating backwards, the cursor to continue."""
|
|
||||||
startCursor: String
|
|
||||||
|
|
||||||
"""When paginating forwards, the cursor to continue."""
|
|
||||||
endCursor: String
|
|
||||||
}
|
|
||||||
|
|
||||||
"""A Relay edge containing a `Ship` and its cursor."""
|
|
||||||
type ShipEdge {
|
|
||||||
"""The item at the end of the edge"""
|
|
||||||
node: Ship
|
|
||||||
|
|
||||||
"""A cursor for use in pagination"""
|
|
||||||
cursor: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""A ship in the Star Wars saga"""
|
|
||||||
type Ship implements Node {
|
|
||||||
"""The ID of the object"""
|
|
||||||
id: ID!
|
|
||||||
|
|
||||||
"""The name of the ship."""
|
|
||||||
name: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Mutation {
|
|
||||||
introduceShip(input: IntroduceShipInput!): IntroduceShipPayload
|
|
||||||
}
|
|
||||||
|
|
||||||
type IntroduceShipPayload {
|
|
||||||
ship: Ship
|
|
||||||
faction: Faction
|
|
||||||
clientMutationId: String
|
|
||||||
}
|
|
||||||
|
|
||||||
input IntroduceShipInput {
|
|
||||||
shipName: String!
|
|
||||||
factionId: String!
|
|
||||||
clientMutationId: String
|
|
||||||
}'''
|
|
|
@ -8,26 +8,46 @@ setup()
|
||||||
client = Client(schema)
|
client = Client(schema)
|
||||||
|
|
||||||
|
|
||||||
def test_correct_fetch_first_ship_rebels(snapshot):
|
def test_correct_fetch_first_ship_rebels():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query RebelsShipsQuery {
|
query RebelsShipsQuery {
|
||||||
rebels {
|
rebels {
|
||||||
name,
|
name,
|
||||||
ships(first: 1) {
|
ships(first: 1) {
|
||||||
pageInfo {
|
pageInfo {
|
||||||
startCursor
|
startCursor
|
||||||
endCursor
|
endCursor
|
||||||
hasNextPage
|
hasNextPage
|
||||||
hasPreviousPage
|
hasPreviousPage
|
||||||
}
|
}
|
||||||
edges {
|
edges {
|
||||||
cursor
|
cursor
|
||||||
node {
|
node {
|
||||||
name
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
""")
|
||||||
|
assert result == {
|
||||||
|
"data": {
|
||||||
|
"rebels": {
|
||||||
|
"name": "Alliance to Restore the Republic",
|
||||||
|
"ships": {
|
||||||
|
"pageInfo": {
|
||||||
|
"startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
||||||
|
"endCursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
||||||
|
"hasNextPage": True,
|
||||||
|
"hasPreviousPage": False,
|
||||||
|
},
|
||||||
|
"edges": [
|
||||||
|
{
|
||||||
|
"cursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
||||||
|
"node": {"name": "X-Wing"},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"""
|
|
||||||
snapshot.assert_match(client.execute(query))
|
|
||||||
|
|
|
@ -8,26 +8,45 @@ setup()
|
||||||
client = Client(schema)
|
client = Client(schema)
|
||||||
|
|
||||||
|
|
||||||
def test_mutations(snapshot):
|
def test_mutations():
|
||||||
query = """
|
result = client.execute("""
|
||||||
mutation MyMutation {
|
mutation MyMutation {
|
||||||
introduceShip(input:{clientMutationId:"abc", shipName: "Peter", factionId: "1"}) {
|
introduceShip(input:{clientMutationId:"abc", shipName: "Peter", factionId: "1"}) {
|
||||||
ship {
|
ship {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
faction {
|
faction {
|
||||||
name
|
name
|
||||||
ships {
|
ships {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
""")
|
||||||
|
assert result == {
|
||||||
|
"data": {
|
||||||
|
"introduceShip": {
|
||||||
|
"ship": {"id": "U2hpcDo5", "name": "Peter"},
|
||||||
|
"faction": {
|
||||||
|
"name": "Alliance to Restore the Republic",
|
||||||
|
"ships": {
|
||||||
|
"edges": [
|
||||||
|
{"node": {"id": "U2hpcDox", "name": "X-Wing"}},
|
||||||
|
{"node": {"id": "U2hpcDoy", "name": "Y-Wing"}},
|
||||||
|
{"node": {"id": "U2hpcDoz", "name": "A-Wing"}},
|
||||||
|
{"node": {"id": "U2hpcDo0", "name": "Millennium Falcon"}},
|
||||||
|
{"node": {"id": "U2hpcDo1", "name": "Home One"}},
|
||||||
|
{"node": {"id": "U2hpcDo5", "name": "Peter"}},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"""
|
|
||||||
snapshot.assert_match(client.execute(query))
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import textwrap
|
||||||
|
|
||||||
from graphene.test import Client
|
from graphene.test import Client
|
||||||
|
|
||||||
from ..data import setup
|
from ..data import setup
|
||||||
|
@ -8,24 +10,115 @@ setup()
|
||||||
client = Client(schema)
|
client = Client(schema)
|
||||||
|
|
||||||
|
|
||||||
def test_str_schema(snapshot):
|
def test_str_schema():
|
||||||
snapshot.assert_match(str(schema).strip())
|
assert str(schema).strip() == textwrap.dedent(
|
||||||
|
'''\
|
||||||
|
type Query {
|
||||||
|
rebels: Faction
|
||||||
|
empire: Faction
|
||||||
|
node(
|
||||||
|
"""The ID of the object"""
|
||||||
|
id: ID!
|
||||||
|
): Node
|
||||||
|
}
|
||||||
|
|
||||||
|
"""A faction in the Star Wars saga"""
|
||||||
|
type Faction implements Node {
|
||||||
|
"""The ID of the object"""
|
||||||
|
id: ID!
|
||||||
|
|
||||||
|
"""The name of the faction."""
|
||||||
|
name: String
|
||||||
|
|
||||||
|
"""The ships used by the faction."""
|
||||||
|
ships(before: String, after: String, first: Int, last: Int): ShipConnection
|
||||||
|
}
|
||||||
|
|
||||||
|
"""An object with an ID"""
|
||||||
|
interface Node {
|
||||||
|
"""The ID of the object"""
|
||||||
|
id: ID!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShipConnection {
|
||||||
|
"""Pagination data for this connection."""
|
||||||
|
pageInfo: PageInfo!
|
||||||
|
|
||||||
|
"""Contains the nodes in this connection."""
|
||||||
|
edges: [ShipEdge]!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
|
||||||
|
"""
|
||||||
|
type PageInfo {
|
||||||
|
"""When paginating forwards, are there more items?"""
|
||||||
|
hasNextPage: Boolean!
|
||||||
|
|
||||||
|
"""When paginating backwards, are there more items?"""
|
||||||
|
hasPreviousPage: Boolean!
|
||||||
|
|
||||||
|
"""When paginating backwards, the cursor to continue."""
|
||||||
|
startCursor: String
|
||||||
|
|
||||||
|
"""When paginating forwards, the cursor to continue."""
|
||||||
|
endCursor: String
|
||||||
|
}
|
||||||
|
|
||||||
|
"""A Relay edge containing a `Ship` and its cursor."""
|
||||||
|
type ShipEdge {
|
||||||
|
"""The item at the end of the edge"""
|
||||||
|
node: Ship
|
||||||
|
|
||||||
|
"""A cursor for use in pagination"""
|
||||||
|
cursor: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""A ship in the Star Wars saga"""
|
||||||
|
type Ship implements Node {
|
||||||
|
"""The ID of the object"""
|
||||||
|
id: ID!
|
||||||
|
|
||||||
|
"""The name of the ship."""
|
||||||
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mutation {
|
||||||
|
introduceShip(input: IntroduceShipInput!): IntroduceShipPayload
|
||||||
|
}
|
||||||
|
|
||||||
|
type IntroduceShipPayload {
|
||||||
|
ship: Ship
|
||||||
|
faction: Faction
|
||||||
|
clientMutationId: String
|
||||||
|
}
|
||||||
|
|
||||||
|
input IntroduceShipInput {
|
||||||
|
shipName: String!
|
||||||
|
factionId: String!
|
||||||
|
clientMutationId: String
|
||||||
|
}'''
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_correctly_fetches_id_name_rebels(snapshot):
|
def test_correctly_fetches_id_name_rebels():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query RebelsQuery {
|
query RebelsQuery {
|
||||||
rebels {
|
rebels {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {
|
||||||
|
"rebels": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_correctly_refetches_rebels(snapshot):
|
def test_correctly_refetches_rebels():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query RebelsRefetchQuery {
|
query RebelsRefetchQuery {
|
||||||
node(id: "RmFjdGlvbjox") {
|
node(id: "RmFjdGlvbjox") {
|
||||||
id
|
id
|
||||||
|
@ -34,24 +127,30 @@ def test_correctly_refetches_rebels(snapshot):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {
|
||||||
|
"node": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_correctly_fetches_id_name_empire(snapshot):
|
def test_correctly_fetches_id_name_empire():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query EmpireQuery {
|
query EmpireQuery {
|
||||||
empire {
|
empire {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {"empire": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_correctly_refetches_empire(snapshot):
|
def test_correctly_refetches_empire():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query EmpireRefetchQuery {
|
query EmpireRefetchQuery {
|
||||||
node(id: "RmFjdGlvbjoy") {
|
node(id: "RmFjdGlvbjoy") {
|
||||||
id
|
id
|
||||||
|
@ -60,12 +159,14 @@ def test_correctly_refetches_empire(snapshot):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {
|
||||||
|
"data": {"node": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_correctly_refetches_xwing(snapshot):
|
def test_correctly_refetches_xwing():
|
||||||
query = """
|
result = client.execute("""
|
||||||
query XWingRefetchQuery {
|
query XWingRefetchQuery {
|
||||||
node(id: "U2hpcDox") {
|
node(id: "U2hpcDox") {
|
||||||
id
|
id
|
||||||
|
@ -74,5 +175,5 @@ def test_correctly_refetches_xwing(snapshot):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
""")
|
||||||
snapshot.assert_match(client.execute(query))
|
assert result == {"data": {"node": {"id": "U2hpcDox", "name": "X-Wing"}}}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# https://github.com/graphql-python/graphene/issues/1293
|
# https://github.com/graphql-python/graphene/issues/1293
|
||||||
|
|
||||||
import datetime
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
import graphene
|
import graphene
|
||||||
from graphql.utilities import print_schema
|
from graphql.utilities import print_schema
|
||||||
|
@ -9,11 +9,11 @@ from graphql.utilities import print_schema
|
||||||
class Filters(graphene.InputObjectType):
|
class Filters(graphene.InputObjectType):
|
||||||
datetime_after = graphene.DateTime(
|
datetime_after = graphene.DateTime(
|
||||||
required=False,
|
required=False,
|
||||||
default_value=datetime.datetime.utcfromtimestamp(1434549820776 / 1000),
|
default_value=datetime.fromtimestamp(1434549820.776, timezone.utc),
|
||||||
)
|
)
|
||||||
datetime_before = graphene.DateTime(
|
datetime_before = graphene.DateTime(
|
||||||
required=False,
|
required=False,
|
||||||
default_value=datetime.datetime.utcfromtimestamp(1444549820776 / 1000),
|
default_value=datetime.fromtimestamp(1444549820.776, timezone.utc),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,35 +51,30 @@ def test_jsonstring_invalid_query():
|
||||||
Test that if an invalid type is provided we get an error
|
Test that if an invalid type is provided we get an error
|
||||||
"""
|
"""
|
||||||
result = schema.execute("{ json(input: 1) }")
|
result = schema.execute("{ json(input: 1) }")
|
||||||
assert result.errors
|
assert result.errors == [
|
||||||
assert len(result.errors) == 1
|
{"message": "Expected value of type 'JSONString', found 1."},
|
||||||
assert result.errors[0].message == "Expected value of type 'JSONString', found 1."
|
]
|
||||||
|
|
||||||
result = schema.execute("{ json(input: {}) }")
|
result = schema.execute("{ json(input: {}) }")
|
||||||
assert result.errors
|
assert result.errors == [
|
||||||
assert len(result.errors) == 1
|
{"message": "Expected value of type 'JSONString', found {}."},
|
||||||
assert result.errors[0].message == "Expected value of type 'JSONString', found {}."
|
]
|
||||||
|
|
||||||
result = schema.execute('{ json(input: "a") }')
|
result = schema.execute('{ json(input: "a") }')
|
||||||
assert result.errors
|
assert result.errors == [
|
||||||
assert len(result.errors) == 1
|
{
|
||||||
assert result.errors[0].message == (
|
"message": "Expected value of type 'JSONString', found \"a\"; "
|
||||||
"Expected value of type 'JSONString', found \"a\"; "
|
"Badly formed JSONString: Expecting value: line 1 column 1 (char 0)",
|
||||||
"Badly formed JSONString: Expecting value: line 1 column 1 (char 0)"
|
},
|
||||||
)
|
]
|
||||||
|
|
||||||
result = schema.execute("""{ json(input: "{\\'key\\': 0}") }""")
|
result = schema.execute("""{ json(input: "{\\'key\\': 0}") }""")
|
||||||
assert result.errors
|
assert result.errors == [
|
||||||
assert len(result.errors) == 1
|
{"message": "Syntax Error: Invalid character escape sequence: '\\''."},
|
||||||
assert (
|
]
|
||||||
result.errors[0].message
|
|
||||||
== "Syntax Error: Invalid character escape sequence: '\\''."
|
|
||||||
)
|
|
||||||
|
|
||||||
result = schema.execute("""{ json(input: "{\\"key\\": 0,}") }""")
|
result = schema.execute("""{ json(input: "{\\"key\\": 0,}") }""")
|
||||||
assert result.errors
|
|
||||||
assert len(result.errors) == 1
|
assert len(result.errors) == 1
|
||||||
assert result.errors[0].message == (
|
assert result.errors[0].message.startswith(
|
||||||
'Expected value of type \'JSONString\', found "{\\"key\\": 0,}"; '
|
'Expected value of type \'JSONString\', found "{\\"key\\": 0,}"; Badly formed JSONString:'
|
||||||
"Badly formed JSONString: Expecting property name enclosed in double quotes: line 1 column 11 (char 10)"
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,67 +1,5 @@
|
||||||
import functools
|
from warnings import warn
|
||||||
import inspect
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
string_types = (type(b""), type(""))
|
|
||||||
|
|
||||||
|
|
||||||
def warn_deprecation(text):
|
def warn_deprecation(text: str):
|
||||||
warnings.warn(text, category=DeprecationWarning, stacklevel=2)
|
warn(text, category=DeprecationWarning, stacklevel=2)
|
||||||
|
|
||||||
|
|
||||||
def deprecated(reason):
|
|
||||||
"""
|
|
||||||
This is a decorator which can be used to mark functions
|
|
||||||
as deprecated. It will result in a warning being emitted
|
|
||||||
when the function is used.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if isinstance(reason, string_types):
|
|
||||||
# The @deprecated is used with a 'reason'.
|
|
||||||
#
|
|
||||||
# .. code-block:: python
|
|
||||||
#
|
|
||||||
# @deprecated("please, use another function")
|
|
||||||
# def old_function(x, y):
|
|
||||||
# pass
|
|
||||||
|
|
||||||
def decorator(func1):
|
|
||||||
if inspect.isclass(func1):
|
|
||||||
fmt1 = f"Call to deprecated class {func1.__name__} ({reason})."
|
|
||||||
else:
|
|
||||||
fmt1 = f"Call to deprecated function {func1.__name__} ({reason})."
|
|
||||||
|
|
||||||
@functools.wraps(func1)
|
|
||||||
def new_func1(*args, **kwargs):
|
|
||||||
warn_deprecation(fmt1)
|
|
||||||
return func1(*args, **kwargs)
|
|
||||||
|
|
||||||
return new_func1
|
|
||||||
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
elif inspect.isclass(reason) or inspect.isfunction(reason):
|
|
||||||
# The @deprecated is used without any 'reason'.
|
|
||||||
#
|
|
||||||
# .. code-block:: python
|
|
||||||
#
|
|
||||||
# @deprecated
|
|
||||||
# def old_function(x, y):
|
|
||||||
# pass
|
|
||||||
|
|
||||||
func2 = reason
|
|
||||||
|
|
||||||
if inspect.isclass(func2):
|
|
||||||
fmt2 = f"Call to deprecated class {func2.__name__}."
|
|
||||||
else:
|
|
||||||
fmt2 = f"Call to deprecated function {func2.__name__}."
|
|
||||||
|
|
||||||
@functools.wraps(func2)
|
|
||||||
def new_func2(*args, **kwargs):
|
|
||||||
warn_deprecation(fmt2)
|
|
||||||
return func2(*args, **kwargs)
|
|
||||||
|
|
||||||
return new_func2
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise TypeError(repr(type(reason)))
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from typing_extensions import deprecated
|
||||||
from .deprecated import deprecated
|
|
||||||
|
|
||||||
|
|
||||||
@deprecated("This function is deprecated")
|
@deprecated("This function is deprecated")
|
||||||
|
|
|
@ -1,75 +1,9 @@
|
||||||
from pytest import raises
|
|
||||||
|
|
||||||
from .. import deprecated
|
from .. import deprecated
|
||||||
from ..deprecated import deprecated as deprecated_decorator
|
|
||||||
from ..deprecated import warn_deprecation
|
from ..deprecated import warn_deprecation
|
||||||
|
|
||||||
|
|
||||||
def test_warn_deprecation(mocker):
|
def test_warn_deprecation(mocker):
|
||||||
mocker.patch.object(deprecated.warnings, "warn")
|
mocker.patch.object(deprecated, "warn")
|
||||||
|
|
||||||
warn_deprecation("OH!")
|
warn_deprecation("OH!")
|
||||||
deprecated.warnings.warn.assert_called_with(
|
deprecated.warn.assert_called_with("OH!", stacklevel=2, category=DeprecationWarning)
|
||||||
"OH!", stacklevel=2, category=DeprecationWarning
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_deprecated_decorator(mocker):
|
|
||||||
mocker.patch.object(deprecated, "warn_deprecation")
|
|
||||||
|
|
||||||
@deprecated_decorator
|
|
||||||
def my_func():
|
|
||||||
return True
|
|
||||||
|
|
||||||
result = my_func()
|
|
||||||
assert result
|
|
||||||
deprecated.warn_deprecation.assert_called_with(
|
|
||||||
"Call to deprecated function my_func."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_deprecated_class(mocker):
|
|
||||||
mocker.patch.object(deprecated, "warn_deprecation")
|
|
||||||
|
|
||||||
@deprecated_decorator
|
|
||||||
class X:
|
|
||||||
pass
|
|
||||||
|
|
||||||
result = X()
|
|
||||||
assert result
|
|
||||||
deprecated.warn_deprecation.assert_called_with("Call to deprecated class X.")
|
|
||||||
|
|
||||||
|
|
||||||
def test_deprecated_decorator_text(mocker):
|
|
||||||
mocker.patch.object(deprecated, "warn_deprecation")
|
|
||||||
|
|
||||||
@deprecated_decorator("Deprecation text")
|
|
||||||
def my_func():
|
|
||||||
return True
|
|
||||||
|
|
||||||
result = my_func()
|
|
||||||
assert result
|
|
||||||
deprecated.warn_deprecation.assert_called_with(
|
|
||||||
"Call to deprecated function my_func (Deprecation text)."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_deprecated_class_text(mocker):
|
|
||||||
mocker.patch.object(deprecated, "warn_deprecation")
|
|
||||||
|
|
||||||
@deprecated_decorator("Deprecation text")
|
|
||||||
class X:
|
|
||||||
pass
|
|
||||||
|
|
||||||
result = X()
|
|
||||||
assert result
|
|
||||||
deprecated.warn_deprecation.assert_called_with(
|
|
||||||
"Call to deprecated class X (Deprecation text)."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_deprecated_other_object(mocker):
|
|
||||||
mocker.patch.object(deprecated, "warn_deprecation")
|
|
||||||
|
|
||||||
with raises(TypeError):
|
|
||||||
deprecated_decorator({})
|
|
||||||
|
|
|
@ -9,6 +9,5 @@ def test_resolve_only_args(mocker):
|
||||||
return root, args
|
return root, args
|
||||||
|
|
||||||
wrapped_resolver = resolve_only_args(resolver)
|
wrapped_resolver = resolve_only_args(resolver)
|
||||||
assert deprecated.warn_deprecation.called
|
|
||||||
result = wrapped_resolver(1, 2, a=3)
|
result = wrapped_resolver(1, 2, a=3)
|
||||||
assert result == (1, {"a": 3})
|
assert result == (1, {"a": 3})
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -50,7 +50,6 @@ tests_require = [
|
||||||
"pytest-cov>=5,<6",
|
"pytest-cov>=5,<6",
|
||||||
"pytest-mock>=3,<4",
|
"pytest-mock>=3,<4",
|
||||||
"pytest-asyncio>=0.16,<2",
|
"pytest-asyncio>=0.16,<2",
|
||||||
"snapshottest>=0.6,<1",
|
|
||||||
"coveralls>=3.3,<5",
|
"coveralls>=3.3,<5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -84,6 +83,7 @@ setup(
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"graphql-core>=3.1,<3.3",
|
"graphql-core>=3.1,<3.3",
|
||||||
"graphql-relay>=3.1,<3.3",
|
"graphql-relay>=3.1,<3.3",
|
||||||
|
"typing-extensions>=4.7.1,<5",
|
||||||
],
|
],
|
||||||
tests_require=tests_require,
|
tests_require=tests_require,
|
||||||
extras_require={"test": tests_require, "dev": dev_requires},
|
extras_require={"test": tests_require, "dev": dev_requires},
|
||||||
|
|
8
tox.ini
8
tox.ini
|
@ -5,15 +5,13 @@ skipsdist = true
|
||||||
[testenv]
|
[testenv]
|
||||||
deps =
|
deps =
|
||||||
.[test]
|
.[test]
|
||||||
setenv =
|
|
||||||
PYTHONPATH = .:{envdir}
|
|
||||||
commands =
|
commands =
|
||||||
py{38,39,310,311,12,13}: pytest --cov=graphene graphene --cov-report=term --cov-report=xml examples {posargs}
|
pytest --cov=graphene graphene --cov-report=term --cov-report=xml examples {posargs}
|
||||||
|
|
||||||
[testenv:pre-commit]
|
[testenv:pre-commit]
|
||||||
basepython = python3.10
|
basepython = python3.10
|
||||||
deps =
|
deps =
|
||||||
pre-commit>=2.16,<3
|
pre-commit>=3.7,<4
|
||||||
setenv =
|
setenv =
|
||||||
LC_CTYPE=en_US.UTF-8
|
LC_CTYPE=en_US.UTF-8
|
||||||
commands =
|
commands =
|
||||||
|
@ -22,7 +20,7 @@ commands =
|
||||||
[testenv:mypy]
|
[testenv:mypy]
|
||||||
basepython = python3.10
|
basepython = python3.10
|
||||||
deps =
|
deps =
|
||||||
mypy>=0.950,<1
|
mypy>=1.10,<2
|
||||||
commands =
|
commands =
|
||||||
mypy graphene
|
mypy graphene
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user