Skip to content

Commit

Permalink
Fix location for test.each (#10413)
Browse files Browse the repository at this point in the history
  • Loading branch information
apexskier committed Sep 14, 2020
1 parent 7e71d5f commit ac73de8
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@

### Fixes

- `[jest-circus, jest-jasmine2]` Find correct location for `test.each` tests ([#10413](https://github.com/facebook/jest/pull/10413))
- `[jest-console]` Add `Console` constructor to `console` object ([#10502](https://github.com/facebook/jest/pull/10502))
- `[jest-globals]` Fix lifecycle hook function types ([#10480](https://github.com/facebook/jest/pull/10480))

Expand Down
45 changes: 32 additions & 13 deletions e2e/__tests__/locationInResults.test.ts
Expand Up @@ -13,13 +13,11 @@ it('defaults to null for location', () => {

const assertions = result.testResults[0].assertionResults;
expect(result.success).toBe(true);
expect(result.numTotalTests).toBe(6);
expect(assertions[0].location).toBeNull();
expect(assertions[1].location).toBeNull();
expect(assertions[2].location).toBeNull();
expect(assertions[3].location).toBeNull();
expect(assertions[4].location).toBeNull();
expect(assertions[5].location).toBeNull();
expect(result.numTotalTests).toBe(10);
expect(assertions).toHaveLength(10);
for (const assertion of assertions) {
expect(assertion.location).toBeNull();
}
});

it('adds correct location info when provided with flag', () => {
Expand All @@ -29,7 +27,8 @@ it('adds correct location info when provided with flag', () => {

const assertions = result.testResults[0].assertionResults;
expect(result.success).toBe(true);
expect(result.numTotalTests).toBe(6);
expect(result.numTotalTests).toBe(10);

expect(assertions[0].location).toEqual({
column: 1,
line: 12,
Expand All @@ -45,20 +44,40 @@ it('adds correct location info when provided with flag', () => {
line: 20,
});

// Technically the column should be 3, but callsites is not correct.
// jest-circus uses stack-utils + asyncErrors which resolves this.
expect(assertions[3].location).toEqual({
column: isJestCircusRun() ? 3 : 2,
line: 25,
column: isJestCircusRun() ? 1 : 22,
line: 24,
});

expect(assertions[4].location).toEqual({
column: isJestCircusRun() ? 1 : 22,
line: 24,
});

// Technically the column should be 3, but callsites is not correct.
// jest-circus uses stack-utils + asyncErrors which resolves this.
expect(assertions[5].location).toEqual({
column: isJestCircusRun() ? 3 : 2,
line: 29,
});

expect(assertions[5].location).toEqual({
expect(assertions[6].location).toEqual({
column: isJestCircusRun() ? 3 : 2,
line: 33,
});

expect(assertions[7].location).toEqual({
column: isJestCircusRun() ? 3 : 2,
line: 37,
});

expect(assertions[8].location).toEqual({
column: isJestCircusRun() ? 3 : 24,
line: 41,
});

expect(assertions[9].location).toEqual({
column: isJestCircusRun() ? 3 : 24,
line: 41,
});
});
8 changes: 8 additions & 0 deletions e2e/location-in-results/__tests__/test.js
Expand Up @@ -21,6 +21,10 @@ fit('fit no ancestors', () => {
expect(true).toBeTruthy();
});

it.each([true, true])('it each no ancestors', () => {
expect(true).toBeTruthy();
});

describe('nested', () => {
it('it nested', () => {
expect(true).toBeTruthy();
Expand All @@ -33,4 +37,8 @@ describe('nested', () => {
fit('fit nested', () => {
expect(true).toBeTruthy();
});

it.each([true, true])('it each nested', () => {
expect(true).toBeTruthy();
});
});
12 changes: 10 additions & 2 deletions packages/jest-circus/src/utils.ts
Expand Up @@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import * as path from 'path';
import type {Circus} from '@jest/types';
import {convertDescriptorToString, formatTime} from 'jest-util';
import isGeneratorFn from 'is-generator-fn';
Expand All @@ -17,6 +18,8 @@ import {ROOT_DESCRIBE_BLOCK_NAME, getState} from './state';

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

const jestEachBuildDir = path.dirname(require.resolve('jest-each'));

export const makeDescribe = (
name: Circus.BlockName,
parent?: Circus.DescribeBlock,
Expand Down Expand Up @@ -299,8 +302,13 @@ export const makeSingleTestResult = (

let location = null;
if (includeTestLocationInResult) {
const stackLine = test.asyncError.stack.split('\n')[1];
const parsedLine = stackUtils.parseLine(stackLine);
const stackLines = test.asyncError.stack.split('\n');
const stackLine = stackLines[1];
let parsedLine = stackUtils.parseLine(stackLine);
if (parsedLine?.file?.startsWith(jestEachBuildDir)) {
const stackLine = stackLines[4];
parsedLine = stackUtils.parseLine(stackLine);
}
if (
parsedLine &&
typeof parsedLine.column === 'number' &&
Expand Down
56 changes: 25 additions & 31 deletions packages/jest-jasmine2/src/index.ts
Expand Up @@ -22,6 +22,8 @@ import type {Jasmine as JestJasmine} from './types';

const JASMINE = require.resolve('./jasmine/jasmineLight');

const jestEachBuildDir = path.dirname(require.resolve('jest-each'));

async function jasmine2(
globalConfig: Config.GlobalConfig,
config: Config.ProjectConfig,
Expand All @@ -47,38 +49,30 @@ async function jasmine2(
// TODO: Remove config option if V8 exposes some way of getting location of caller
// in a future version
if (config.testLocationInResults === true) {
const originalIt = environment.global.it;
environment.global.it = ((...args) => {
const stack = getCallsite(1, runtime.getSourceMaps());
const it = originalIt(...args);

// @ts-expect-error
it.result.__callsite = stack;

return it;
}) as Global.Global['it'];

const originalXit = environment.global.xit;
environment.global.xit = ((...args) => {
const stack = getCallsite(1, runtime.getSourceMaps());
const xit = originalXit(...args);

// @ts-expect-error
xit.result.__callsite = stack;

return xit;
}) as Global.Global['xit'];

const originalFit = environment.global.fit;
environment.global.fit = ((...args) => {
const stack = getCallsite(1, runtime.getSourceMaps());
const fit = originalFit(...args);

// @ts-expect-error
fit.result.__callsite = stack;
function wrapIt<T extends Global.ItBase>(original: T): T {
const wrapped = (
testName: Global.TestName,
fn: Global.TestFn,
timeout?: number,
) => {
const sourcemaps = runtime.getSourceMaps();
let stack = getCallsite(1, sourcemaps);
const it = original(testName, fn, timeout);

if (stack.getFileName()?.startsWith(jestEachBuildDir)) {
stack = getCallsite(4, sourcemaps);
}
// @ts-expect-error
it.result.__callsite = stack;

return it;
};
return (wrapped as any) as T;
}

return fit;
}) as Global.Global['fit'];
environment.global.it = wrapIt(environment.global.it);
environment.global.xit = wrapIt(environment.global.xit);
environment.global.fit = wrapIt(environment.global.fit);
}

jasmineAsyncInstall(globalConfig, environment.global);
Expand Down

0 comments on commit ac73de8

Please sign in to comment.