Skip to content

Commit

Permalink
Added run button on test nodes in the meson view.
Browse files Browse the repository at this point in the history
  • Loading branch information
lukester1975 committed Nov 16, 2023
1 parent 1c3d322 commit 459c3e0
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 14 deletions.
38 changes: 38 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@
{
"command": "mesonbuild.restartLanguageServer",
"title": "Meson: Restart Language Server"
},
{
"command": "mesonbuild.node.runAll",
"title": "Run all",
"icon": "$(testing-run-all-icon)"
},
{
"command": "mesonbuild.node.run",
"title": "Run",
"icon": "$(testing-run-icon)"
}
],
"configuration": {
Expand Down Expand Up @@ -392,6 +402,26 @@
"command": "mesonbuild.openBuildFile",
"when": "view == meson-project && viewItem == meson-target",
"group": "inline"
},
{
"command": "mesonbuild.node.runAll",
"when": "view == meson-project && viewItem == meson-test-root",
"group": "inline"
},
{
"command": "mesonbuild.node.runAll",
"when": "view == meson-project && viewItem == meson-test-root",
"group": "run"
},
{
"command": "mesonbuild.node.run",
"when": "view == meson-project && viewItem == meson-test",
"group": "inline"
},
{
"command": "mesonbuild.node.run",
"when": "view == meson-project && viewItem == meson-test",
"group": "run"
}
],
"view/title": [
Expand All @@ -405,6 +435,14 @@
{
"command": "mesonbuild.openBuildFile",
"when": "false"
},
{
"command": "mesonbuild.node.run",
"when": "false"
},
{
"command": "mesonbuild.node.runAll",
"when": "false"
}
]
},
Expand Down
10 changes: 10 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { activateFormatters } from "./formatters";
import { SettingsKey, TaskQuickPickItem } from "./types";
import { createLanguageServerClient } from "./lsp/common";
import { dirname, relative } from "path";
import { IRunnableNode } from "./treeview/nodes/base";

export let extensionPath: string;
export let workspaceState: vscode.Memento;
Expand Down Expand Up @@ -201,6 +202,15 @@ export async function activate(ctx: vscode.ExtensionContext) {
}),
);

// Two commands just to have different icons.
ctx.subscriptions.push(
vscode.commands.registerCommand("mesonbuild.node.runAll", async (node: IRunnableNode) => node.run()),
);

ctx.subscriptions.push(
vscode.commands.registerCommand("mesonbuild.node.run", async (node: IRunnableNode) => node.run()),
);

if (!checkMesonIsConfigured(buildDir)) {
let configureOnOpen = configurationChosen || extensionConfiguration(SettingsKey.configureOnOpen);
if (configureOnOpen === "ask") {
Expand Down
10 changes: 5 additions & 5 deletions src/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vscode from "vscode";
import { getMesonTargets, getMesonTests, getMesonBenchmarks } from "./introspection";
import { extensionConfiguration, getOutputChannel, getTargetName, getEnvDict } from "./utils";
import { Test, Target } from "./types";
import { Test, Target, pseudoAllTarget } from "./types";
import { checkMesonIsConfigured } from "./utils";
import { workspaceState } from "./extension";

Expand Down Expand Up @@ -75,22 +75,22 @@ export async function getMesonTasks(buildDir: string, sourceDir: string) {
"$meson-gcc",
);
const defaultTestTask = new vscode.Task(
{ type: "meson", mode: "test" },
{ type: "meson", mode: "test", target: pseudoAllTarget },
"Run all tests",
"Meson",
new vscode.ShellExecution(
extensionConfiguration("mesonPath"),
["test", ...extensionConfiguration("testOptions")],
["test", ...extensionConfiguration("testOptions"), pseudoAllTarget],
{ cwd: buildDir },
),
);
const defaultBenchmarkTask = new vscode.Task(
{ type: "meson", mode: "benchmark" },
{ type: "meson", mode: "benchmark", target: pseudoAllTarget },
"Run all benchmarks",
"Meson",
new vscode.ShellExecution(
extensionConfiguration("mesonPath"),
["test", "--benchmark", ...extensionConfiguration("benchmarkOptions")],
["test", "--benchmark", ...extensionConfiguration("benchmarkOptions"), pseudoAllTarget],
{ cwd: buildDir },
),
);
Expand Down
5 changes: 5 additions & 0 deletions src/treeview/nodes/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ export abstract class BaseDirectoryNode<T> extends BaseNode {

abstract buildFileTree(fpaths: T[]): FolderMap<T> | Thenable<FolderMap<T>>;
}

// A node in the meson tree view that can be run.
export interface IRunnableNode {
run(): Thenable<any>;
}
42 changes: 33 additions & 9 deletions src/treeview/nodes/tests.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import * as vscode from "vscode";

import { BaseNode } from "../basenode";
import { Test, Tests } from "../../types";
import { Test, Tests, pseudoAllTarget } from "../../types";
import { extensionRelative } from "../../utils";
import { IRunnableNode } from "./base";

export class TestRootNode extends BaseNode {
function getTestCommand(isBenchmark: boolean): string {
return isBenchmark ? "benchmark" : "test";
}

export class TestRootNode extends BaseNode implements IRunnableNode {
constructor(
parentId: string,
private readonly tests: Tests,
private readonly isBenchmark: boolean,
) {
super(`${parentId}-${isBenchmark ? "benchmarks" : "tests"}`);
super(`${parentId}-${getTestCommand(isBenchmark)}`);
}

override getTreeItem() {
Expand All @@ -21,39 +26,58 @@ export class TestRootNode extends BaseNode {
item.collapsibleState =
this.tests.length === 0 ? vscode.TreeItemCollapsibleState.None : vscode.TreeItemCollapsibleState.Collapsed;

// To key in to "when": "view == meson-project && viewItem == meson-test-root" in package.json.
item.contextValue = "meson-test-root";

return item;
}

override getChildren() {
return this.tests.map((test) => new TestNode(this.id, test, this.isBenchmark));
}

run() {
return vscode.commands.executeCommand(`mesonbuild.${getTestCommand(this.isBenchmark)}`, pseudoAllTarget);
}
}

class TestNode extends BaseNode {
class TestNode extends BaseNode implements IRunnableNode {
private readonly taskName: string;
private readonly command: string;

constructor(
parentId: string,
private readonly test: Test,
private readonly isBenchmark: boolean,
) {
super(`${parentId}-${test.suite[0]}-${test.name}`);

this.command = getTestCommand(this.isBenchmark);
const project = this.test.suite[0].split(":")[0];
this.taskName = `${project}:${this.test.name}`;
}

override getTreeItem() {
const item = super.getTreeItem() as vscode.TreeItem;
const project = this.test.suite[0].split(":")[0];
const name = `${project}:${this.test.name}`;

item.label = this.test.name;
item.iconPath = extensionRelative("res/meson_32.svg");
item.command = {
title: `Run ${this.isBenchmark ? "benchmark" : "test"}`,
command: `mesonbuild.${this.isBenchmark ? "benchmark" : "test"}`,
arguments: [name],
title: `Run ${this.command}`,
command: `mesonbuild.${this.command}`,
arguments: [this.taskName],
};

// No children currently, so don't display toggle.
item.collapsibleState = vscode.TreeItemCollapsibleState.None;

// To key in to "when": "view == meson-project && viewItem == meson-test" in package.json.
item.contextValue = "meson-test";

return item;
}

run() {
return vscode.commands.executeCommand(`mesonbuild.${this.command}`, this.taskName);
}
}
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,5 @@ export enum SettingsKey {
languageServer = "languageServer",
configureOnOpen = "configureOnOpen",
}

export const pseudoAllTarget = "'*'"; // Quoted for for ShellExecution.

0 comments on commit 459c3e0

Please sign in to comment.