Skip to content

Commit f62077d

Browse files
committed
add more tests, handle more invalid cases
1 parent c9c11cf commit f62077d

16 files changed

+7767
-43
lines changed

src/transform/__tests__/abstract-test.ts

Lines changed: 639 additions & 0 deletions
Large diffs are not rendered by default.

src/transform/__tests__/cancellation-test.ts

Lines changed: 800 additions & 0 deletions
Large diffs are not rendered by default.

src/transform/__tests__/defer-test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ import {
1717
import { GraphQLID, GraphQLString } from '../../type/scalars.js';
1818
import { GraphQLSchema } from '../../type/schema.js';
1919

20-
import { legacyExecuteIncrementally } from '../legacyExecuteIncrementally.js';
2120
import type {
2221
LegacyInitialIncrementalExecutionResult,
2322
LegacySubsequentIncrementalExecutionResult,
2423
} from '../transformResult.js';
2524

25+
import { execute } from './execute.js';
26+
2627
const friendType = new GraphQLObjectType({
2728
fields: {
2829
id: { type: GraphQLID },
@@ -141,7 +142,7 @@ async function complete(
141142
rootValue: unknown = { hero },
142143
enableEarlyExecution = false,
143144
) {
144-
const result = await legacyExecuteIncrementally({
145+
const result = await execute({
145146
schema,
146147
document,
147148
rootValue,
@@ -848,7 +849,7 @@ describe('Execute: legacy defer directive format', () => {
848849
promiseWithResolvers();
849850
let cResolverCalled = false;
850851
let eResolverCalled = false;
851-
const executeResult = legacyExecuteIncrementally({
852+
const executeResult = execute({
852853
schema,
853854
document,
854855
rootValue: {
@@ -964,7 +965,7 @@ describe('Execute: legacy defer directive format', () => {
964965
promiseWithResolvers<void>();
965966
let cResolverCalled = false;
966967
let eResolverCalled = false;
967-
const executeResult = legacyExecuteIncrementally({
968+
const executeResult = execute({
968969
schema,
969970
document,
970971
rootValue: {
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
import { expect } from 'chai';
2+
import { describe, it } from 'mocha';
3+
4+
import { parse } from '../../language/parser.js';
5+
6+
import { GraphQLObjectType } from '../../type/definition.js';
7+
import { GraphQLString } from '../../type/scalars.js';
8+
import { GraphQLSchema } from '../../type/schema.js';
9+
10+
import { executeSync } from './execute.js';
11+
12+
const schema = new GraphQLSchema({
13+
query: new GraphQLObjectType({
14+
name: 'TestType',
15+
fields: {
16+
a: { type: GraphQLString },
17+
b: { type: GraphQLString },
18+
},
19+
}),
20+
});
21+
22+
const rootValue = {
23+
a() {
24+
return 'a';
25+
},
26+
b() {
27+
return 'b';
28+
},
29+
};
30+
31+
function executeTestQuery(query: string) {
32+
const document = parse(query);
33+
return executeSync({ schema, document, rootValue });
34+
}
35+
36+
describe('Execute: handles directives', () => {
37+
describe('works without directives', () => {
38+
it('basic query works', () => {
39+
const result = executeTestQuery('{ a, b }');
40+
41+
expect(result).to.deep.equal({
42+
data: { a: 'a', b: 'b' },
43+
});
44+
});
45+
});
46+
47+
describe('works on scalars', () => {
48+
it('if true includes scalar', () => {
49+
const result = executeTestQuery('{ a, b @include(if: true) }');
50+
51+
expect(result).to.deep.equal({
52+
data: { a: 'a', b: 'b' },
53+
});
54+
});
55+
56+
it('if false omits on scalar', () => {
57+
const result = executeTestQuery('{ a, b @include(if: false) }');
58+
59+
expect(result).to.deep.equal({
60+
data: { a: 'a' },
61+
});
62+
});
63+
64+
it('unless false includes scalar', () => {
65+
const result = executeTestQuery('{ a, b @skip(if: false) }');
66+
67+
expect(result).to.deep.equal({
68+
data: { a: 'a', b: 'b' },
69+
});
70+
});
71+
72+
it('unless true omits scalar', () => {
73+
const result = executeTestQuery('{ a, b @skip(if: true) }');
74+
75+
expect(result).to.deep.equal({
76+
data: { a: 'a' },
77+
});
78+
});
79+
});
80+
81+
describe('works on fragment spreads', () => {
82+
it('if false omits fragment spread', () => {
83+
const result = executeTestQuery(`
84+
query {
85+
a
86+
...Frag @include(if: false)
87+
}
88+
fragment Frag on TestType {
89+
b
90+
}
91+
`);
92+
93+
expect(result).to.deep.equal({
94+
data: { a: 'a' },
95+
});
96+
});
97+
98+
it('if true includes fragment spread', () => {
99+
const result = executeTestQuery(`
100+
query {
101+
a
102+
...Frag @include(if: true)
103+
}
104+
fragment Frag on TestType {
105+
b
106+
}
107+
`);
108+
109+
expect(result).to.deep.equal({
110+
data: { a: 'a', b: 'b' },
111+
});
112+
});
113+
114+
it('unless false includes fragment spread', () => {
115+
const result = executeTestQuery(`
116+
query {
117+
a
118+
...Frag @skip(if: false)
119+
}
120+
fragment Frag on TestType {
121+
b
122+
}
123+
`);
124+
125+
expect(result).to.deep.equal({
126+
data: { a: 'a', b: 'b' },
127+
});
128+
});
129+
130+
it('unless true omits fragment spread', () => {
131+
const result = executeTestQuery(`
132+
query {
133+
a
134+
...Frag @skip(if: true)
135+
}
136+
fragment Frag on TestType {
137+
b
138+
}
139+
`);
140+
141+
expect(result).to.deep.equal({
142+
data: { a: 'a' },
143+
});
144+
});
145+
});
146+
147+
describe('works on inline fragment', () => {
148+
it('if false omits inline fragment', () => {
149+
const result = executeTestQuery(`
150+
query {
151+
a
152+
... on TestType @include(if: false) {
153+
b
154+
}
155+
}
156+
`);
157+
158+
expect(result).to.deep.equal({
159+
data: { a: 'a' },
160+
});
161+
});
162+
163+
it('if true includes inline fragment', () => {
164+
const result = executeTestQuery(`
165+
query {
166+
a
167+
... on TestType @include(if: true) {
168+
b
169+
}
170+
}
171+
`);
172+
173+
expect(result).to.deep.equal({
174+
data: { a: 'a', b: 'b' },
175+
});
176+
});
177+
178+
it('unless false includes inline fragment', () => {
179+
const result = executeTestQuery(`
180+
query {
181+
a
182+
... on TestType @skip(if: false) {
183+
b
184+
}
185+
}
186+
`);
187+
188+
expect(result).to.deep.equal({
189+
data: { a: 'a', b: 'b' },
190+
});
191+
});
192+
193+
it('unless true includes inline fragment', () => {
194+
const result = executeTestQuery(`
195+
query {
196+
a
197+
... on TestType @skip(if: true) {
198+
b
199+
}
200+
}
201+
`);
202+
203+
expect(result).to.deep.equal({
204+
data: { a: 'a' },
205+
});
206+
});
207+
});
208+
209+
describe('works on anonymous inline fragment', () => {
210+
it('if false omits anonymous inline fragment', () => {
211+
const result = executeTestQuery(`
212+
query {
213+
a
214+
... @include(if: false) {
215+
b
216+
}
217+
}
218+
`);
219+
220+
expect(result).to.deep.equal({
221+
data: { a: 'a' },
222+
});
223+
});
224+
225+
it('if true includes anonymous inline fragment', () => {
226+
const result = executeTestQuery(`
227+
query {
228+
a
229+
... @include(if: true) {
230+
b
231+
}
232+
}
233+
`);
234+
235+
expect(result).to.deep.equal({
236+
data: { a: 'a', b: 'b' },
237+
});
238+
});
239+
240+
it('unless false includes anonymous inline fragment', () => {
241+
const result = executeTestQuery(`
242+
query Q {
243+
a
244+
... @skip(if: false) {
245+
b
246+
}
247+
}
248+
`);
249+
250+
expect(result).to.deep.equal({
251+
data: { a: 'a', b: 'b' },
252+
});
253+
});
254+
255+
it('unless true includes anonymous inline fragment', () => {
256+
const result = executeTestQuery(`
257+
query {
258+
a
259+
... @skip(if: true) {
260+
b
261+
}
262+
}
263+
`);
264+
265+
expect(result).to.deep.equal({
266+
data: { a: 'a' },
267+
});
268+
});
269+
});
270+
271+
describe('works with skip and include directives', () => {
272+
it('include and no skip', () => {
273+
const result = executeTestQuery(`
274+
{
275+
a
276+
b @include(if: true) @skip(if: false)
277+
}
278+
`);
279+
280+
expect(result).to.deep.equal({
281+
data: { a: 'a', b: 'b' },
282+
});
283+
});
284+
285+
it('include and skip', () => {
286+
const result = executeTestQuery(`
287+
{
288+
a
289+
b @include(if: true) @skip(if: true)
290+
}
291+
`);
292+
293+
expect(result).to.deep.equal({
294+
data: { a: 'a' },
295+
});
296+
});
297+
298+
it('no include or skip', () => {
299+
const result = executeTestQuery(`
300+
{
301+
a
302+
b @include(if: false) @skip(if: false)
303+
}
304+
`);
305+
306+
expect(result).to.deep.equal({
307+
data: { a: 'a' },
308+
});
309+
});
310+
});
311+
});

src/transform/__tests__/execute.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { isPromise } from '../../jsutils/isPromise.js';
2+
import type { PromiseOrValue } from '../../jsutils/PromiseOrValue.js';
3+
4+
import type { ExecutionArgs } from '../../execution/execute.js';
5+
import type { ExecutionResult } from '../../execution/types.js';
6+
7+
import { legacyExecuteIncrementally } from '../legacyExecuteIncrementally.js';
8+
import type { LegacyExperimentalIncrementalExecutionResults } from '../transformResult.js';
9+
10+
export function executeSync(args: ExecutionArgs): ExecutionResult {
11+
const result = legacyExecuteIncrementally(args);
12+
13+
// Assert that the execution was synchronous.
14+
if (isPromise(result) || 'initialResult' in result) {
15+
throw new Error('GraphQL execution failed to complete synchronously.');
16+
}
17+
18+
return result;
19+
}
20+
21+
export function execute(
22+
args: ExecutionArgs,
23+
): PromiseOrValue<
24+
ExecutionResult | LegacyExperimentalIncrementalExecutionResults
25+
> {
26+
return legacyExecuteIncrementally(args);
27+
}

0 commit comments

Comments
 (0)