Skip to content

Commit

Permalink
fix: use WeakRef for tracked handles
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Apr 8, 2021
1 parent 4926564 commit 27ce372
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
6 changes: 4 additions & 2 deletions packages/jest-core/src/cli/index.ts
Expand Up @@ -32,7 +32,7 @@ import watch from '../watch';

const {print: preRunMessagePrint} = preRunMessage;

type OnCompleteCallback = (results: AggregatedResult) => void;
type OnCompleteCallback = (results: AggregatedResult) => void | undefined;

export async function runCLI(
argv: Config.Argv,
Expand Down Expand Up @@ -89,7 +89,9 @@ export async function runCLI(
configsOfProjectsToRun,
hasDeprecationWarnings,
outputStream,
r => (results = r),
r => {
results = r;
},
);

if (argv.watch || argv.watchAll) {
Expand Down
22 changes: 17 additions & 5 deletions packages/jest-core/src/collectHandles.ts
Expand Up @@ -13,6 +13,8 @@ import type {Config} from '@jest/types';
import {formatExecError} from 'jest-message-util';
import {ErrorWithStack} from 'jest-util';

export type HandleCollectionResult = () => Array<Error>;

function stackIsFromUser(stack: string) {
// Either the test file, or something required by it
if (stack.includes('Runtime.requireModule')) {
Expand All @@ -37,9 +39,11 @@ function stackIsFromUser(stack: string) {

const alwaysActive = () => true;

const hasWeakRef = typeof WeakRef === 'function';

// Inspired by https://github.com/mafintosh/why-is-node-running/blob/master/index.js
// Extracted as we want to format the result ourselves
export default function collectHandles(): () => Array<Error> {
export default function collectHandles(): HandleCollectionResult {
const activeHandles: Map<
number,
{error: Error; isActive: () => boolean}
Expand Down Expand Up @@ -68,10 +72,18 @@ export default function collectHandles(): () => Array<Error> {
let isActive: () => boolean;

if (type === 'Timeout' || type === 'Immediate') {
// Timer that supports hasRef (Node v11+)
if ('hasRef' in resource) {
// Timer that supports hasRef (Node v11+)
// @ts-expect-error: doesn't exist in v10 typings
isActive = resource.hasRef.bind(resource);
if (hasWeakRef) {
const ref = new WeakRef(resource);
isActive = () => {
// @ts-expect-error: doesn't exist in v10 typings
return ref.deref()?.hasRef() ?? false;
};
} else {
// @ts-expect-error: doesn't exist in v10 typings
isActive = resource.hasRef.bind(resource);
}
} else {
// Timer that doesn't support hasRef
isActive = alwaysActive;
Expand All @@ -88,7 +100,7 @@ export default function collectHandles(): () => Array<Error> {

hook.enable();

return (): Array<Error> => {
return () => {
hook.disable();

// Get errors for every async resource still referenced at this moment
Expand Down
8 changes: 4 additions & 4 deletions packages/jest-core/src/runJest.ts
Expand Up @@ -26,7 +26,7 @@ import type FailedTestsCache from './FailedTestsCache';
import SearchSource from './SearchSource';
import TestScheduler, {TestSchedulerContext} from './TestScheduler';
import type TestWatcher from './TestWatcher';
import collectNodeHandles from './collectHandles';
import collectNodeHandles, {HandleCollectionResult} from './collectHandles';
import getNoTestsFoundMessage from './getNoTestsFoundMessage';
import runGlobalHook from './runGlobalHook';
import type {Filter, TestRunData} from './types';
Expand Down Expand Up @@ -70,7 +70,7 @@ type ProcessResultOptions = Pick<
Config.GlobalConfig,
'json' | 'outputFile' | 'testResultsProcessor'
> & {
collectHandles?: () => Array<Error>;
collectHandles?: HandleCollectionResult;
onComplete?: (result: AggregatedResult) => void;
outputStream: NodeJS.WriteStream;
};
Expand Down Expand Up @@ -111,7 +111,7 @@ const processResults = (
}
}

return onComplete && onComplete(runResults);
onComplete?.(runResults);
};

const testSchedulerContext: TestSchedulerContext = {
Expand Down Expand Up @@ -278,7 +278,7 @@ export default async function runJest({
await runGlobalHook({allTests, globalConfig, moduleName: 'globalTeardown'});
}

await processResults(results, {
processResults(results, {
collectHandles,
json: globalConfig.json,
onComplete,
Expand Down

0 comments on commit 27ce372

Please sign in to comment.