formatNodeAssertErrors.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _assert = require('assert');
  7. var _chalk = _interopRequireDefault(require('chalk'));
  8. var _jestMatcherUtils = require('jest-matcher-utils');
  9. var _prettyFormat = require('pretty-format');
  10. function _interopRequireDefault(obj) {
  11. return obj && obj.__esModule ? obj : {default: obj};
  12. }
  13. /**
  14. * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  15. *
  16. * This source code is licensed under the MIT license found in the
  17. * LICENSE file in the root directory of this source tree.
  18. */
  19. const assertOperatorsMap = {
  20. '!=': 'notEqual',
  21. '!==': 'notStrictEqual',
  22. '==': 'equal',
  23. '===': 'strictEqual'
  24. };
  25. const humanReadableOperators = {
  26. deepEqual: 'to deeply equal',
  27. deepStrictEqual: 'to deeply and strictly equal',
  28. equal: 'to be equal',
  29. notDeepEqual: 'not to deeply equal',
  30. notDeepStrictEqual: 'not to deeply and strictly equal',
  31. notEqual: 'to not be equal',
  32. notStrictEqual: 'not be strictly equal',
  33. strictEqual: 'to strictly be equal'
  34. };
  35. const formatNodeAssertErrors = (event, state) => {
  36. if (event.name === 'test_done') {
  37. event.test.errors = event.test.errors.map(errors => {
  38. let error;
  39. if (Array.isArray(errors)) {
  40. const [originalError, asyncError] = errors;
  41. if (originalError == null) {
  42. error = asyncError;
  43. } else if (!originalError.stack) {
  44. error = asyncError;
  45. error.message = originalError.message
  46. ? originalError.message
  47. : `thrown: ${(0, _prettyFormat.format)(originalError, {
  48. maxDepth: 3
  49. })}`;
  50. } else {
  51. error = originalError;
  52. }
  53. } else {
  54. error = errors;
  55. }
  56. return isAssertionError(error)
  57. ? {
  58. message: assertionErrorMessage(error, {
  59. expand: state.expand
  60. })
  61. }
  62. : errors;
  63. });
  64. }
  65. };
  66. const getOperatorName = (operator, stack) => {
  67. if (typeof operator === 'string') {
  68. return assertOperatorsMap[operator] || operator;
  69. }
  70. if (stack.match('.doesNotThrow')) {
  71. return 'doesNotThrow';
  72. }
  73. if (stack.match('.throws')) {
  74. return 'throws';
  75. } // this fallback is only needed for versions older than node 10
  76. if (stack.match('.fail')) {
  77. return 'fail';
  78. }
  79. return '';
  80. };
  81. const operatorMessage = operator => {
  82. const niceOperatorName = getOperatorName(operator, '');
  83. const humanReadableOperator = humanReadableOperators[niceOperatorName];
  84. return typeof operator === 'string'
  85. ? `${humanReadableOperator || niceOperatorName} to:\n`
  86. : '';
  87. };
  88. const assertThrowingMatcherHint = operatorName =>
  89. operatorName
  90. ? _chalk.default.dim('assert') +
  91. _chalk.default.dim('.' + operatorName + '(') +
  92. _chalk.default.red('function') +
  93. _chalk.default.dim(')')
  94. : '';
  95. const assertMatcherHint = (operator, operatorName, expected) => {
  96. let message = '';
  97. if (operator === '==' && expected === true) {
  98. message =
  99. _chalk.default.dim('assert') +
  100. _chalk.default.dim('(') +
  101. _chalk.default.red('received') +
  102. _chalk.default.dim(')');
  103. } else if (operatorName) {
  104. message =
  105. _chalk.default.dim('assert') +
  106. _chalk.default.dim('.' + operatorName + '(') +
  107. _chalk.default.red('received') +
  108. _chalk.default.dim(', ') +
  109. _chalk.default.green('expected') +
  110. _chalk.default.dim(')');
  111. }
  112. return message;
  113. };
  114. function assertionErrorMessage(error, options) {
  115. const {expected, actual, generatedMessage, message, operator, stack} = error;
  116. const diffString = (0, _jestMatcherUtils.diff)(expected, actual, options);
  117. const hasCustomMessage = !generatedMessage;
  118. const operatorName = getOperatorName(operator, stack);
  119. const trimmedStack = stack
  120. .replace(message, '')
  121. .replace(/AssertionError(.*)/g, '');
  122. if (operatorName === 'doesNotThrow') {
  123. return (
  124. buildHintString(assertThrowingMatcherHint(operatorName)) +
  125. _chalk.default.reset('Expected the function not to throw an error.\n') +
  126. _chalk.default.reset('Instead, it threw:\n') +
  127. ` ${(0, _jestMatcherUtils.printReceived)(actual)}` +
  128. _chalk.default.reset(
  129. hasCustomMessage ? '\n\nMessage:\n ' + message : ''
  130. ) +
  131. trimmedStack
  132. );
  133. }
  134. if (operatorName === 'throws') {
  135. return (
  136. buildHintString(assertThrowingMatcherHint(operatorName)) +
  137. _chalk.default.reset('Expected the function to throw an error.\n') +
  138. _chalk.default.reset("But it didn't throw anything.") +
  139. _chalk.default.reset(
  140. hasCustomMessage ? '\n\nMessage:\n ' + message : ''
  141. ) +
  142. trimmedStack
  143. );
  144. }
  145. if (operatorName === 'fail') {
  146. return (
  147. buildHintString(assertMatcherHint(operator, operatorName, expected)) +
  148. _chalk.default.reset(hasCustomMessage ? 'Message:\n ' + message : '') +
  149. trimmedStack
  150. );
  151. }
  152. return (
  153. buildHintString(assertMatcherHint(operator, operatorName, expected)) +
  154. _chalk.default.reset(`Expected value ${operatorMessage(operator)}`) +
  155. ` ${(0, _jestMatcherUtils.printExpected)(expected)}\n` +
  156. _chalk.default.reset('Received:\n') +
  157. ` ${(0, _jestMatcherUtils.printReceived)(actual)}` +
  158. _chalk.default.reset(hasCustomMessage ? '\n\nMessage:\n ' + message : '') +
  159. (diffString ? `\n\nDifference:\n\n${diffString}` : '') +
  160. trimmedStack
  161. );
  162. }
  163. function isAssertionError(error) {
  164. return (
  165. error &&
  166. (error instanceof _assert.AssertionError ||
  167. error.name === _assert.AssertionError.name ||
  168. error.code === 'ERR_ASSERTION')
  169. );
  170. }
  171. function buildHintString(hint) {
  172. return hint ? hint + '\n\n' : '';
  173. }
  174. var _default = formatNodeAssertErrors;
  175. exports.default = _default;