run_test.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. // Keeping the core of "runTest" as a separate function (as "runTestInternal")
  6. // is key to be able to detect memory leaks. Since all variables are local to
  7. // the function, when "runTestInternal" finishes its execution, they can all be
  8. // freed, UNLESS something else is leaking them (and that's why we can detect
  9. // the leak!).
  10. //
  11. // If we had all the code in a single function, we should manually nullify all
  12. // references to verify if there is a leak, which is not maintainable and error
  13. // prone. That's why "runTestInternal" CANNOT be inlined inside "runTest".
  14. let runTestInternal = (() => {
  15. var _ref = _asyncToGenerator(function*(path, globalConfig, config, resolver) {
  16. const testSource = (_gracefulFs || _load_gracefulFs()).default.readFileSync(
  17. path,
  18. 'utf8'
  19. );
  20. const parsedDocblock = (_jestDocblock || _load_jestDocblock()).parse(
  21. (_jestDocblock || _load_jestDocblock()).extract(testSource)
  22. );
  23. const customEnvironment = parsedDocblock['jest-environment'];
  24. let testEnvironment = config.testEnvironment;
  25. if (customEnvironment) {
  26. testEnvironment = (0,
  27. (_jestConfig || _load_jestConfig()).getTestEnvironment)(
  28. Object.assign({}, config, {
  29. testEnvironment: customEnvironment
  30. })
  31. );
  32. }
  33. /* $FlowFixMe */
  34. const TestEnvironment = require(testEnvironment);
  35. const testFramework =
  36. process.env.JEST_CIRCUS === '1'
  37. ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies
  38. : /* $FlowFixMe */
  39. require(config.testRunner);
  40. /* $FlowFixMe */
  41. const Runtime = require(config.moduleLoader || 'jest-runtime');
  42. let runtime = undefined;
  43. const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout;
  44. const consoleFormatter = function(type, message) {
  45. return (0, (_jestUtil || _load_jestUtil()).getConsoleOutput)(
  46. config.cwd,
  47. !!globalConfig.verbose,
  48. // 4 = the console call is buried 4 stack frames deep
  49. (_jestUtil || _load_jestUtil()).BufferedConsole.write(
  50. [],
  51. type,
  52. message,
  53. 4,
  54. runtime && runtime.getSourceMaps()
  55. )
  56. );
  57. };
  58. let testConsole;
  59. if (globalConfig.silent) {
  60. testConsole = new (_jestUtil || _load_jestUtil()).NullConsole(
  61. consoleOut,
  62. process.stderr,
  63. consoleFormatter
  64. );
  65. } else if (globalConfig.verbose) {
  66. testConsole = new (_jestUtil || _load_jestUtil()).Console(
  67. consoleOut,
  68. process.stderr,
  69. consoleFormatter
  70. );
  71. } else {
  72. testConsole = new (_jestUtil || _load_jestUtil()).BufferedConsole(
  73. function() {
  74. return runtime && runtime.getSourceMaps();
  75. }
  76. );
  77. }
  78. const environment = new TestEnvironment(config, {console: testConsole});
  79. const leakDetector = config.detectLeaks
  80. ? new (_jestLeakDetector || _load_jestLeakDetector()).default(environment)
  81. : null;
  82. const cacheFS = {[path]: testSource};
  83. (0,
  84. (_jestUtil || _load_jestUtil())
  85. .setGlobal)(environment.global, 'console', testConsole);
  86. runtime = new Runtime(config, environment, resolver, cacheFS, {
  87. collectCoverage: globalConfig.collectCoverage,
  88. collectCoverageFrom: globalConfig.collectCoverageFrom,
  89. collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom
  90. });
  91. const start = Date.now();
  92. const sourcemapOptions = {
  93. environment: 'node',
  94. handleUncaughtExceptions: false,
  95. retrieveSourceMap: function(source) {
  96. const sourceMaps = runtime && runtime.getSourceMaps();
  97. const sourceMapSource = sourceMaps && sourceMaps[source];
  98. if (sourceMapSource) {
  99. try {
  100. return {
  101. map: JSON.parse(
  102. (_gracefulFs || _load_gracefulFs()).default.readFileSync(
  103. sourceMapSource
  104. )
  105. ),
  106. url: source
  107. };
  108. } catch (e) {}
  109. }
  110. return null;
  111. }
  112. };
  113. // For tests
  114. runtime
  115. .requireInternalModule(
  116. require.resolve('source-map-support'),
  117. 'source-map-support'
  118. )
  119. .install(sourcemapOptions);
  120. // For runtime errors
  121. (_sourceMapSupport || _load_sourceMapSupport()).default.install(
  122. sourcemapOptions
  123. );
  124. if (
  125. environment.global &&
  126. environment.global.process &&
  127. environment.global.process.exit
  128. ) {
  129. const realExit = environment.global.process.exit;
  130. environment.global.process.exit = function exit() {
  131. for (
  132. var _len = arguments.length, args = Array(_len), _key = 0;
  133. _key < _len;
  134. _key++
  135. ) {
  136. args[_key] = arguments[_key];
  137. }
  138. const error = new Error(
  139. `process.exit called with "${args.join(', ')}"`
  140. );
  141. if (Error.captureStackTrace) {
  142. Error.captureStackTrace(error, exit);
  143. }
  144. const formattedError = (0,
  145. (_jestMessageUtil || _load_jestMessageUtil()).formatExecError)(
  146. error,
  147. config,
  148. {noStackTrace: false},
  149. undefined,
  150. true
  151. );
  152. process.stderr.write(formattedError);
  153. return realExit.apply(undefined, args);
  154. };
  155. }
  156. try {
  157. yield environment.setup();
  158. let result;
  159. try {
  160. result = yield testFramework(
  161. globalConfig,
  162. config,
  163. environment,
  164. runtime,
  165. path
  166. );
  167. } catch (err) {
  168. // Access stack before uninstalling sourcemaps
  169. err.stack;
  170. throw err;
  171. }
  172. const testCount =
  173. result.numPassingTests +
  174. result.numFailingTests +
  175. result.numPendingTests;
  176. result.perfStats = {end: Date.now(), start: start};
  177. result.testFilePath = path;
  178. result.coverage = runtime.getAllCoverageInfoCopy();
  179. result.sourceMaps = runtime.getSourceMapInfo(
  180. new Set(Object.keys(result.coverage || {}))
  181. );
  182. result.console = testConsole.getBuffer();
  183. result.skipped = testCount === result.numPendingTests;
  184. result.displayName = config.displayName;
  185. if (globalConfig.logHeapUsage) {
  186. if (global.gc) {
  187. global.gc();
  188. }
  189. result.memoryUsage = process.memoryUsage().heapUsed;
  190. }
  191. // Delay the resolution to allow log messages to be output.
  192. return new Promise(function(resolve) {
  193. setImmediate(function() {
  194. return resolve({leakDetector: leakDetector, result: result});
  195. });
  196. });
  197. } finally {
  198. yield environment.teardown();
  199. (
  200. _sourceMapSupport || _load_sourceMapSupport()
  201. ).default.resetRetrieveHandlers();
  202. }
  203. });
  204. return function runTestInternal(_x, _x2, _x3, _x4) {
  205. return _ref.apply(this, arguments);
  206. };
  207. })();
  208. var _gracefulFs;
  209. function _load_gracefulFs() {
  210. return (_gracefulFs = _interopRequireDefault(require('graceful-fs')));
  211. }
  212. var _jestUtil;
  213. function _load_jestUtil() {
  214. return (_jestUtil = require('jest-util'));
  215. }
  216. var _jestLeakDetector;
  217. function _load_jestLeakDetector() {
  218. return (_jestLeakDetector = _interopRequireDefault(
  219. require('jest-leak-detector')
  220. ));
  221. }
  222. var _jestConfig;
  223. function _load_jestConfig() {
  224. return (_jestConfig = require('jest-config'));
  225. }
  226. var _jestDocblock;
  227. function _load_jestDocblock() {
  228. return (_jestDocblock = _interopRequireWildcard(require('jest-docblock')));
  229. }
  230. var _jestMessageUtil;
  231. function _load_jestMessageUtil() {
  232. return (_jestMessageUtil = require('jest-message-util'));
  233. }
  234. var _sourceMapSupport;
  235. function _load_sourceMapSupport() {
  236. return (_sourceMapSupport = _interopRequireDefault(
  237. require('source-map-support')
  238. ));
  239. }
  240. function _interopRequireWildcard(obj) {
  241. if (obj && obj.__esModule) {
  242. return obj;
  243. } else {
  244. var newObj = {};
  245. if (obj != null) {
  246. for (var key in obj) {
  247. if (Object.prototype.hasOwnProperty.call(obj, key))
  248. newObj[key] = obj[key];
  249. }
  250. }
  251. newObj.default = obj;
  252. return newObj;
  253. }
  254. }
  255. function _interopRequireDefault(obj) {
  256. return obj && obj.__esModule ? obj : {default: obj};
  257. }
  258. function _asyncToGenerator(fn) {
  259. return function() {
  260. var gen = fn.apply(this, arguments);
  261. return new Promise(function(resolve, reject) {
  262. function step(key, arg) {
  263. try {
  264. var info = gen[key](arg);
  265. var value = info.value;
  266. } catch (error) {
  267. reject(error);
  268. return;
  269. }
  270. if (info.done) {
  271. resolve(value);
  272. } else {
  273. return Promise.resolve(value).then(
  274. function(value) {
  275. step('next', value);
  276. },
  277. function(err) {
  278. step('throw', err);
  279. }
  280. );
  281. }
  282. }
  283. return step('next');
  284. });
  285. };
  286. }
  287. /**
  288. * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
  289. *
  290. * This source code is licensed under the MIT license found in the
  291. * LICENSE file in the root directory of this source tree.
  292. *
  293. *
  294. */
  295. exports.default = (() => {
  296. var _ref2 = _asyncToGenerator(function*(
  297. path,
  298. globalConfig,
  299. config,
  300. resolver
  301. ) {
  302. var _ref3 = yield runTestInternal(path, globalConfig, config, resolver);
  303. const leakDetector = _ref3.leakDetector,
  304. result = _ref3.result;
  305. // Resolve leak detector, outside the "runTestInternal" closure.
  306. result.leaks = leakDetector ? leakDetector.isLeaking() : false;
  307. return result;
  308. });
  309. function runTest(_x5, _x6, _x7, _x8) {
  310. return _ref2.apply(this, arguments);
  311. }
  312. return runTest;
  313. })();