UNPKG

5.1 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', {
4 value: true
5});
6exports.default = collectHandles;
7exports.formatHandleErrors = formatHandleErrors;
8
9function asyncHooks() {
10 const data = _interopRequireWildcard(require('async_hooks'));
11
12 asyncHooks = function () {
13 return data;
14 };
15
16 return data;
17}
18
19function _jestMessageUtil() {
20 const data = require('jest-message-util');
21
22 _jestMessageUtil = function () {
23 return data;
24 };
25
26 return data;
27}
28
29function _jestUtil() {
30 const data = require('jest-util');
31
32 _jestUtil = function () {
33 return data;
34 };
35
36 return data;
37}
38
39function _stripAnsi() {
40 const data = _interopRequireDefault(require('strip-ansi'));
41
42 _stripAnsi = function () {
43 return data;
44 };
45
46 return data;
47}
48
49function _interopRequireDefault(obj) {
50 return obj && obj.__esModule ? obj : {default: obj};
51}
52
53function _getRequireWildcardCache() {
54 if (typeof WeakMap !== 'function') return null;
55 var cache = new WeakMap();
56 _getRequireWildcardCache = function () {
57 return cache;
58 };
59 return cache;
60}
61
62function _interopRequireWildcard(obj) {
63 if (obj && obj.__esModule) {
64 return obj;
65 }
66 if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
67 return {default: obj};
68 }
69 var cache = _getRequireWildcardCache();
70 if (cache && cache.has(obj)) {
71 return cache.get(obj);
72 }
73 var newObj = {};
74 var hasPropertyDescriptor =
75 Object.defineProperty && Object.getOwnPropertyDescriptor;
76 for (var key in obj) {
77 if (Object.prototype.hasOwnProperty.call(obj, key)) {
78 var desc = hasPropertyDescriptor
79 ? Object.getOwnPropertyDescriptor(obj, key)
80 : null;
81 if (desc && (desc.get || desc.set)) {
82 Object.defineProperty(newObj, key, desc);
83 } else {
84 newObj[key] = obj[key];
85 }
86 }
87 }
88 newObj.default = obj;
89 if (cache) {
90 cache.set(obj, newObj);
91 }
92 return newObj;
93}
94
95/**
96 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
97 *
98 * This source code is licensed under the MIT license found in the
99 * LICENSE file in the root directory of this source tree.
100 */
101function stackIsFromUser(stack) {
102 // Either the test file, or something required by it
103 if (stack.includes('Runtime.requireModule')) {
104 return true;
105 } // jest-jasmine it or describe call
106
107 if (stack.includes('asyncJestTest') || stack.includes('asyncJestLifecycle')) {
108 return true;
109 } // An async function call from within circus
110
111 if (stack.includes('callAsyncCircusFn')) {
112 // jest-circus it or describe call
113 return (
114 stack.includes('_callCircusTest') || stack.includes('_callCircusHook')
115 );
116 }
117
118 return false;
119}
120
121const alwaysActive = () => true; // Inspired by https://github.com/mafintosh/why-is-node-running/blob/master/index.js
122// Extracted as we want to format the result ourselves
123
124function collectHandles() {
125 const activeHandles = new Map();
126 const hook = asyncHooks().createHook({
127 destroy(asyncId) {
128 activeHandles.delete(asyncId);
129 },
130
131 init: function initHook(asyncId, type, _triggerAsyncId, resource) {
132 if (type === 'PROMISE' || type === 'TIMERWRAP') {
133 return;
134 }
135
136 const error = new (_jestUtil().ErrorWithStack)(type, initHook);
137
138 if (stackIsFromUser(error.stack || '')) {
139 let isActive;
140
141 if (type === 'Timeout' || type === 'Immediate') {
142 if ('hasRef' in resource) {
143 // Timer that supports hasRef (Node v11+)
144 // @ts-expect-error: doesn't exist in v10 typings
145 isActive = resource.hasRef.bind(resource);
146 } else {
147 // Timer that doesn't support hasRef
148 isActive = alwaysActive;
149 }
150 } else {
151 // Any other async resource
152 isActive = alwaysActive;
153 }
154
155 activeHandles.set(asyncId, {
156 error,
157 isActive
158 });
159 }
160 }
161 });
162 hook.enable();
163 return () => {
164 hook.disable(); // Get errors for every async resource still referenced at this moment
165
166 const result = Array.from(activeHandles.values())
167 .filter(({isActive}) => isActive())
168 .map(({error}) => error);
169 activeHandles.clear();
170 return result;
171 };
172}
173
174function formatHandleErrors(errors, config) {
175 const stacks = new Set();
176 return (
177 errors
178 .map(err =>
179 (0, _jestMessageUtil().formatExecError)(
180 err,
181 config,
182 {
183 noStackTrace: false
184 },
185 undefined,
186 true
187 )
188 ) // E.g. timeouts might give multiple traces to the same line of code
189 // This hairy filtering tries to remove entries with duplicate stack traces
190 .filter(handle => {
191 const ansiFree = (0, _stripAnsi().default)(handle);
192 const match = ansiFree.match(/\s+at(.*)/);
193
194 if (!match || match.length < 2) {
195 return true;
196 }
197
198 const stack = ansiFree.substr(ansiFree.indexOf(match[1])).trim();
199
200 if (stacks.has(stack)) {
201 return false;
202 }
203
204 stacks.add(stack);
205 return true;
206 })
207 );
208}