diff --git a/package.json b/package.json index dff9d192..579ab135 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "vitest-explorer", "displayName": "Vitest", - "description": "Run Vitest tests right from vscode", - "version": "0.0.3", + "description": "Run Vitest tests right from editor", + "version": "0.1.0", "icon": "img/icon.png", "preview": true, "author": "zxch3n", diff --git a/samples/basic/test/add.test.ts b/samples/basic/test/add.test.ts index 9af83c12..3a42e00b 100644 --- a/samples/basic/test/add.test.ts +++ b/samples/basic/test/add.test.ts @@ -19,7 +19,8 @@ describe("addition", () => { describe("haha a a", () => { it("run", () => { - expect(5).toBe(4); + let a = 10; + expect(a).toBe(10); }); it("123", () => {}); }); diff --git a/src/TestData.ts b/src/TestData.ts index adc13bb1..a4cb153a 100644 --- a/src/TestData.ts +++ b/src/TestData.ts @@ -46,6 +46,10 @@ export class TestDescribe { getFullPattern(): string { return getFullPattern(this); } + + getFilePath(): string { + return this.fileItem.uri!.path; + } } export class TestCase { @@ -59,6 +63,10 @@ export class TestCase { getFullPattern(): string { return getFullPattern(this); } + + getFilePath(): string { + return this.fileItem.uri!.path; + } } export class TestFile { @@ -86,7 +94,11 @@ export class TestFile { } getFullPattern(): string { - return this.pattern; + return ""; + } + + getFilePath(): string { + return this.item.uri!.path; } } diff --git a/src/extension.ts b/src/extension.ts index 0011d917..a5959d05 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,7 +3,7 @@ import * as vscode from "vscode"; import { extensionId } from "./config"; import { discoverAllFilesInWorkspace, discoverTestFromDoc } from "./discover"; import { isVitestEnv } from "./pure/isVitestEnv"; -import { runHandler } from "./runHandler"; +import { debugHandler, runHandler } from "./runHandler"; import { WEAKMAP_TEST_DATA, TestFile } from "./TestData"; export async function activate(context: vscode.ExtensionContext) { @@ -42,6 +42,13 @@ export async function activate(context: vscode.ExtensionContext) { true ); + ctrl.createRunProfile( + "Debug Tests", + vscode.TestRunProfileKind.Debug, + debugHandler.bind(null, ctrl), + true + ); + vscode.window.visibleTextEditors.forEach((x) => discoverTestFromDoc(ctrl, x.document) ); diff --git a/src/pure/runner.ts b/src/pure/runner.ts index 8fd2175d..f3afd159 100644 --- a/src/pure/runner.ts +++ b/src/pure/runner.ts @@ -1,7 +1,7 @@ import { existsSync, readFile } from "fs-extra"; import * as path from "path"; import { tmpdir } from "os"; -import { Lock, PriorityTaskQueue, TaskQueue } from "mighty-promise"; +import { TaskQueue } from "mighty-promise"; import execa = require("execa"); export function getVitestPath(projectRoot: string): string | undefined { @@ -10,12 +10,15 @@ export function getVitestPath(projectRoot: string): string | undefined { return; } - if (existsSync(path.resolve(node_modules, ".bin", "vitest"))) { - return path.resolve(node_modules, ".bin", "vitest"); + if (existsSync(path.resolve(node_modules, "vitest", "vitest.mjs"))) { + return path.resolve(node_modules, "vitest", "vitest.mjs"); } - if (existsSync(path.resolve(node_modules, ".bin", "vitest.cmd"))) { - return path.resolve(node_modules, ".bin", "vitest.cmd"); + const suffixes = [".js", "", ".cmd"]; + for (const suffix of suffixes) { + if (existsSync(path.resolve(node_modules, ".bin", "vitest" + suffix))) { + return path.resolve(node_modules, ".bin", "vitest" + suffix); + } } return; diff --git a/src/runHandler.ts b/src/runHandler.ts index 032dfe2a..35daef27 100644 --- a/src/runHandler.ts +++ b/src/runHandler.ts @@ -1,3 +1,4 @@ +import { resolve } from "path"; import * as vscode from "vscode"; import { getVitestPath as getVitestPath, TestRunner } from "./pure/runner"; import { @@ -7,12 +8,79 @@ import { TestFile, } from "./TestData"; +export async function debugHandler( + ctrl: vscode.TestController, + request: vscode.TestRunRequest +) { + if ( + vscode.workspace.workspaceFolders === undefined || + vscode.workspace.workspaceFolders.length === 0 + ) { + return; + } + + const tests = request.include ?? []; + if (tests.length === 1) { + await debugTest(vscode.workspace.workspaceFolders[0], tests[0]); + } else { + await debugTest(vscode.workspace.workspaceFolders[0]); + } +} + +async function debugTest( + workspaceFolder: vscode.WorkspaceFolder, + testItem?: vscode.TestItem +) { + let config = { + type: "pwa-node", + request: "launch", + name: "Debug Current Test File", + autoAttachChildProcesses: true, + skipFiles: ["/**", "**/node_modules/**"], + program: getVitestPath(workspaceFolder.uri.path), + args: [] as string[], + smartStep: true, + console: "integratedTerminal", + }; + + if (testItem) { + const data = WEAKMAP_TEST_DATA.get(testItem); + if (!data) { + console.error("Item not found"); + return; + } + + config.args = [ + "run", + data.getFilePath(), + "--testNamePattern", + data.getFullPattern(), + ]; + } else { + config.args = ["run"]; + } + + if (config.program == null) { + vscode.window.showErrorMessage("Cannot find vitest"); + return; + } + + try { + vscode.debug.startDebugging(workspaceFolder, config); + } catch (e) { + console.error(`startDebugging error ${(e as any).toString()}`); + } +} + export async function runHandler( ctrl: vscode.TestController, request: vscode.TestRunRequest, cancellation: vscode.CancellationToken ) { - if (vscode.workspace.workspaceFolders === undefined) { + if ( + vscode.workspace.workspaceFolders === undefined || + vscode.workspace.workspaceFolders.length === 0 + ) { return; }