Skip to content

Commit c409014

Browse files
authored
fix(coverage): non-awaited module imports cause wrong offsets (#10643)
1 parent 76139c5 commit c409014

6 files changed

Lines changed: 87 additions & 0 deletions

File tree

packages/vitest/src/runtime/moduleRunner/moduleEvaluator.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,15 @@ export class VitestModuleEvaluator implements ModuleEvaluator {
330330

331331
// this will always be 1 element because it's cached after load
332332
const importer = module.importers.values().next().value
333+
334+
// Initialize execution info in case worker exited before module evaluation finished
335+
this.options.moduleExecutionInfo?.set(options.filename, {
336+
duration: 0,
337+
selfTime: 0,
338+
startOffset: codeDefinition.length,
339+
importer,
340+
})
341+
333342
const finishModuleExecutionInfo = this.debug.startCalculateModuleExecutionInfo(options.filename, {
334343
startOffset: codeDefinition.length,
335344
importer,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { response } from "./slow-module";
2+
3+
export function uncovered() {
4+
throw new Error("uncovered");
5+
}
6+
7+
export function uncovered2() {
8+
throw new Error("uncovered");
9+
}
10+
11+
export function covered(value: number) {
12+
if(!response.ok) {
13+
throw new Error("response not ok");
14+
}
15+
16+
return value + 100;
17+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { setTimeout } from "node:timers/promises";
2+
3+
const delay = parseInt(process.env.DELAY ?? "100", 10);
4+
5+
if (delay > 0) {
6+
await setTimeout(delay);
7+
}
8+
9+
export const response = { ok: true };
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { expect, test } from "vitest";
2+
import { covered } from "../src/slow-module-imported";
3+
4+
test("covers covered()", () => {
5+
expect(covered(2)).toBe(102);
6+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { expect, test } from "vitest";
2+
3+
process.env.DELAY = "10000";
4+
5+
test("module import pending", async () => {
6+
const promise = import("../src/slow-module-imported");
7+
8+
await new Promise((resolve) => setTimeout(resolve, 10));
9+
10+
expect(promise).toBeTruthy();
11+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect } from 'vitest'
2+
import { StableTestFileOrderSorter } from '../../test-utils'
3+
import { readCoverageMap, runVitest, test } from '../utils'
4+
5+
test('module offset is set correctly when module import is pending (#10581)', async () => {
6+
await runVitest({
7+
include: [
8+
'fixtures/test/slow-module-import-awaited.test.ts',
9+
'fixtures/test/slow-module-import-pending.test.ts',
10+
],
11+
fileParallelism: false,
12+
sequence: { sequencer: StableTestFileOrderSorter },
13+
coverage: { reporter: 'json' },
14+
})
15+
16+
const coverageMap = await readCoverageMap()
17+
expect(coverageMap.files()).toMatchInlineSnapshot(`
18+
[
19+
"<process-cwd>/fixtures/src/slow-module-imported.ts",
20+
"<process-cwd>/fixtures/src/slow-module.ts",
21+
]
22+
`)
23+
24+
const fileCoverage = coverageMap.fileCoverageFor('<process-cwd>/fixtures/src/slow-module-imported.ts')
25+
26+
/** {@link file://./../fixtures/src/slow-module-imported.ts} */
27+
const lineCoverage = fileCoverage.getLineCoverage()
28+
29+
expect.soft(lineCoverage['4']).toBe(0)
30+
expect.soft(lineCoverage['8']).toBe(0)
31+
32+
expect.soft(lineCoverage['12']).toBe(1)
33+
expect.soft(lineCoverage['13']).toBe(0)
34+
expect.soft(lineCoverage['16']).toBe(1)
35+
})

0 commit comments

Comments
 (0)