diff --git a/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap b/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap index a39921bd1894..4cf7e417890e 100644 --- a/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap +++ b/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.js.snap @@ -22,6 +22,22 @@ exports[`formatStackTrace should strip node internals 1`] = ` " `; +exports[`retains message in babel code frame error 1`] = ` +" Babel test + + + packages/react/src/forwardRef.js: Unexpected token, expected , (20:10) + + 18 | false, + 19 | 'forwardRef requires a render function but received a \`memo\` ' + > 20 | 'component. Instead of forwardRef(memo(...)), use ' + + | ^ + 21 | 'memo(forwardRef(...)).', + 22 | ); + 23 | } else if (typeof render !== 'function') { +" +`; + exports[`should exclude jasmine from stack trace for Unix paths. 1`] = ` " Unix test diff --git a/packages/jest-message-util/src/__tests__/messages.test.js b/packages/jest-message-util/src/__tests__/messages.test.js index 6f8c9964e0c6..0a2078ca299c 100644 --- a/packages/jest-message-util/src/__tests__/messages.test.js +++ b/packages/jest-message-util/src/__tests__/messages.test.js @@ -58,6 +58,19 @@ const vendorStack = at Object.asyncFn (__tests__/vendor/sulu/node_modules/sulu-content-bundle/best_component.js:1:5) `; +const babelStack = + ' ' + + ` + packages/react/src/forwardRef.js: Unexpected token, expected , (20:10) + \u001b[0m \u001b[90m 18 | \u001b[39m \u001b[36mfalse\u001b[39m\u001b[33m,\u001b[39m + \u001b[90m 19 | \u001b[39m \u001b[32m'forwardRef requires a render function but received a \`memo\` '\u001b[39m + \u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 20 | \u001b[39m \u001b[32m'component. Instead of forwardRef(memo(...)), use '\u001b[39m \u001b[33m+\u001b[39m + \u001b[90m | \u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m + \u001b[90m 21 | \u001b[39m \u001b[32m'memo(forwardRef(...)).'\u001b[39m\u001b[33m,\u001b[39m + \u001b[90m 22 | \u001b[39m )\u001b[33m;\u001b[39m + \u001b[90m 23 | \u001b[39m } \u001b[36melse\u001b[39m \u001b[36mif\u001b[39m (\u001b[36mtypeof\u001b[39m render \u001b[33m!==\u001b[39m \u001b[32m'function'\u001b[39m) {\u001b[0m +`; + it('should exclude jasmine from stack trace for Unix paths.', () => { const messages = formatResultsErrors( [ @@ -134,3 +147,23 @@ it('should not exclude vendor from stack trace', () => { expect(messages).toMatchSnapshot(); }); + +it('retains message in babel code frame error', () => { + const messages = formatResultsErrors( + [ + { + ancestorTitles: [], + failureMessages: [babelStack], + title: 'Babel test', + }, + ], + { + rootDir: '', + }, + { + noStackTrace: false, + }, + ); + + expect(messages).toMatchSnapshot(); +}); diff --git a/packages/jest-message-util/src/index.js b/packages/jest-message-util/src/index.js index 1f8f4d5f62ba..717e1861a8ff 100644 --- a/packages/jest-message-util/src/index.js +++ b/packages/jest-message-util/src/index.js @@ -62,7 +62,6 @@ const TITLE_BULLET = chalk.bold('\u25cf '); const STACK_TRACE_COLOR = chalk.dim; const STACK_PATH_REGEXP = /\s*at.*\(?(\:\d*\:\d*|native)\)?/; const EXEC_ERROR_MESSAGE = 'Test suite failed to run'; -const ERROR_TEXT = 'Error: '; const NOT_EMPTY_LINE_REGEXP = /^(?!$)/gm; const indentAllLines = (lines: string, indent: string) => @@ -335,13 +334,14 @@ export const separateMessageFromStack = (content: string) => { return {message: '', stack: ''}; } - const messageMatch = content.match(/(^(.|\n)*?(?=\n\s*at\s.*\:\d*\:\d*))/); - let message = messageMatch ? messageMatch[0] : 'Error'; - const stack = messageMatch ? content.slice(message.length) : content; - // If the error is a plain error instead of a SyntaxError or TypeError - // we remove it from the message because it is generally not useful. - if (message.startsWith(ERROR_TEXT)) { - message = message.substr(ERROR_TEXT.length); - } + // All lines up to what looks like a stack -- or if nothing looks like a stack + // (maybe it's a code frame instead), just the first non-empty line. + // If the error is a plain "Error:" instead of a SyntaxError or TypeError we + // remove the prefix from the message because it is generally not useful. + const messageMatch = content.match( + /^(?:Error: )?([\s\S]*?(?=\n\s*at\s.*\:\d*\:\d*)|\s*.*)([\s\S]*)$/ + ); + const message = messageMatch[1]; + const stack = messageMatch[2]; return {message, stack}; };