UNPKG

5.04 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 isActive = resource.hasRef.bind(resource);
145 } else {
146 // Timer that doesn't support hasRef
147 isActive = alwaysActive;
148 }
149 } else {
150 // Any other async resource
151 isActive = alwaysActive;
152 }
153
154 activeHandles.set(asyncId, {
155 error,
156 isActive
157 });
158 }
159 }
160 });
161 hook.enable();
162 return () => {
163 hook.disable(); // Get errors for every async resource still referenced at this moment
164
165 const result = Array.from(activeHandles.values())
166 .filter(({isActive}) => isActive())
167 .map(({error}) => error);
168 activeHandles.clear();
169 return result;
170 };
171}
172
173function formatHandleErrors(errors, config) {
174 const stacks = new Set();
175 return (
176 errors
177 .map(err =>
178 (0, _jestMessageUtil().formatExecError)(
179 err,
180 config,
181 {
182 noStackTrace: false
183 },
184 undefined,
185 true
186 )
187 ) // E.g. timeouts might give multiple traces to the same line of code
188 // This hairy filtering tries to remove entries with duplicate stack traces
189 .filter(handle => {
190 const ansiFree = (0, _stripAnsi().default)(handle);
191 const match = ansiFree.match(/\s+at(.*)/);
192
193 if (!match || match.length < 2) {
194 return true;
195 }
196
197 const stack = ansiFree.substr(ansiFree.indexOf(match[1])).trim();
198
199 if (stacks.has(stack)) {
200 return false;
201 }
202
203 stacks.add(stack);
204 return true;
205 })
206 );
207}