Skip to content

Commit d383367

Browse files
authored
Merge branch 'master' into master
2 parents 734b3f0 + e39398a commit d383367

File tree

8 files changed

+162
-27
lines changed

8 files changed

+162
-27
lines changed

Diff for: .github/workflows/lint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Lint
22

3-
on: [pull_request]
3+
on: [push, pull_request]
44

55
jobs:
66
build:

Diff for: .github/workflows/tests.yml

+41-15
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,52 @@
11
name: Tests
22

3-
on: [pull_request]
3+
on: [push, pull_request]
44

55
jobs:
66
build:
7-
runs-on: ubuntu-latest
7+
runs-on: ${{ matrix.os }}
88
strategy:
99
max-parallel: 4
1010
matrix:
1111
python-version: ["3.6", "3.7", "3.8", "3.9-dev"]
12+
os: [ubuntu-latest, windows-latest]
13+
exclude:
14+
- os: windows-latest
15+
python-version: "3.6"
16+
- os: windows-latest
17+
python-version: "3.7"
18+
- os: windows-latest
19+
python-version: "3.9-dev"
20+
21+
steps:
22+
- uses: actions/checkout@v2
23+
- name: Set up Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v2
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
- name: Install dependencies
28+
run: |
29+
python -m pip install --upgrade pip
30+
pip install tox tox-gh-actions
31+
- name: Test with tox
32+
run: tox
33+
env:
34+
TOXENV: ${{ matrix.toxenv }}
35+
36+
coverage:
37+
runs-on: ubuntu-latest
1238

1339
steps:
14-
- uses: actions/checkout@v2
15-
- name: Set up Python ${{ matrix.python-version }}
16-
uses: actions/setup-python@v2
17-
with:
18-
python-version: ${{ matrix.python-version }}
19-
- name: Install dependencies
20-
run: |
21-
python -m pip install --upgrade pip
22-
pip install tox tox-gh-actions
23-
- name: Test with tox
24-
run: tox
25-
env:
26-
TOXENV: ${{ matrix.toxenv }}
40+
- uses: actions/checkout@v2
41+
- name: Set up Python 3.8
42+
uses: actions/setup-python@v2
43+
with:
44+
python-version: 3.8
45+
- name: Install test dependencies
46+
run: |
47+
python -m pip install --upgrade pip
48+
pip install .[test]
49+
- name: Test with coverage
50+
run: pytest --cov=graphql_server --cov-report=xml tests
51+
- name: Upload coverage to Codecov
52+
uses: codecov/codecov-action@v1

Diff for: graphql_server/aiohttp/graphqlview.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import List
55

66
from aiohttp import web
7-
from graphql import GraphQLError
7+
from graphql import ExecutionResult, GraphQLError
88
from graphql.type.schema import GraphQLSchema
99

1010
from graphql_server import (
@@ -152,7 +152,10 @@ async def __call__(self, request):
152152
)
153153

154154
exec_res = (
155-
[await ex for ex in execution_results]
155+
[
156+
ex if ex is None or isinstance(ex, ExecutionResult) else await ex
157+
for ex in execution_results
158+
]
156159
if self.enable_async
157160
else execution_results
158161
)

Diff for: graphql_server/sanic/graphqlview.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from functools import partial
55
from typing import List
66

7-
from graphql import GraphQLError
7+
from graphql import ExecutionResult, GraphQLError
88
from graphql.type.schema import GraphQLSchema
99
from sanic.response import HTTPResponse, html
1010
from sanic.views import HTTPMethodView
@@ -105,7 +105,12 @@ async def dispatch_request(self, request, *args, **kwargs):
105105
middleware=self.get_middleware(),
106106
)
107107
exec_res = (
108-
[await ex for ex in execution_results]
108+
[
109+
ex
110+
if ex is None or isinstance(ex, ExecutionResult)
111+
else await ex
112+
for ex in execution_results
113+
]
109114
if self.enable_async
110115
else execution_results
111116
)

Diff for: tests/aiohttp/schema.py

+18
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,22 @@ def resolver_field_sync(_obj, info):
9191
)
9292

9393

94+
def resolver_field_sync_1(_obj, info):
95+
return "synced_one"
96+
97+
98+
def resolver_field_sync_2(_obj, info):
99+
return "synced_two"
100+
101+
102+
SyncQueryType = GraphQLObjectType(
103+
"SyncQueryType",
104+
{
105+
"a": GraphQLField(GraphQLString, resolve=resolver_field_sync_1),
106+
"b": GraphQLField(GraphQLString, resolve=resolver_field_sync_2),
107+
},
108+
)
109+
110+
94111
AsyncSchema = GraphQLSchema(AsyncQueryType)
112+
SyncSchema = GraphQLSchema(SyncQueryType)

Diff for: tests/aiohttp/test_graphiqlview.py

+44-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from jinja2 import Environment
44

55
from tests.aiohttp.app import create_app, url_string
6-
from tests.aiohttp.schema import AsyncSchema, Schema
6+
from tests.aiohttp.schema import AsyncSchema, Schema, SyncSchema
77

88

99
@pytest.fixture
@@ -102,11 +102,51 @@ async def test_graphiql_get_subscriptions(app, client):
102102

103103

104104
@pytest.mark.asyncio
105-
@pytest.mark.parametrize("app", [create_app(schema=AsyncSchema, enable_async=True)])
106-
async def test_graphiql_async_schema(app, client):
105+
@pytest.mark.parametrize(
106+
"app", [create_app(schema=AsyncSchema, enable_async=True, graphiql=True)]
107+
)
108+
async def test_graphiql_enabled_async_schema(app, client):
107109
response = await client.get(
108110
url_string(query="{a,b,c}"), headers={"Accept": "text/html"},
109111
)
110112

113+
expected_response = (
114+
(
115+
"{\n"
116+
' "data": {\n'
117+
' "a": "hey",\n'
118+
' "b": "hey2",\n'
119+
' "c": "hey3"\n'
120+
" }\n"
121+
"}"
122+
)
123+
.replace('"', '\\"')
124+
.replace("\n", "\\n")
125+
)
126+
assert response.status == 200
127+
assert expected_response in await response.text()
128+
129+
130+
@pytest.mark.asyncio
131+
@pytest.mark.parametrize(
132+
"app", [create_app(schema=SyncSchema, enable_async=True, graphiql=True)]
133+
)
134+
async def test_graphiql_enabled_sync_schema(app, client):
135+
response = await client.get(
136+
url_string(query="{a,b}"), headers={"Accept": "text/html"},
137+
)
138+
139+
expected_response = (
140+
(
141+
"{\n"
142+
' "data": {\n'
143+
' "a": "synced_one",\n'
144+
' "b": "synced_two"\n'
145+
" }\n"
146+
"}"
147+
)
148+
.replace('"', '\\"')
149+
.replace("\n", "\\n")
150+
)
111151
assert response.status == 200
112-
assert await response.json() == {"data": {"a": "hey", "b": "hey2", "c": "hey3"}}
152+
assert expected_response in await response.text()

Diff for: tests/sanic/schema.py

+18
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,22 @@ def resolver_field_sync(_obj, info):
7878
},
7979
)
8080

81+
82+
def resolver_field_sync_1(_obj, info):
83+
return "synced_one"
84+
85+
86+
def resolver_field_sync_2(_obj, info):
87+
return "synced_two"
88+
89+
90+
SyncQueryType = GraphQLObjectType(
91+
"SyncQueryType",
92+
{
93+
"a": GraphQLField(GraphQLString, resolve=resolver_field_sync_1),
94+
"b": GraphQLField(GraphQLString, resolve=resolver_field_sync_2),
95+
},
96+
)
97+
8198
AsyncSchema = GraphQLSchema(AsyncQueryType)
99+
SyncSchema = GraphQLSchema(SyncQueryType)

Diff for: tests/sanic/test_graphiqlview.py

+28-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from jinja2 import Environment
33

44
from .app import create_app, url_string
5-
from .schema import AsyncSchema
5+
from .schema import AsyncSchema, SyncSchema
66

77

88
@pytest.fixture
@@ -62,9 +62,9 @@ def test_graphiql_html_is_not_accepted(app):
6262

6363

6464
@pytest.mark.parametrize(
65-
"app", [create_app(graphiql=True, schema=AsyncSchema, enable_async=True)]
65+
"app", [create_app(schema=AsyncSchema, enable_async=True, graphiql=True)]
6666
)
67-
def test_graphiql_asyncio_schema(app):
67+
def test_graphiql_enabled_async_schema(app):
6868
query = "{a,b,c}"
6969
_, response = app.client.get(
7070
uri=url_string(query=query), headers={"Accept": "text/html"}
@@ -86,3 +86,28 @@ def test_graphiql_asyncio_schema(app):
8686

8787
assert response.status == 200
8888
assert expected_response in response.body.decode("utf-8")
89+
90+
91+
@pytest.mark.parametrize(
92+
"app", [create_app(schema=SyncSchema, enable_async=True, graphiql=True)]
93+
)
94+
def test_graphiql_enabled_sync_schema(app):
95+
query = "{a,b}"
96+
_, response = app.client.get(
97+
uri=url_string(query=query), headers={"Accept": "text/html"}
98+
)
99+
100+
expected_response = (
101+
(
102+
"{\n"
103+
' "data": {\n'
104+
' "a": "synced_one",\n'
105+
' "b": "synced_two"\n'
106+
" }\n"
107+
"}"
108+
)
109+
.replace('"', '\\"')
110+
.replace("\n", "\\n")
111+
)
112+
assert response.status == 200
113+
assert expected_response in response.body.decode("utf-8")

0 commit comments

Comments
 (0)