Skip to content

Commit

Permalink
Support extension settings ('pretest', 'packageManager', 'testCommand…
Browse files Browse the repository at this point in the history
…', 'extraArguments', and 'executableOptions') (#11)

* Support extension settings ('pretest', 'packageManager', 'testCommand', 'extraArguments', and 'executableOptions')

Co-authored-by: Raz Luvaton <16746759+rluvaton@users.noreply.github.com>
  • Loading branch information
cafesanu and rluvaton committed Mar 24, 2024
1 parent 728655c commit b0ea528
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.3.0",
"version": "0.4.0",
"configurations": [
{
"name": "Launch Extension",
Expand Down
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@

Vitest runner for vscode that actually works

Supports:
-
![preview](https://github.com/rluvaton/vitest-vs-code-plugin/blob/main/docs/preview.png?raw=true)
### Run/Watch/debug any test (`it`, `test`, or `describe`) in `.js`, `.ts`, `.jsx`, or `.tsx` files:

![preview](screenshot.png)


## Extension Settings

| Command | Description | Examples | Default |
| --------------------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------| --------------------------------------------- |
| `vscode-vitest.preTest` | Any command(s) to run before test starts | `["npm run script1", "npm run script2"` (will run in the given order. If command(s) fail, tests will not run) | [] |
| `vscode-vitest.postTest` | Any command(s) to run after test finishes | `["npm run clean1", "npm run clean2"` (will run in the given order) | [] |
| `vscode-vitest.packageManager` | Desired package manager | `npm`, `yarn`, `pnpm`, `pnpn dlx`, etc | `npx` |
| `vscode-vitest.testCommand` | Define an alternative vitest command | `test` (e.g. for CRA, package.json `test` script, or similar abstractions) | `vitest` |
| `vscode-vitest.extraArguments` | Any additional vitest arguments | `--silent=true --maxWorkers=2` | `""` |
| `vscode-vitest.executableOptions` | Executable option to show | `{"debug": false, "run": false}` (will only display `watch`) | `{"debug": true,"run": true, "run": true}` |


### Example Settings:
```
"vscode-vitest.preTest": ["npm run script1"],
"vscode-vitest.postTest": ["npm run cleanAfterTest"],
"vscode-vitest.packageManager": "pnpm",
"vscode-vitest.testCommand": "test",
"vscode-vitest.extraArguments": "--silent --maxWorkers=2",
"vscode-vitest.executableOptions": {
"debug": false,
"watch": false
},
```
66 changes: 65 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vscode-vitest",
"displayName": "Vitest Runner for VSCode that actually work",
"version": "0.3.0",
"version": "0.4.0",
"main": "dist/index.js",
"icon": "logo.png",
"license": "MIT",
Expand Down Expand Up @@ -44,5 +44,69 @@
},
"dependencies": {
"find-up": "^5.0.0"
},
"contributes": {
"configuration": {
"title": "Vitest Runner Configuration",
"properties": {
"vscode-vitest.preTest": {
"type": ["array"],
"items": {
"type": "string"
},
"default": [],
"description": "Command to run before tests run. e.g npm run preTest"
},
"vscode-vitest.postTest": {
"type": ["array"],
"items": {
"type": "string"
},
"default": [],
"description": "Command to run after tests run. e.g npm run cleanAfterTest"
},
"vscode-vitest.packageManager": {
"type": "string",
"default": "npx",
"description": "Command to run tests. e.g npm, pnpm, npx, yarn"
},
"vscode-vitest.testCommand": {
"type": "string",
"default": "vitest",
"description": "Command to run tests. e.g test, vitest"
},
"vscode-vitest.extraArguments": {
"type": "string",
"default": "",
"description": "Extra arguments to run the test. e.g --maxWorkers --silent"
},
"vscode-vitest.executableOptions": {
"type": "object",
"default": {
"run": true,
"watch": true,
"debug": true
},
"properties": {
"run": {
"type": "boolean",
"default": true,
"description": "Enable or disable Run(Vitest)"
},
"watch": {
"type": "boolean",
"default": true,
"description": "Enable or disable Watch(Vitest)"
},
"debug": {
"type": "boolean",
"default": true,
"description": "Enable or disable Debug(Vitest)."
}
},
"description": "Choose which executable options to enable"
}
}
}
}
}
Binary file added screenshot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 29 additions & 3 deletions src/codelens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import {DebugVitestCommand, RunVitestCommand, WatchVitestCommand} from './vscode
import {TestTreeBuilder} from "./test-tree/build";
import {TestTreeNode} from './test-tree/types';

interface ExecutableOptions {
run: boolean;
watch: boolean;
debug: boolean;
}

const config = vscode.workspace.getConfiguration('vscode-vitest');

export class CodeLensProvider implements vscode.CodeLensProvider {
constructor(private typescript: typeof ts) {
}
Expand All @@ -24,19 +32,37 @@ export class CodeLensProvider implements vscode.CodeLensProvider {
const start = document.positionAt(testNode.position.start);
const end = document.positionAt(testNode.position.end);

return [
const executableOptions: ExecutableOptions = config.get("executableOptions") ?? {
run: true,
watch: true,
debug: true,
}

const runCommand = executableOptions.run ? [
new vscode.CodeLens(
new vscode.Range(start, end),
new RunVitestCommand(testNode.name, document.fileName)
),
)
] : []

const debugCommand = executableOptions.debug ? [
new vscode.CodeLens(
new vscode.Range(start, end),
new DebugVitestCommand(testNode.name, document.fileName)
),
)
] : []

const watchCommand = executableOptions.watch ? [
new vscode.CodeLens(
new vscode.Range(start, end),
new WatchVitestCommand(testNode.name, document.fileName)
)
] : []

return [
...runCommand,
...debugCommand,
...watchCommand,
];
});
}
Expand Down
47 changes: 20 additions & 27 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import * as path from 'path';
import * as findUp from 'find-up';
import { configFiles } from './vitest-config-files';

const config = vscode.workspace.getConfiguration('vscode-vitest');

function getCwd(testFile: string) {
const configFilePath = findUp.sync(configFiles, { cwd: testFile });

Expand All @@ -12,14 +14,16 @@ function getCwd(testFile: string) {
return path.dirname(configFilePath);
}

function buildVitestArgs({ caseName, casePath, sanitize = true, command = 'run' }: { caseName: string, casePath: string, sanitize?: boolean, command?: 'run' | 'watch' }) {
function buildVitestArgs({ caseName, casePath, sanitize = true, testMode = 'run' }: { caseName: string, casePath: string, sanitize?: boolean, testMode?: 'run' | 'watch' }) {
let sanitizedCasePath = casePath;
if (sanitize) {
sanitizedCasePath = JSON.stringify(casePath);
caseName = JSON.stringify(caseName);
}

const args = ['vitest', command, '--testNamePattern', caseName, sanitizedCasePath];
const testCommand = config.get("testCommand")

const args = [testCommand, testMode, '--testNamePattern', caseName, sanitizedCasePath];

const rootDir = getCwd(casePath);
if (rootDir) {
Expand All @@ -35,38 +39,25 @@ async function saveFile(filePath: string) {
await vscode.workspace.textDocuments.find((doc) => doc.fileName === filePath)?.save();
}

export async function runInTerminal(text: string, filename: string) {
export async function executeInTerminal(text: string, filename: string, testMode: "run" | "watch" = "run") {
let terminalAlreadyExists = true;
if (!terminal || terminal.exitStatus) {
terminalAlreadyExists = false;
terminal?.dispose();
terminal = vscode.window.createTerminal(`vscode-vitest-runner`);
}

const vitestArgs = buildVitestArgs({ caseName: text, casePath: filename });
const npxArgs = ['npx', ...vitestArgs];

if (terminalAlreadyExists) {
// CTRL-C to stop the previous run
terminal.sendText('\x03');
}
const preTest = (config.get("preTest") as string[]);
const finalPreTest = preTest.length > 0 ? [`${preTest.join(" && ")} && `] : []

await saveFile(filename);
const postTest = (config.get("postTest") as string[]);
const finalPostTest = postTest.length > 0 ? [` && ${postTest.join(" && ")}`] : []

const packageManager = config.get("packageManager")
const extraArguments = config.get("extraArguments")

terminal.sendText(npxArgs.join(' '), true);
terminal.show();
}

export async function watchInTerminal(text: string, filename: string) {
let terminalAlreadyExists = true;
if (!terminal || terminal.exitStatus) {
terminalAlreadyExists = false;
terminal?.dispose();
terminal = vscode.window.createTerminal(`vscode-vitest-runner`);
}

const vitestArgs = buildVitestArgs({ command: 'watch', caseName: text, casePath: filename });
const npxArgs = ['npx', ...vitestArgs];
const vitestArgs = buildVitestArgs({ caseName: text, casePath: filename, testMode });
const commandToRun = [...finalPreTest, packageManager, ...vitestArgs, extraArguments, ...finalPostTest];

if (terminalAlreadyExists) {
// CTRL-C to stop the previous run
Expand All @@ -75,20 +66,22 @@ export async function watchInTerminal(text: string, filename: string) {

await saveFile(filename);

terminal.sendText(npxArgs.join(' '), true);
terminal.sendText(commandToRun.join(' '), true);
terminal.show();
}

function buildDebugConfig(
casePath: string,
text: string
): vscode.DebugConfiguration {
const packageManager = config.get("packageManager")

return {
name: 'Debug vitest case',
request: 'launch',
runtimeArgs: buildVitestArgs({ caseName: text, casePath: casePath, sanitize: false }),
cwd: getCwd(casePath) || path.dirname(casePath),
runtimeExecutable: 'npx',
runtimeExecutable: packageManager,
skipFiles: ['<node_internals>/**'],
type: 'pwa-node',
console: 'integratedTerminal',
Expand Down
6 changes: 3 additions & 3 deletions src/vscode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { debugInTerminal, runInTerminal, watchInTerminal } from './run';
import { debugInTerminal, executeInTerminal } from './run';

export class RunVitestCommand implements vscode.Command {
static ID = 'vitest.runTest';
Expand Down Expand Up @@ -37,14 +37,14 @@ export class DebugVitestCommand implements vscode.Command {
vscode.commands.registerCommand(
RunVitestCommand.ID,
(text: string, filename: string) => {
runInTerminal(text, filename)
executeInTerminal(text, filename, "run")
}
);

vscode.commands.registerCommand(
WatchVitestCommand.ID,
(text: string, filename: string) => {
watchInTerminal(text, filename);
executeInTerminal(text, filename, "watch");
}
);

Expand Down

0 comments on commit b0ea528

Please sign in to comment.