Skip to content

Commit

Permalink
Codeframe fixes (#5094)
Browse files Browse the repository at this point in the history
* fix(jest-message-util): handle expectation being in another file from the test

* fix(jest-message-util): exclude codeframes from node_modules

* style: flow fixes

* test: update snapshots

* fix(jest-message-util): don't try to read relative paths

* fix(jest-message-util): strip `next (native)` from stack

* fix(jest-message-util): don't try to read non-existent files

Also fix integration test which worked differently depending on if the
test had been run before or not

* fix(jest-message-util): make sure the frame chosen has a filename in it
  • Loading branch information
SimenB authored and cpojer committed Dec 17, 2017
1 parent 2e9feaf commit fb10f7a
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 17 deletions.
53 changes: 53 additions & 0 deletions integration_tests/__tests__/__snapshots__/failures.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,59 @@ exports[`not throwing Error objects 4`] = `
"
`;
exports[`works with assertions in separate files 1`] = `
"FAIL __tests__/test_macro.test.js
✕ use some imported macro to make assertion
● use some imported macro to make assertion
expect(received).toEqual(expected)
Expected value to equal:
2
Received:
1
10 |
11 | module.exports = (one: any, two: any) => {
> 12 | expect(one).toEqual(two);
13 | };
14 |
at macros.js:12:15
at __tests__/test_macro.test.js:14:3
"
`;
exports[`works with async failures 1`] = `
"FAIL __tests__/async_failures.test.js
✕ something async
● something async
expect(received).toEqual(expected)
Expected value to equal:
{\\"baz\\": \\"bar\\"}
Received:
{\\"foo\\": \\"bar\\"}
Difference:
- Expected
+ Received
Object {
- \\"baz\\": \\"bar\\",
+ \\"foo\\": \\"bar\\",
}
at ../../packages/expect/build/index.js:155:54
"
`;
exports[`works with node assert 1`] = `
"FAIL __tests__/node_assertion_error.test.js
✕ assert
Expand Down
15 changes: 9 additions & 6 deletions integration_tests/__tests__/coverage_remapping.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@
const {readFileSync} = require('fs');
const path = require('path');
const skipOnWindows = require('../../scripts/skip_on_windows');
const {run} = require('../utils');
const {cleanup, run} = require('../utils');
const runJest = require('../runJest');

const dir = path.resolve(__dirname, '../coverage-remapping');
const coverageDir = path.join(dir, 'coverage');

skipOnWindows.suite();

beforeAll(() => {
cleanup(coverageDir);
});

it('maps code coverage against original source', () => {
const dir = path.resolve(__dirname, '../coverage-remapping');
run('yarn', dir);
runJest(dir, ['--coverage', '--mapCoverage', '--no-cache']);

const coverageMapFile = path.join(
__dirname,
'../coverage-remapping/coverage/coverage-final.json',
);
const coverageMapFile = path.join(coverageDir, 'coverage-final.json');
const coverageMap = JSON.parse(readFileSync(coverageMapFile, 'utf-8'));

// reduce absolute paths embedded in the coverage map to just filenames
Expand Down
12 changes: 12 additions & 0 deletions integration_tests/__tests__/failures.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,15 @@ test('works with node assert', () => {

expect(summary).toMatchSnapshot();
});

test('works with assertions in separate files', () => {
const {stderr} = runJest(dir, ['test_macro.test.js']);

expect(normalizeDots(extractSummary(stderr).rest)).toMatchSnapshot();
});

test('works with async failures', () => {
const {stderr} = runJest(dir, ['async_failures.test.js']);

expect(normalizeDots(extractSummary(stderr).rest)).toMatchSnapshot();
});
13 changes: 13 additions & 0 deletions integration_tests/failures/__tests__/async_failures.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+jsinfra
*/
'use strict';

test('something async', () => {
return expect(Promise.resolve({foo: 'bar'})).resolves.toEqual({baz: 'bar'});
});
15 changes: 15 additions & 0 deletions integration_tests/failures/__tests__/test_macro.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+jsinfra
*/
'use strict';

const shouldEqual = require('../macros');

test('use some imported macro to make assertion', () => {
shouldEqual(1, 2);
});
13 changes: 13 additions & 0 deletions integration_tests/failures/macros.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
'use strict';

module.exports = (one: any, two: any) => {
expect(one).toEqual(two);
};
39 changes: 28 additions & 11 deletions packages/jest-message-util/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ import slash from 'slash';
import {codeFrameColumns} from '@babel/code-frame';
import StackUtils from 'stack-utils';

// stack utils tries to create pretty stack by making paths relative.
const stackUtils = new StackUtils({
cwd: 'something which does not exist',
});

let nodeInternals = [];

try {
Expand Down Expand Up @@ -45,6 +50,7 @@ const JEST_INTERNALS_IGNORE = /^\s+at.*?jest(-.*?)?(\/|\\)(build|node_modules|pa
const ANONYMOUS_FN_IGNORE = /^\s+at <anonymous>.*$/;
const ANONYMOUS_PROMISE_IGNORE = /^\s+at (new )?Promise \(<anonymous>\).*$/;
const ANONYMOUS_GENERATOR_IGNORE = /^\s+at Generator.next \(<anonymous>\).*$/;
const NATIVE_NEXT_IGNORE = /^\s+at next \(native\).*$/;
const TITLE_INDENT = ' ';
const MESSAGE_INDENT = ' ';
const STACK_INDENT = ' ';
Expand Down Expand Up @@ -136,6 +142,10 @@ const removeInternalStackEntries = (lines, options: StackTraceOptions) => {
return false;
}

if (NATIVE_NEXT_IGNORE.test(line)) {
return false;
}

if (nodeInternals.some(internal => internal.test(line))) {
return false;
}
Expand Down Expand Up @@ -202,19 +212,26 @@ export const formatStackTrace = (
: null;
lines = removeInternalStackEntries(lines, options);

if (testPath) {
const topFrame = lines
.join('\n')
.trim()
.split('\n')[0];

const parsedFrame = StackUtils.parseLine(topFrame);

if (parsedFrame) {
const topFrame = lines
.map(line => line.trim())
.filter(Boolean)
.filter(
line =>
!line.includes(`${path.sep}node_modules${path.sep}`) &&
!line.includes(`${path.sep}expect${path.sep}build${path.sep}`),
)
.map(line => stackUtils.parseLine(line))
.filter(Boolean)
.filter(parsedFrame => parsedFrame.file)[0];

if (topFrame) {
const filename = topFrame.file;

if (path.isAbsolute(filename)) {
renderedCallsite = codeFrameColumns(
fs.readFileSync(testPath, 'utf8'),
fs.readFileSync(filename, 'utf8'),
{
start: {line: parsedFrame.line},
start: {line: topFrame.line},
},
{highlightCode: true},
);
Expand Down

0 comments on commit fb10f7a

Please sign in to comment.