Skip to content

Commit 14762e7

Browse files
author
igor.luckenkov
committed
ignore coverage and skip abortion test if node doesn't support AbortController
1 parent 2e1d930 commit 14762e7

File tree

3 files changed

+85
-69
lines changed

3 files changed

+85
-69
lines changed

src/execution/__tests__/executor-test.ts

Lines changed: 72 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { describe, it } from 'mocha';
44
import { expectJSON } from '../../__testUtils__/expectJSON.js';
55
import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick.js';
66

7-
import { AbortController } from '../../jsutils/AbortController.js';
7+
import {
8+
AbortController,
9+
hasAbortControllerSupport,
10+
} from '../../jsutils/AbortController.js';
811
import { inspect } from '../../jsutils/inspect.js';
912

1013
import { Kind } from '../../language/kinds.js';
@@ -1277,59 +1280,60 @@ describe('Execute: Handles basic execution tasks', () => {
12771280
expect(possibleTypes).to.deep.equal([fooObject]);
12781281
});
12791282

1280-
it('stops execution and throws an error when signal is aborted', async () => {
1281-
/**
1282-
* This test has 3 resolvers nested in each other.
1283-
* Every resolve function waits 200ms before returning data.
1284-
*
1285-
* The test waits for the first resolver and half of the 2nd resolver execution time (200ms + 100ms)
1286-
* and then aborts the execution.
1287-
*
1288-
* 2nd resolver execution finishes, and we then expect to not execute the 3rd resolver
1289-
* and to get an error about aborted operation.
1290-
*/
1291-
1292-
const WAIT_MS_BEFORE_RESOLVING = 200;
1293-
const ABORT_IN_MS_AFTER_STARTING_EXECUTION =
1294-
WAIT_MS_BEFORE_RESOLVING + WAIT_MS_BEFORE_RESOLVING / 2;
1295-
1296-
const schema = new GraphQLSchema({
1297-
query: new GraphQLObjectType({
1298-
name: 'Query',
1299-
fields: {
1300-
resolvesIn500ms: {
1301-
type: new GraphQLObjectType({
1302-
name: 'ResolvesIn500ms',
1303-
fields: {
1304-
resolvesIn400ms: {
1305-
type: new GraphQLObjectType({
1306-
name: 'ResolvesIn400ms',
1307-
fields: {
1308-
shouldNotBeResolved: {
1309-
type: GraphQLString,
1310-
/* c8 ignore next 3 */
1311-
resolve: () => {
1312-
throw new Error('This should not be executed!');
1283+
/* c8 ignore start */
1284+
if (hasAbortControllerSupport) {
1285+
it('stops execution and throws an error when signal is aborted', async () => {
1286+
/**
1287+
* This test has 3 resolvers nested in each other.
1288+
* Every resolve function waits 200ms before returning data.
1289+
*
1290+
* The test waits for the first resolver and half of the 2nd resolver execution time (200ms + 100ms)
1291+
* and then aborts the execution.
1292+
*
1293+
* 2nd resolver execution finishes, and we then expect to not execute the 3rd resolver
1294+
* and to get an error about aborted operation.
1295+
*/
1296+
1297+
const WAIT_MS_BEFORE_RESOLVING = 200;
1298+
const ABORT_IN_MS_AFTER_STARTING_EXECUTION =
1299+
WAIT_MS_BEFORE_RESOLVING + WAIT_MS_BEFORE_RESOLVING / 2;
1300+
1301+
const schema = new GraphQLSchema({
1302+
query: new GraphQLObjectType({
1303+
name: 'Query',
1304+
fields: {
1305+
resolvesIn500ms: {
1306+
type: new GraphQLObjectType({
1307+
name: 'ResolvesIn500ms',
1308+
fields: {
1309+
resolvesIn400ms: {
1310+
type: new GraphQLObjectType({
1311+
name: 'ResolvesIn400ms',
1312+
fields: {
1313+
shouldNotBeResolved: {
1314+
type: GraphQLString,
1315+
resolve: () => {
1316+
throw new Error('This should not be executed!');
1317+
},
13131318
},
13141319
},
1315-
},
1316-
}),
1317-
resolve: () =>
1318-
new Promise((resolve) => {
1319-
setTimeout(() => resolve({}), WAIT_MS_BEFORE_RESOLVING);
13201320
}),
1321+
resolve: () =>
1322+
new Promise((resolve) => {
1323+
setTimeout(() => resolve({}), WAIT_MS_BEFORE_RESOLVING);
1324+
}),
1325+
},
13211326
},
1322-
},
1323-
}),
1324-
resolve: () =>
1325-
new Promise((resolve) => {
1326-
setTimeout(() => resolve({}), WAIT_MS_BEFORE_RESOLVING);
13271327
}),
1328+
resolve: () =>
1329+
new Promise((resolve) => {
1330+
setTimeout(() => resolve({}), WAIT_MS_BEFORE_RESOLVING);
1331+
}),
1332+
},
13281333
},
1329-
},
1330-
}),
1331-
});
1332-
const document = parse(`
1334+
}),
1335+
});
1336+
const document = parse(`
13331337
query {
13341338
resolvesIn500ms {
13351339
resolvesIn400ms {
@@ -1339,22 +1343,24 @@ describe('Execute: Handles basic execution tasks', () => {
13391343
}
13401344
`);
13411345

1342-
const abortController = new AbortController();
1343-
const executionPromise = execute({
1344-
schema,
1345-
document,
1346-
signal: abortController.signal,
1347-
});
1348-
1349-
setTimeout(
1350-
() => abortController.abort(),
1351-
ABORT_IN_MS_AFTER_STARTING_EXECUTION,
1352-
);
1353-
1354-
const result = await executionPromise;
1355-
expect(result.errors?.[0].message).to.eq('Execution aborted.');
1356-
expect(result.data).to.eql({
1357-
resolvesIn500ms: { resolvesIn400ms: null },
1358-
});
1359-
});
1346+
const abortController = new AbortController();
1347+
const executionPromise = execute({
1348+
schema,
1349+
document,
1350+
signal: abortController.signal,
1351+
});
1352+
1353+
setTimeout(
1354+
() => abortController.abort(),
1355+
ABORT_IN_MS_AFTER_STARTING_EXECUTION,
1356+
);
1357+
1358+
const result = await executionPromise;
1359+
expect(result.errors?.[0].message).to.eq('Execution aborted.');
1360+
expect(result.data).to.eql({
1361+
resolvesIn500ms: { resolvesIn400ms: null },
1362+
});
1363+
});
1364+
}
1365+
/* c8 ignore stop */
13601366
});

src/execution/execute.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ export function experimentalExecuteIncrementally(
339339
return executeImpl(exeContext);
340340
}
341341

342+
/* c8 ignore start */
342343
function subscribeToAbortSignal(exeContext: ExecutionContext): () => void {
343344
const { abortion } = exeContext;
344345
if (!abortion) {
@@ -353,6 +354,7 @@ function subscribeToAbortSignal(exeContext: ExecutionContext): () => void {
353354
abortion.executionAbortController.abort();
354355
};
355356
}
357+
/* c8 ignore stop */
356358

357359
function executeImpl(
358360
exeContext: ExecutionContext,
@@ -537,6 +539,7 @@ export function buildExecutionContext(
537539
};
538540
}
539541

542+
/* c8 ignore start */
540543
function getContextAbortionEntities(
541544
passedInAbortSignal: Maybe<IAbortSignal>,
542545
): ExecutionContext['abortion'] {
@@ -552,6 +555,7 @@ function getContextAbortionEntities(
552555
executionAbortSignal: executionAbortController.signal,
553556
};
554557
}
558+
/* c8 ignore stop */
555559

556560
function buildPerEventExecutionContext(
557561
exeContext: ExecutionContext,
@@ -886,12 +890,11 @@ function completeValue(
886890
result: unknown,
887891
asyncPayloadRecord?: AsyncPayloadRecord,
888892
): PromiseOrValue<unknown> {
889-
// Ignoring test coverage for abortion check since Node 14 doesn't support AbortSignal
890-
// and this condition is never true.
891-
/* c8 ignore next 3 */
893+
/* c8 ignore start */
892894
if (exeContext.abortion?.executionAbortSignal.aborted) {
893895
throw new GraphQLError('Execution aborted.');
894896
}
897+
/* c8 ignore stop */
895898

896899
// If result is an Error, throw a located error.
897900
if (result instanceof Error) {
@@ -1666,11 +1669,13 @@ export function experimentalSubscribeIncrementally(
16661669
> {
16671670
// Until we have execution cancelling support in Subscriptions,
16681671
// throw an error if client provides abort signal.
1672+
/* c8 ignore start */
16691673
if (args.signal) {
16701674
return {
16711675
errors: [new GraphQLError('Subscriptions do not support abort signals.')],
16721676
};
16731677
}
1678+
/* c8 ignore stop */
16741679

16751680
// If a valid execution context cannot be created due to incorrect arguments,
16761681
// a "Response" with only errors is returned.

src/jsutils/AbortController.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@ export const AbortController: new () => IAbortController =
2828
this._signal.aborted = true;
2929
}
3030
};
31+
32+
export const hasAbortControllerSupport =
33+
// eslint-disable-next-line no-undef
34+
Boolean(global.AbortController);
35+
3136
/* c8 ignore stop */

0 commit comments

Comments
 (0)