Skip to content

Commit 75831af

Browse files
captbaritoneaaronabramov
authored andcommitted
Add testLocationInResults support to jest-circus (jestjs#6291)
* Add `testLocationInResults` support to jest-circus Part of jestjs#4362 * Hoist StackUtils construction * Move test location config into state
1 parent 7b8a840 commit 75831af

File tree

8 files changed

+49
-4
lines changed

8 files changed

+49
-4
lines changed

integration-tests/__tests__/location_in_results.test.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import skipOnJestCicrus from '../../scripts/SkipOnJestCircus';
1212
const runJest = require('../runJest');
13+
const SkipOnJestCircus = require('../../scripts/SkipOnJestCircus');
1314

1415
skipOnJestCicrus.suite();
1516

@@ -32,5 +33,11 @@ it('adds correct location info when provided with flag', () => {
3233
expect(result.success).toBe(true);
3334
expect(result.numTotalTests).toBe(2);
3435
expect(assertions[0].location).toEqual({column: 1, line: 10});
35-
expect(assertions[1].location).toEqual({column: 2, line: 15});
36+
37+
// Technically the column should be 3, but callsites is not correct.
38+
// jest-circus uses stack-utils + asyncErrors which resolves this.
39+
expect(assertions[1].location).toEqual({
40+
column: SkipOnJestCircus.isJestCircusRun() ? 3 : 2,
41+
line: 15,
42+
});
3643
});

packages/jest-circus/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"jest-message-util": "^23.0.0",
1818
"jest-snapshot": "^23.0.0",
1919
"jest-util": "^23.0.0",
20-
"pretty-format": "^23.0.0"
20+
"pretty-format": "^23.0.0",
21+
"stack-utils": "^1.0.1"
2122
},
2223
"devDependencies": {
2324
"jest-runtime": "^23.0.0"

packages/jest-circus/src/event_handler.js

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ const TEST_TIMEOUT_SYMBOL = Symbol.for('TEST_TIMEOUT_SYMBOL');
2626

2727
const handler: EventHandler = (event, state): void => {
2828
switch (event.name) {
29+
case 'include_test_location_in_result': {
30+
state.includeTestLocationInResult = true;
31+
break;
32+
}
2933
case 'hook_start': {
3034
break;
3135
}

packages/jest-circus/src/legacy_code_todo_rewrite/jest_adapter_init.js

+7
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ export const initialize = ({
7676
testNamePattern: globalConfig.testNamePattern,
7777
});
7878

79+
if (config.testLocationInResults) {
80+
dispatch({
81+
name: 'include_test_location_in_result',
82+
});
83+
}
84+
7985
// Jest tests snapshotSerializers in order preceding built-in serializers.
8086
// Therefore, add in reverse because the last added is the first tested.
8187
config.snapshotSerializers
@@ -131,6 +137,7 @@ export const runAndTransformResultsToJestFormat = async ({
131137
duration: testResult.duration,
132138
failureMessages: testResult.errors,
133139
fullName: ancestorTitles.concat(title).join(' '),
140+
location: testResult.location,
134141
numPassingAsserts: 0,
135142
status,
136143
title: testResult.testPath[testResult.testPath.length - 1],

packages/jest-circus/src/state.js

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const INITIAL_STATE: State = {
2727
currentlyRunningTest: null,
2828
expand: undefined,
2929
hasFocusedTests: false, // whether .only has been used on any test/describe
30+
includeTestLocationInResult: false,
3031
parentProcess: null,
3132
rootDescribeBlock: ROOT_DESCRIBE_BLOCK,
3233
testNamePattern: null,

packages/jest-circus/src/utils.js

+18-2
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,20 @@ import {convertDescriptorToString} from 'jest-util';
2626
import isGeneratorFn from 'is-generator-fn';
2727
import co from 'co';
2828

29+
import StackUtils from 'stack-utils';
30+
2931
import prettyFormat from 'pretty-format';
3032

33+
import {getState} from './state';
34+
3135
// Try getting the real promise object from the context, if available. Someone
3236
// could have overridden it in a test. Async functions return it implicitly.
3337
// eslint-disable-next-line no-unused-vars
3438
const Promise = global[Symbol.for('jest-native-promise')] || global.Promise;
3539
export const getOriginalPromise = () => Promise;
3640

41+
const stackUtils = new StackUtils({cwd: 'A path that does not exist'});
42+
3743
export const makeDescribe = (
3844
name: BlockName,
3945
parent: ?DescribeBlock,
@@ -235,7 +241,8 @@ export const makeRunResult = (
235241
};
236242
};
237243

238-
const makeTestResults = (describeBlock: DescribeBlock): TestResults => {
244+
const makeTestResults = (describeBlock: DescribeBlock, config): TestResults => {
245+
const {includeTestLocationInResult} = getState();
239246
let testResults = [];
240247
for (const test of describeBlock.tests) {
241248
const testPath = [];
@@ -249,16 +256,25 @@ const makeTestResults = (describeBlock: DescribeBlock): TestResults => {
249256
if (!status) {
250257
throw new Error('Status should be present after tests are run.');
251258
}
259+
260+
let location = null;
261+
if (includeTestLocationInResult) {
262+
const stackLine = test.asyncError.stack.split('\n')[1];
263+
const {line, column} = stackUtils.parseLine(stackLine);
264+
location = {column, line};
265+
}
266+
252267
testResults.push({
253268
duration: test.duration,
254269
errors: test.errors.map(_formatError),
270+
location,
255271
status,
256272
testPath,
257273
});
258274
}
259275

260276
for (const child of describeBlock.children) {
261-
testResults = testResults.concat(makeTestResults(child));
277+
testResults = testResults.concat(makeTestResults(child, config));
262278
}
263279

264280
return testResults;

scripts/SkipOnJestCircus.js

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
/* eslint-disable jest/no-focused-tests */
1111

1212
const SkipOnJestCircus = {
13+
isJestCircusRun() {
14+
return process.env.JEST_CIRCUS === '1';
15+
},
16+
1317
suite() {
1418
if (process.env.JEST_CIRCUS === '1') {
1519
fit('does not work on jest-circus', () => {

types/Circus.js

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ export type Hook = {
3232
export type EventHandler = (event: Event, state: State) => void;
3333

3434
export type Event =
35+
| {|
36+
name: 'include_test_location_in_result',
37+
|}
3538
| {|
3639
asyncError: Exception,
3740
mode: BlockMode,
@@ -143,6 +146,7 @@ export type TestResult = {|
143146
duration: ?number,
144147
errors: Array<FormattedError>,
145148
status: TestStatus,
149+
location: ?{|column: number, line: number|},
146150
testPath: Array<TestName | BlockName>,
147151
|};
148152

@@ -172,6 +176,7 @@ export type State = {|
172176
testNamePattern: ?RegExp,
173177
testTimeout: number,
174178
unhandledErrors: Array<Exception>,
179+
includeTestLocationInResult: boolean,
175180
|};
176181

177182
export type DescribeBlock = {|

0 commit comments

Comments
 (0)