Skip to content

Commit

Permalink
Add testLocationInResults support to jest-circus (#6291)
Browse files Browse the repository at this point in the history
* Add `testLocationInResults` support to jest-circus

Part of #4362

* Hoist StackUtils construction

* Move test location config into state
  • Loading branch information
captbaritone authored and aaronabramov committed May 27, 2018
1 parent 7b8a840 commit 75831af
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 4 deletions.
9 changes: 8 additions & 1 deletion integration-tests/__tests__/location_in_results.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import skipOnJestCicrus from '../../scripts/SkipOnJestCircus';
const runJest = require('../runJest');
const SkipOnJestCircus = require('../../scripts/SkipOnJestCircus');

skipOnJestCicrus.suite();

Expand All @@ -32,5 +33,11 @@ it('adds correct location info when provided with flag', () => {
expect(result.success).toBe(true);
expect(result.numTotalTests).toBe(2);
expect(assertions[0].location).toEqual({column: 1, line: 10});
expect(assertions[1].location).toEqual({column: 2, line: 15});

// Technically the column should be 3, but callsites is not correct.
// jest-circus uses stack-utils + asyncErrors which resolves this.
expect(assertions[1].location).toEqual({
column: SkipOnJestCircus.isJestCircusRun() ? 3 : 2,
line: 15,
});
});
3 changes: 2 additions & 1 deletion packages/jest-circus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"jest-message-util": "^23.0.0",
"jest-snapshot": "^23.0.0",
"jest-util": "^23.0.0",
"pretty-format": "^23.0.0"
"pretty-format": "^23.0.0",
"stack-utils": "^1.0.1"
},
"devDependencies": {
"jest-runtime": "^23.0.0"
Expand Down
4 changes: 4 additions & 0 deletions packages/jest-circus/src/event_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const TEST_TIMEOUT_SYMBOL = Symbol.for('TEST_TIMEOUT_SYMBOL');

const handler: EventHandler = (event, state): void => {
switch (event.name) {
case 'include_test_location_in_result': {
state.includeTestLocationInResult = true;
break;
}
case 'hook_start': {
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ export const initialize = ({
testNamePattern: globalConfig.testNamePattern,
});

if (config.testLocationInResults) {
dispatch({
name: 'include_test_location_in_result',
});
}

// Jest tests snapshotSerializers in order preceding built-in serializers.
// Therefore, add in reverse because the last added is the first tested.
config.snapshotSerializers
Expand Down Expand Up @@ -131,6 +137,7 @@ export const runAndTransformResultsToJestFormat = async ({
duration: testResult.duration,
failureMessages: testResult.errors,
fullName: ancestorTitles.concat(title).join(' '),
location: testResult.location,
numPassingAsserts: 0,
status,
title: testResult.testPath[testResult.testPath.length - 1],
Expand Down
1 change: 1 addition & 0 deletions packages/jest-circus/src/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const INITIAL_STATE: State = {
currentlyRunningTest: null,
expand: undefined,
hasFocusedTests: false, // whether .only has been used on any test/describe
includeTestLocationInResult: false,
parentProcess: null,
rootDescribeBlock: ROOT_DESCRIBE_BLOCK,
testNamePattern: null,
Expand Down
20 changes: 18 additions & 2 deletions packages/jest-circus/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ import {convertDescriptorToString} from 'jest-util';
import isGeneratorFn from 'is-generator-fn';
import co from 'co';

import StackUtils from 'stack-utils';

import prettyFormat from 'pretty-format';

import {getState} from './state';

// Try getting the real promise object from the context, if available. Someone
// could have overridden it in a test. Async functions return it implicitly.
// eslint-disable-next-line no-unused-vars
const Promise = global[Symbol.for('jest-native-promise')] || global.Promise;
export const getOriginalPromise = () => Promise;

const stackUtils = new StackUtils({cwd: 'A path that does not exist'});

export const makeDescribe = (
name: BlockName,
parent: ?DescribeBlock,
Expand Down Expand Up @@ -235,7 +241,8 @@ export const makeRunResult = (
};
};

const makeTestResults = (describeBlock: DescribeBlock): TestResults => {
const makeTestResults = (describeBlock: DescribeBlock, config): TestResults => {
const {includeTestLocationInResult} = getState();
let testResults = [];
for (const test of describeBlock.tests) {
const testPath = [];
Expand All @@ -249,16 +256,25 @@ const makeTestResults = (describeBlock: DescribeBlock): TestResults => {
if (!status) {
throw new Error('Status should be present after tests are run.');
}

let location = null;
if (includeTestLocationInResult) {
const stackLine = test.asyncError.stack.split('\n')[1];
const {line, column} = stackUtils.parseLine(stackLine);
location = {column, line};
}

testResults.push({
duration: test.duration,
errors: test.errors.map(_formatError),
location,
status,
testPath,
});
}

for (const child of describeBlock.children) {
testResults = testResults.concat(makeTestResults(child));
testResults = testResults.concat(makeTestResults(child, config));
}

return testResults;
Expand Down
4 changes: 4 additions & 0 deletions scripts/SkipOnJestCircus.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
/* eslint-disable jest/no-focused-tests */

const SkipOnJestCircus = {
isJestCircusRun() {
return process.env.JEST_CIRCUS === '1';
},

suite() {
if (process.env.JEST_CIRCUS === '1') {
fit('does not work on jest-circus', () => {
Expand Down
5 changes: 5 additions & 0 deletions types/Circus.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ export type Hook = {
export type EventHandler = (event: Event, state: State) => void;

export type Event =
| {|
name: 'include_test_location_in_result',
|}
| {|
asyncError: Exception,
mode: BlockMode,
Expand Down Expand Up @@ -143,6 +146,7 @@ export type TestResult = {|
duration: ?number,
errors: Array<FormattedError>,
status: TestStatus,
location: ?{|column: number, line: number|},
testPath: Array<TestName | BlockName>,
|};

Expand Down Expand Up @@ -172,6 +176,7 @@ export type State = {|
testNamePattern: ?RegExp,
testTimeout: number,
unhandledErrors: Array<Exception>,
includeTestLocationInResult: boolean,
|};

export type DescribeBlock = {|
Expand Down

0 comments on commit 75831af

Please sign in to comment.