summary_reporter.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. function _chalk() {
  7. const data = _interopRequireDefault(require('chalk'));
  8. _chalk = function _chalk() {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _jestUtil() {
  14. const data = require('jest-util');
  15. _jestUtil = function _jestUtil() {
  16. return data;
  17. };
  18. return data;
  19. }
  20. var _base_reporter = _interopRequireDefault(require('./base_reporter'));
  21. var _utils = require('./utils');
  22. var _get_result_header = _interopRequireDefault(require('./get_result_header'));
  23. var _get_snapshot_summary = _interopRequireDefault(
  24. require('./get_snapshot_summary')
  25. );
  26. function _interopRequireDefault(obj) {
  27. return obj && obj.__esModule ? obj : {default: obj};
  28. }
  29. function _defineProperty(obj, key, value) {
  30. if (key in obj) {
  31. Object.defineProperty(obj, key, {
  32. value: value,
  33. enumerable: true,
  34. configurable: true,
  35. writable: true
  36. });
  37. } else {
  38. obj[key] = value;
  39. }
  40. return obj;
  41. }
  42. const TEST_SUMMARY_THRESHOLD = 20;
  43. const NPM_EVENTS = new Set([
  44. 'prepublish',
  45. 'publish',
  46. 'postpublish',
  47. 'preinstall',
  48. 'install',
  49. 'postinstall',
  50. 'preuninstall',
  51. 'uninstall',
  52. 'postuninstall',
  53. 'preversion',
  54. 'version',
  55. 'postversion',
  56. 'pretest',
  57. 'test',
  58. 'posttest',
  59. 'prestop',
  60. 'stop',
  61. 'poststop',
  62. 'prestart',
  63. 'start',
  64. 'poststart',
  65. 'prerestart',
  66. 'restart',
  67. 'postrestart'
  68. ]);
  69. const _process$env = process.env,
  70. npm_config_user_agent = _process$env.npm_config_user_agent,
  71. npm_lifecycle_event = _process$env.npm_lifecycle_event,
  72. npm_lifecycle_script = _process$env.npm_lifecycle_script;
  73. class SummaryReporter extends _base_reporter.default {
  74. constructor(globalConfig) {
  75. super();
  76. _defineProperty(this, '_estimatedTime', void 0);
  77. _defineProperty(this, '_globalConfig', void 0);
  78. this._globalConfig = globalConfig;
  79. this._estimatedTime = 0;
  80. } // If we write more than one character at a time it is possible that
  81. // Node.js exits in the middle of printing the result. This was first observed
  82. // in Node.js 0.10 and still persists in Node.js 6.7+.
  83. // Let's print the test failure summary character by character which is safer
  84. // when hundreds of tests are failing.
  85. _write(string) {
  86. for (let i = 0; i < string.length; i++) {
  87. process.stderr.write(string.charAt(i));
  88. }
  89. }
  90. onRunStart(aggregatedResults, options) {
  91. super.onRunStart(aggregatedResults, options);
  92. this._estimatedTime = options.estimatedTime;
  93. }
  94. onRunComplete(contexts, aggregatedResults) {
  95. const numTotalTestSuites = aggregatedResults.numTotalTestSuites,
  96. testResults = aggregatedResults.testResults,
  97. wasInterrupted = aggregatedResults.wasInterrupted;
  98. if (numTotalTestSuites) {
  99. const lastResult = testResults[testResults.length - 1]; // Print a newline if the last test did not fail to line up newlines
  100. // similar to when an error would have been thrown in the test.
  101. if (
  102. !this._globalConfig.verbose &&
  103. lastResult &&
  104. !lastResult.numFailingTests &&
  105. !lastResult.testExecError
  106. ) {
  107. this.log('');
  108. }
  109. this._printSummary(aggregatedResults, this._globalConfig);
  110. this._printSnapshotSummary(
  111. aggregatedResults.snapshot,
  112. this._globalConfig
  113. );
  114. if (numTotalTestSuites) {
  115. let message = (0, _utils.getSummary)(aggregatedResults, {
  116. estimatedTime: this._estimatedTime
  117. });
  118. if (!this._globalConfig.silent) {
  119. message +=
  120. '\n' +
  121. (wasInterrupted
  122. ? _chalk().default.bold.red('Test run was interrupted.')
  123. : this._getTestSummary(contexts, this._globalConfig));
  124. }
  125. this.log(message);
  126. }
  127. }
  128. }
  129. _printSnapshotSummary(snapshots, globalConfig) {
  130. if (
  131. snapshots.added ||
  132. snapshots.filesRemoved ||
  133. snapshots.unchecked ||
  134. snapshots.unmatched ||
  135. snapshots.updated
  136. ) {
  137. let updateCommand;
  138. const event = npm_lifecycle_event || '';
  139. const prefix = NPM_EVENTS.has(event) ? '' : 'run ';
  140. const isYarn =
  141. typeof npm_config_user_agent === 'string' &&
  142. npm_config_user_agent.includes('yarn');
  143. const client = isYarn ? 'yarn' : 'npm';
  144. const scriptUsesJest =
  145. typeof npm_lifecycle_script === 'string' &&
  146. npm_lifecycle_script.includes('jest');
  147. if (globalConfig.watch || globalConfig.watchAll) {
  148. updateCommand = 'press `u`';
  149. } else if (event && scriptUsesJest) {
  150. updateCommand = `run \`${client +
  151. ' ' +
  152. prefix +
  153. event +
  154. (isYarn ? '' : ' --')} -u\``;
  155. } else {
  156. updateCommand = 're-run jest with `-u`';
  157. }
  158. const snapshotSummary = (0, _get_snapshot_summary.default)(
  159. snapshots,
  160. globalConfig,
  161. updateCommand
  162. );
  163. snapshotSummary.forEach(this.log);
  164. this.log(''); // print empty line
  165. }
  166. }
  167. _printSummary(aggregatedResults, globalConfig) {
  168. // If there were any failing tests and there was a large number of tests
  169. // executed, re-print the failing results at the end of execution output.
  170. const failedTests = aggregatedResults.numFailedTests;
  171. const runtimeErrors = aggregatedResults.numRuntimeErrorTestSuites;
  172. if (
  173. failedTests + runtimeErrors > 0 &&
  174. aggregatedResults.numTotalTestSuites > TEST_SUMMARY_THRESHOLD
  175. ) {
  176. this.log(_chalk().default.bold('Summary of all failing tests'));
  177. aggregatedResults.testResults.forEach(testResult => {
  178. const failureMessage = testResult.failureMessage;
  179. if (failureMessage) {
  180. this._write(
  181. (0, _get_result_header.default)(testResult, globalConfig) +
  182. '\n' +
  183. failureMessage +
  184. '\n'
  185. );
  186. }
  187. });
  188. this.log(''); // print empty line
  189. }
  190. }
  191. _getTestSummary(contexts, globalConfig) {
  192. const getMatchingTestsInfo = () => {
  193. const prefix = globalConfig.findRelatedTests
  194. ? ' related to files matching '
  195. : ' matching ';
  196. return (
  197. _chalk().default.dim(prefix) +
  198. (0, _jestUtil().testPathPatternToRegExp)(
  199. globalConfig.testPathPattern
  200. ).toString()
  201. );
  202. };
  203. let testInfo = '';
  204. if (globalConfig.runTestsByPath) {
  205. testInfo = _chalk().default.dim(' within paths');
  206. } else if (globalConfig.onlyChanged) {
  207. testInfo = _chalk().default.dim(' related to changed files');
  208. } else if (globalConfig.testPathPattern) {
  209. testInfo = getMatchingTestsInfo();
  210. }
  211. let nameInfo = '';
  212. if (globalConfig.runTestsByPath) {
  213. nameInfo = ' ' + globalConfig.nonFlagArgs.map(p => `"${p}"`).join(', ');
  214. } else if (globalConfig.testNamePattern) {
  215. nameInfo =
  216. _chalk().default.dim(' with tests matching ') +
  217. `"${globalConfig.testNamePattern}"`;
  218. }
  219. const contextInfo =
  220. contexts.size > 1
  221. ? _chalk().default.dim(' in ') +
  222. contexts.size +
  223. _chalk().default.dim(' projects')
  224. : '';
  225. return (
  226. _chalk().default.dim('Ran all test suites') +
  227. testInfo +
  228. nameInfo +
  229. contextInfo +
  230. _chalk().default.dim('.')
  231. );
  232. }
  233. }
  234. exports.default = SummaryReporter;