jest-doctor 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/createEnvMixin.js +9 -6
- package/dist/patch/promiseConcurrency.js +17 -11
- package/dist/types.d.ts +7 -11
- package/dist/utils/createAsyncHookCleaner.js +2 -1
- package/dist/utils/createAsyncHookDetector.js +5 -2
- package/dist/utils/getStack.js +1 -1
- package/dist/utils/normalizeOptions.d.ts +1 -1
- package/dist/utils/normalizeOptions.js +77 -45
- package/dist/utils/reportLeaks.js +1 -2
- package/package.json +5 -4
- package/readme.md +7 -11
- package/dist/patch/promise.d.ts +0 -3
- package/dist/patch/promise.js +0 -34
- package/dist/patch/race.d.ts +0 -1
- package/dist/patch/race.js +0 -2
package/dist/createEnvMixin.js
CHANGED
|
@@ -21,7 +21,6 @@ const hook_1 = __importDefault(require("./patch/hook"));
|
|
|
21
21
|
const getAllAfterEach_1 = __importDefault(require("./utils/getAllAfterEach"));
|
|
22
22
|
const normalizeOptions_1 = __importDefault(require("./utils/normalizeOptions"));
|
|
23
23
|
const getReporterTmpDir_1 = __importDefault(require("./utils/getReporterTmpDir"));
|
|
24
|
-
const promise_1 = __importDefault(require("./patch/promise"));
|
|
25
24
|
const promiseConcurrency_1 = __importDefault(require("./patch/promiseConcurrency"));
|
|
26
25
|
const createEnvMixin = (Environment) => {
|
|
27
26
|
// @ts-expect-error strange ts rule where constructor arguments should be any[] where again TypeScript complains
|
|
@@ -57,8 +56,7 @@ const createEnvMixin = (Environment) => {
|
|
|
57
56
|
: '';
|
|
58
57
|
this.options = (0, normalizeOptions_1.default)(config.projectConfig.testEnvironmentOptions);
|
|
59
58
|
(0, initLeakRecord_1.default)(this, consts_1.MAIN_THREAD);
|
|
60
|
-
if (this.options.report.promises
|
|
61
|
-
this.options.report.promises.patch === 'async_hooks') {
|
|
59
|
+
if (this.options.report.promises) {
|
|
62
60
|
this.asyncHookCleaner = (0, createAsyncHookCleaner_1.default)(this);
|
|
63
61
|
this.asyncHookDetector = (0, createAsyncHookDetector_1.default)(this);
|
|
64
62
|
}
|
|
@@ -76,9 +74,6 @@ const createEnvMixin = (Environment) => {
|
|
|
76
74
|
}
|
|
77
75
|
if (report.promises) {
|
|
78
76
|
(0, promiseConcurrency_1.default)(this);
|
|
79
|
-
if (report.promises.patch === 'promise') {
|
|
80
|
-
(0, promise_1.default)(this);
|
|
81
|
-
}
|
|
82
77
|
}
|
|
83
78
|
}
|
|
84
79
|
// unfortunately @jest/types doesn't export the necessary types,
|
|
@@ -104,6 +99,14 @@ const createEnvMixin = (Environment) => {
|
|
|
104
99
|
(0, hook_1.default)(this, 'beforeAll');
|
|
105
100
|
(0, hook_1.default)(this, 'afterEach');
|
|
106
101
|
(0, hook_1.default)(this, 'afterAll');
|
|
102
|
+
Object.assign(circusEvent.runtimeGlobals, {
|
|
103
|
+
it: this.global.it,
|
|
104
|
+
test: this.global.test,
|
|
105
|
+
beforeEach: this.global.beforeEach,
|
|
106
|
+
beforeAll: this.global.beforeAll,
|
|
107
|
+
afterEach: this.global.afterEach,
|
|
108
|
+
afterAll: this.global.afterAll,
|
|
109
|
+
});
|
|
107
110
|
}
|
|
108
111
|
await super.handleEvent?.(circusEvent, circusState);
|
|
109
112
|
}
|
|
@@ -4,20 +4,26 @@ const patchPromiseConcurrency = (that) => {
|
|
|
4
4
|
const env = that.global;
|
|
5
5
|
const concurrencyFactor = (fn) => (concurrentPromises) => {
|
|
6
6
|
const promises = that.leakRecords.get(that.currentTestName)?.promises;
|
|
7
|
-
|
|
8
|
-
const removePromises = () => {
|
|
7
|
+
return fn(concurrentPromises).finally(() => {
|
|
9
8
|
if (promises) {
|
|
10
|
-
concurrentPromises.forEach((
|
|
11
|
-
promises.
|
|
9
|
+
concurrentPromises.forEach((concurrentPromise) => {
|
|
10
|
+
const leak = promises.get(concurrentPromise);
|
|
11
|
+
if (leak) {
|
|
12
|
+
const asyncId = leak?.asyncId;
|
|
13
|
+
that.asyncIdToPromise.delete(asyncId);
|
|
14
|
+
that.promiseOwner.delete(asyncId);
|
|
15
|
+
promises.delete(concurrentPromise);
|
|
16
|
+
// Promise.race and Promise.any will create a new Promise for every entry that needs to be deleted
|
|
17
|
+
promises.forEach((childLeak, key) => {
|
|
18
|
+
if (childLeak.parentAsyncId === asyncId) {
|
|
19
|
+
that.asyncIdToPromise.delete(childLeak.asyncId);
|
|
20
|
+
that.promiseOwner.delete(childLeak.asyncId);
|
|
21
|
+
promises.delete(key);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
12
25
|
});
|
|
13
26
|
}
|
|
14
|
-
};
|
|
15
|
-
return fn(concurrentPromises).then((returnValues) => {
|
|
16
|
-
removePromises();
|
|
17
|
-
return returnValues;
|
|
18
|
-
}, (error) => {
|
|
19
|
-
removePromises();
|
|
20
|
-
throw error;
|
|
21
27
|
});
|
|
22
28
|
};
|
|
23
29
|
env.Promise.race = concurrencyFactor(env.Promise.race.bind(env.Promise));
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ModernFakeTimers } from '@jest/fake-timers';
|
|
2
2
|
import { JestEnvironment } from '@jest/environment';
|
|
3
3
|
import initOriginal from './utils/initOriginal';
|
|
4
|
+
import type { AsyncHook } from 'node:async_hooks';
|
|
4
5
|
export interface TimerRecord {
|
|
5
6
|
type: 'timeout' | 'interval' | 'fakeTimeout' | 'fakeInterval';
|
|
6
7
|
delay: number;
|
|
@@ -10,6 +11,8 @@ export interface TimerRecord {
|
|
|
10
11
|
export interface PromiseRecord {
|
|
11
12
|
stack: string;
|
|
12
13
|
testName: string;
|
|
14
|
+
asyncId: number;
|
|
15
|
+
parentAsyncId: number;
|
|
13
16
|
}
|
|
14
17
|
export interface ConsoleRecord {
|
|
15
18
|
method: keyof Console;
|
|
@@ -39,9 +42,8 @@ export interface FakeTimers extends Omit<ModernFakeTimers, '_fakeTimers'> {
|
|
|
39
42
|
};
|
|
40
43
|
}
|
|
41
44
|
export type TimerIsolation = 'afterEach' | 'immediate';
|
|
42
|
-
export type OnError =
|
|
45
|
+
export type OnError = false | 'throw' | 'warn';
|
|
43
46
|
export type ThrowOrWarn = 'throw' | 'warn';
|
|
44
|
-
export type Patch = 'async_hooks' | 'promise';
|
|
45
47
|
export interface ConsoleOptions {
|
|
46
48
|
onError: ThrowOrWarn;
|
|
47
49
|
methods: Array<keyof Console>;
|
|
@@ -53,10 +55,7 @@ export interface NormalizedOptions {
|
|
|
53
55
|
console: NormalizedConsoleOptions;
|
|
54
56
|
timers: OnError;
|
|
55
57
|
fakeTimers: OnError;
|
|
56
|
-
promises:
|
|
57
|
-
onError: ThrowOrWarn;
|
|
58
|
-
patch: Patch;
|
|
59
|
-
};
|
|
58
|
+
promises: OnError;
|
|
60
59
|
};
|
|
61
60
|
verbose: boolean;
|
|
62
61
|
delayThreshold: number;
|
|
@@ -68,16 +67,12 @@ export type RawConsoleOptions = boolean | {
|
|
|
68
67
|
methods?: Array<keyof Console>;
|
|
69
68
|
ignore?: string | RegExp | Array<string | RegExp>;
|
|
70
69
|
};
|
|
71
|
-
export type RawPromise = boolean | {
|
|
72
|
-
onError?: ThrowOrWarn;
|
|
73
|
-
patch?: Patch;
|
|
74
|
-
};
|
|
75
70
|
export interface RawOptions {
|
|
76
71
|
report?: {
|
|
77
72
|
console?: RawConsoleOptions;
|
|
78
73
|
timers?: OnError;
|
|
79
74
|
fakeTimers?: OnError;
|
|
80
|
-
promises?:
|
|
75
|
+
promises?: OnError;
|
|
81
76
|
};
|
|
82
77
|
verbose?: boolean;
|
|
83
78
|
delayThreshold?: number;
|
|
@@ -103,5 +98,6 @@ export interface JestDoctorEnvironment {
|
|
|
103
98
|
options: NormalizedOptions;
|
|
104
99
|
aggregatedReport: AggregatedReport;
|
|
105
100
|
asyncIdToPromise: Map<number, Promise<unknown>>;
|
|
101
|
+
asyncHookDetector?: AsyncHook;
|
|
106
102
|
}
|
|
107
103
|
export {};
|
|
@@ -5,8 +5,9 @@ const createAsyncHookCleaner = (that) => {
|
|
|
5
5
|
return (0, node_async_hooks_1.createHook)({
|
|
6
6
|
promiseResolve(asyncId) {
|
|
7
7
|
const owner = that.promiseOwner.get(asyncId);
|
|
8
|
-
if (!owner)
|
|
8
|
+
if (!owner) {
|
|
9
9
|
return;
|
|
10
|
+
}
|
|
10
11
|
const promise = that.asyncIdToPromise.get(asyncId);
|
|
11
12
|
if (promise) {
|
|
12
13
|
that.leakRecords.get(owner)?.promises.delete(promise);
|
|
@@ -6,9 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const node_async_hooks_1 = require("node:async_hooks");
|
|
7
7
|
const getStack_1 = __importDefault(require("./getStack"));
|
|
8
8
|
const createAsyncHookDetector = (that) => {
|
|
9
|
-
const init = (asyncId, type,
|
|
10
|
-
if (type !== 'PROMISE')
|
|
9
|
+
const init = (asyncId, type, parentAsyncId, resource) => {
|
|
10
|
+
if (type !== 'PROMISE') {
|
|
11
11
|
return;
|
|
12
|
+
}
|
|
12
13
|
const promise = resource;
|
|
13
14
|
const owner = that.currentTestName;
|
|
14
15
|
that.promiseOwner.set(asyncId, owner);
|
|
@@ -16,6 +17,8 @@ const createAsyncHookDetector = (that) => {
|
|
|
16
17
|
that.leakRecords.get(owner)?.promises.set(promise, {
|
|
17
18
|
stack: (0, getStack_1.default)(init, 'Promise'),
|
|
18
19
|
testName: owner,
|
|
20
|
+
asyncId,
|
|
21
|
+
parentAsyncId,
|
|
19
22
|
});
|
|
20
23
|
};
|
|
21
24
|
return (0, node_async_hooks_1.createHook)({ init });
|
package/dist/utils/getStack.js
CHANGED
|
@@ -1,6 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.normalizeOptions = normalizeOptions;
|
|
37
|
+
const zod = __importStar(require("zod"));
|
|
4
38
|
const DEFAULTS = {
|
|
5
39
|
report: {
|
|
6
40
|
console: {
|
|
@@ -10,58 +44,56 @@ const DEFAULTS = {
|
|
|
10
44
|
},
|
|
11
45
|
timers: 'throw',
|
|
12
46
|
fakeTimers: 'throw',
|
|
13
|
-
promises:
|
|
14
|
-
onError: 'throw',
|
|
15
|
-
patch: 'async_hooks',
|
|
16
|
-
},
|
|
47
|
+
promises: 'throw',
|
|
17
48
|
},
|
|
18
49
|
verbose: false,
|
|
19
50
|
delayThreshold: 0,
|
|
20
51
|
timerIsolation: 'afterEach',
|
|
21
52
|
clearTimers: true,
|
|
22
53
|
};
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
const onError = zod
|
|
55
|
+
.union([zod.literal(false), zod.enum(['throw', 'warn'])])
|
|
56
|
+
.default('throw');
|
|
57
|
+
const schema = zod
|
|
58
|
+
.object({
|
|
59
|
+
report: zod
|
|
60
|
+
.object({
|
|
61
|
+
console: zod
|
|
62
|
+
.union([
|
|
63
|
+
zod.literal(false),
|
|
64
|
+
zod.object({
|
|
65
|
+
onError: zod.enum(['throw', 'warn']).default('throw'),
|
|
66
|
+
methods: zod
|
|
67
|
+
.array(zod.enum(['log', 'warn', 'error', 'info', 'debug']))
|
|
68
|
+
.default(DEFAULTS.report.console.methods),
|
|
69
|
+
ignore: zod
|
|
70
|
+
.union([
|
|
71
|
+
zod.string(),
|
|
72
|
+
zod.instanceof(RegExp),
|
|
73
|
+
zod.array(zod.union([zod.string(), zod.instanceof(RegExp)])),
|
|
74
|
+
])
|
|
75
|
+
.transform((value) => (Array.isArray(value) ? value : [value]))
|
|
76
|
+
.default([]),
|
|
77
|
+
}),
|
|
78
|
+
])
|
|
79
|
+
.default(DEFAULTS.report.console),
|
|
80
|
+
timers: onError,
|
|
81
|
+
fakeTimers: onError,
|
|
82
|
+
promises: onError,
|
|
83
|
+
})
|
|
84
|
+
.default(DEFAULTS.report),
|
|
85
|
+
verbose: zod.boolean().default(false),
|
|
86
|
+
delayThreshold: zod.int().gte(0).default(0),
|
|
87
|
+
timerIsolation: zod.enum(['afterEach', 'immediate']).default('afterEach'),
|
|
88
|
+
clearTimers: zod.boolean().default(true),
|
|
89
|
+
})
|
|
90
|
+
.default(DEFAULTS);
|
|
91
|
+
function normalizeOptions(raw) {
|
|
92
|
+
try {
|
|
93
|
+
return schema.parse(raw || {});
|
|
43
94
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
onError: rawPromise.onError ?? DEFAULTS.report.promises.onError,
|
|
47
|
-
patch: rawPromise.patch ?? DEFAULTS.report.promises.patch,
|
|
48
|
-
};
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw zod.prettifyError(error);
|
|
49
97
|
}
|
|
50
|
-
return false;
|
|
51
|
-
};
|
|
52
|
-
function normalizeOptions(raw) {
|
|
53
|
-
const report = raw.report ?? {};
|
|
54
|
-
return {
|
|
55
|
-
report: {
|
|
56
|
-
console: normalizeConsole(report.console),
|
|
57
|
-
timers: report.timers ?? DEFAULTS.report.timers,
|
|
58
|
-
fakeTimers: report.fakeTimers ?? DEFAULTS.report.fakeTimers,
|
|
59
|
-
promises: normalizePromise(report.promises),
|
|
60
|
-
},
|
|
61
|
-
verbose: raw.verbose ?? DEFAULTS.verbose,
|
|
62
|
-
delayThreshold: raw.delayThreshold ?? DEFAULTS.delayThreshold,
|
|
63
|
-
timerIsolation: raw.timerIsolation ?? DEFAULTS.timerIsolation,
|
|
64
|
-
clearTimers: raw.clearTimers ?? DEFAULTS.clearTimers,
|
|
65
|
-
};
|
|
66
98
|
}
|
|
67
99
|
exports.default = normalizeOptions;
|
|
@@ -13,8 +13,7 @@ const reportLeaks = (that, leakRecord) => {
|
|
|
13
13
|
leakRecord[property].values().next().value?.stack,
|
|
14
14
|
].join('\n');
|
|
15
15
|
const option = that.options.report[property];
|
|
16
|
-
if (option === 'throw'
|
|
17
|
-
(typeof option === 'object' && option.onError === 'throw')) {
|
|
16
|
+
if (option === 'throw') {
|
|
18
17
|
const error = new Error();
|
|
19
18
|
error.stack = message;
|
|
20
19
|
throw error;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jest-doctor",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "jest environment for leak detection",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Stephan Dum",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"@types/react": "^19.2.8",
|
|
39
39
|
"@types/react-dom": "^19.2.3",
|
|
40
40
|
"c8": "^10.1.3",
|
|
41
|
-
"cross-env": "^10.1.0",
|
|
42
41
|
"cross-spawn": "^7.0.6",
|
|
43
42
|
"eslint": "^9.39.2",
|
|
44
|
-
"istanbul-lib-report": "^3.0.1",
|
|
45
43
|
"jest": "30.2.0",
|
|
44
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
45
|
+
"jest-environment-node": "^30.2.0",
|
|
46
46
|
"memfs": "^4.52.0",
|
|
47
47
|
"nyc": "^17.1.0",
|
|
48
48
|
"react": "^19.2.3",
|
|
@@ -63,7 +63,8 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"chalk": "4.1.2"
|
|
66
|
+
"chalk": "4.1.2",
|
|
67
|
+
"zod": "^4.3.5"
|
|
67
68
|
},
|
|
68
69
|
"scripts": {
|
|
69
70
|
"typecheck": "tsc",
|
package/readme.md
CHANGED
|
@@ -40,12 +40,8 @@ The environment can be configured through jest config `testEnvironmentOptions`:
|
|
|
40
40
|
- **report**: an object defining which leaks should be tracked and reported
|
|
41
41
|
- **timers**: `false | 'warn' | 'trow'` (default `throw`) whether normal setTimeout and setInterval should be reported and how
|
|
42
42
|
- **fakeTimers**: `false | 'warn' | 'trow'` (default `throw`) same as timers but for fake api
|
|
43
|
-
- **promises**: `false`
|
|
44
|
-
|
|
45
|
-
- **patch**: `'async_hooks' | 'promise'` (default `async_hooks`) controls how to patch promises
|
|
46
|
-
- **async_hooks**: uses node async_hook API to detect any promise generation, robust solution but with an overhead.
|
|
47
|
-
- **promise**: overwrites the global Promise object which is faster but will not detect: internal promises, async await, native API promises!
|
|
48
|
-
- **console**: `false` or object (default object)
|
|
43
|
+
- **promises**: `false | 'warn' | 'trow'` (default `throw`) indicating if promises should be reported and how
|
|
44
|
+
- **console**: `false` or object (default object)
|
|
49
45
|
- **onError**: `'warn' | 'trow'` (default `throw`) how to handle reporting
|
|
50
46
|
- **methods**: `keyof Console` (default all methods) which console methods should be tracked
|
|
51
47
|
- **ignore**: `string | regexp | Array<string | regexp>` (default: []) allows to excluded console output from tracking
|
|
@@ -67,9 +63,7 @@ export default {
|
|
|
67
63
|
},
|
|
68
64
|
timers: 'warn',
|
|
69
65
|
fakeTimers: 'warn',
|
|
70
|
-
promises:
|
|
71
|
-
onErro: 'warn',
|
|
72
|
-
},
|
|
66
|
+
promises: 'warn',
|
|
73
67
|
},
|
|
74
68
|
delayThreshold: 1000,
|
|
75
69
|
timerIsolation: 'afterEach',
|
|
@@ -100,9 +94,11 @@ Promise.resolve().then(() => {
|
|
|
100
94
|
/* i am not tracked as unresolved */
|
|
101
95
|
});
|
|
102
96
|
```
|
|
103
|
-
-
|
|
97
|
+
- Promise.race and Promise.any can only accept unchained promises, or they will report the chained promise as open.
|
|
104
98
|
```js
|
|
105
|
-
|
|
99
|
+
const p1 = Promise.resolve().then(() => { /* not allowed */});
|
|
100
|
+
const p2 = Promise.resolve();
|
|
101
|
+
await Promise.race([p1, p2]);
|
|
106
102
|
```
|
|
107
103
|
|
|
108
104
|
- console, setTimeout / setInterval can also be imported and will not participate in leak detection in these cases, but this can also serve as exit hatch if needed.
|
package/dist/patch/promise.d.ts
DELETED
package/dist/patch/promise.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const getStack_1 = __importDefault(require("../utils/getStack"));
|
|
7
|
-
const patchPromise = (that) => {
|
|
8
|
-
const OriginalPromise = that.global.Promise;
|
|
9
|
-
class TrackedPromise extends OriginalPromise {
|
|
10
|
-
constructor(executor) {
|
|
11
|
-
let resolveRef;
|
|
12
|
-
let rejectRef;
|
|
13
|
-
super((resolve, reject) => {
|
|
14
|
-
resolveRef = resolve;
|
|
15
|
-
rejectRef = reject;
|
|
16
|
-
});
|
|
17
|
-
const promiseLeaks = that.leakRecords.get(that.currentTestName)?.promises;
|
|
18
|
-
promiseLeaks?.set(this, {
|
|
19
|
-
testName: that.currentTestName,
|
|
20
|
-
stack: (0, getStack_1.default)(that.global.Promise, 'Promise'),
|
|
21
|
-
});
|
|
22
|
-
executor((value) => {
|
|
23
|
-
promiseLeaks?.delete(this);
|
|
24
|
-
resolveRef(value);
|
|
25
|
-
}, (reason) => {
|
|
26
|
-
promiseLeaks?.delete(this);
|
|
27
|
-
rejectRef(reason);
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
Object.assign(Promise, OriginalPromise);
|
|
32
|
-
that.global.Promise = TrackedPromise;
|
|
33
|
-
};
|
|
34
|
-
exports.default = patchPromise;
|
package/dist/patch/race.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
declare const patchRace: () => void;
|
package/dist/patch/race.js
DELETED