Skip to content

Commit

Permalink
fix: should use test name as id instead of index
Browse files Browse the repository at this point in the history
index is not reliable in async tests
  • Loading branch information
zxch3n committed Mar 22, 2022
1 parent 8134a66 commit e7622dd
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 68 deletions.
26 changes: 22 additions & 4 deletions src/pure/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ interface AggregatedResult {
export class TestRunner {
private queue = new TaskQueue<Promise<AggregatedResult>>({
maxParallelNum: 4,
onError: (err) => {
throw err;
},
});
constructor(
private workspacePath: string,
Expand Down Expand Up @@ -93,6 +96,7 @@ export class TestRunner {

let child;
let error: any;
let outputs: string[] = [];
try {
// it will throw when test failed or the testing is failed to run
if (this.vitestPath) {
Expand All @@ -109,21 +113,35 @@ export class TestRunner {

for await (const line of chunksToLinesAsync(child.stdout)) {
log(line + "\r\n");
outputs.push(line);
}
} catch (e) {
error = e;
}

if (!existsSync(path)) {
console.error("scheduleRun error", error.toString());
console.error(error.stack);
console.log("vitestPah", this.vitestPath, args, this.workspacePath);
throw error;
handleError();
}

const file = await readFile(path, "utf-8");
const out = JSON.parse(file) as AggregatedResult;
if (out.testResults.length === 0) {
handleError();
}

return out;

function handleError() {
if (error) {
console.error("scheduleRun error", error.toString());
console.error(error.stack);
} else {
error = new Error(outputs.join("\n"));
}

console.error(outputs.join("\n"));
return error as Error;
}
});
}
}
131 changes: 67 additions & 64 deletions src/runHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ async function runTest(
items: readonly vscode.TestItem[]
) {
const testCaseSet: Set<vscode.TestItem> = new Set();
const fileToTestCasesMap = new Map<string, vscode.TestItem[]>();
const testItemIdMap = new Map<string, vscode.TestItem>();
const fileItems: vscode.TestItem[] = [];
for (const item of items) {
const testingData = WEAKMAP_TEST_DATA.get(item);
Expand All @@ -133,14 +133,19 @@ async function runTest(

fileItems.push(file);
const fileTestCases = getAllTestCases(file);
fileToTestCasesMap.set(item.uri!.path, fileTestCases);
for (const testCase of fileTestCases) {
// remove suffix of test item id
// e.g. "test-case@1" -> "test-case"
// TODO: refactor
testItemIdMap.set(testCase.id.replace(/@\d+$/g, ""), testCase);
}

for (const test of getAllTestCases(item)) {
testCaseSet.add(test);
}
}

testCaseSet.forEach((testCase) => {
run.enqueued(testCase);
run.started(testCase);
});

Expand All @@ -149,75 +154,73 @@ async function runTest(
pathToFile.set(file.uri!.path, file);
}

try {
const out = await runner.scheduleRun(
const out = await runner
.scheduleRun(
fileItems.map((x) => x.uri!.fsPath),
items.length === 1
? WEAKMAP_TEST_DATA.get(items[0])!.getFullPattern()
: "",
items.length === 1
? (msg) => run.appendOutput(msg, undefined, items[0])
: (msg) => run.appendOutput(msg)
);
if (out.testResults.length !== 0) {
Object.values(groupBy(out.testResults, (x) => x.testFilePath)).forEach(
(results) => {
results.forEach((result, index) => {
const fileTestCases = fileToTestCasesMap.get(result.testFilePath!)!;
/**
* ATTENTION: Current implementation assumes that testResults are ordered by
* original test case position for each test file
*/
let child: undefined | vscode.TestItem = fileTestCases[index];
const id =
getTestCaseId(
pathToFile.get(result.testFilePath!)!,
result.displayName!
) || "";
if (!child || !child.id.startsWith(id)) {
console.error("not match");
throw new Error("not match");
}

if (!child || !testCaseSet.has(child)) {
return;
}

testCaseSet.delete(child);
switch (result.status) {
case "pass":
run.passed(child, result.perfStats?.runtime);
return;
case "fail":
run.failed(
child,
new vscode.TestMessage(result.failureMessage || "")
);
return;
}

if (result.skipped || result.status == null) {
run.skipped(child);
}
});
}
);
)
.catch((e) => {
run.appendOutput("Run test failed \r\n" + (e as Error) + "\r\n");
run.appendOutput("" + (e as Error)?.stack + "\r\n");
testCaseSet.forEach((testCase) => {
run.skipped(testCase);
run.appendOutput(`Cannot find test ${testCase.id}`);
run.errored(testCase, new vscode.TestMessage((e as Error)?.toString()));
});
} else {
testCaseSet.forEach((testCase) => {
run.errored(
testCase,
new vscode.TestMessage(
"Unexpected condition. Please report the bug to https://github.com/zxch3n/vitest-explorer/issues"
)
);
});
}
} catch (e) {
console.error(e);
run.appendOutput("Run test failed " + (e as Error).toString());
});

if (out === undefined) {
return;
}

if (out.testResults.length !== 0) {
Object.values(groupBy(out.testResults, (x) => x.testFilePath)).forEach(
(results) => {
results.forEach((result, index) => {
const id =
getTestCaseId(
pathToFile.get(result.testFilePath!)!,
result.displayName!
) || "";
const child = testItemIdMap.get(id)!;
if (!child || !testCaseSet.has(child)) {
return;
}

testCaseSet.delete(child);
switch (result.status) {
case "pass":
run.passed(child, result.perfStats?.runtime);
return;
case "fail":
run.failed(
child,
new vscode.TestMessage(result.failureMessage || "")
);
return;
}

if (result.skipped || result.status == null) {
run.skipped(child);
}
});
}
);
testCaseSet.forEach((testCase) => {
run.skipped(testCase);
run.appendOutput(`Cannot find test ${testCase.id}`);
});
} else {
testCaseSet.forEach((testCase) => {
run.errored(
testCase,
new vscode.TestMessage(
"Unexpected condition. Please report the bug to https://github.com/zxch3n/vitest-explorer/issues"
)
);
});
}
}

0 comments on commit e7622dd

Please sign in to comment.