Skip to content

Commit 55eb7e2

Browse files
committed
Added run button on test nodes in the meson view.
1 parent 51f7816 commit 55eb7e2

File tree

6 files changed

+93
-14
lines changed

6 files changed

+93
-14
lines changed

package.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@
8787
{
8888
"command": "mesonbuild.restartLanguageServer",
8989
"title": "Meson: Restart Language Server"
90+
},
91+
{
92+
"command": "mesonbuild.node.runAll",
93+
"title": "Run all",
94+
"icon": "$(testing-run-all-icon)"
95+
},
96+
{
97+
"command": "mesonbuild.node.run",
98+
"title": "Run",
99+
"icon": "$(testing-run-icon)"
90100
}
91101
],
92102
"configuration": {
@@ -392,6 +402,26 @@
392402
"command": "mesonbuild.openBuildFile",
393403
"when": "view == meson-project && viewItem == meson-target",
394404
"group": "inline"
405+
},
406+
{
407+
"command": "mesonbuild.node.runAll",
408+
"when": "view == meson-project && viewItem == meson-test-root",
409+
"group": "inline"
410+
},
411+
{
412+
"command": "mesonbuild.node.runAll",
413+
"when": "view == meson-project && viewItem == meson-test-root",
414+
"group": "run"
415+
},
416+
{
417+
"command": "mesonbuild.node.run",
418+
"when": "view == meson-project && viewItem == meson-test",
419+
"group": "inline"
420+
},
421+
{
422+
"command": "mesonbuild.node.run",
423+
"when": "view == meson-project && viewItem == meson-test",
424+
"group": "run"
395425
}
396426
],
397427
"view/title": [
@@ -405,6 +435,14 @@
405435
{
406436
"command": "mesonbuild.openBuildFile",
407437
"when": "false"
438+
},
439+
{
440+
"command": "mesonbuild.node.run",
441+
"when": "false"
442+
},
443+
{
444+
"command": "mesonbuild.node.runAll",
445+
"when": "false"
408446
}
409447
]
410448
},

src/extension.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { activateFormatters } from "./formatters";
2121
import { SettingsKey, TaskQuickPickItem } from "./types";
2222
import { createLanguageServerClient } from "./lsp/common";
2323
import { dirname, relative } from "path";
24+
import { IRunnableNode } from "./treeview/nodes/base";
2425

2526
export let extensionPath: string;
2627
export let workspaceState: vscode.Memento;
@@ -201,6 +202,15 @@ export async function activate(ctx: vscode.ExtensionContext) {
201202
}),
202203
);
203204

205+
// Two commands just to have different icons.
206+
ctx.subscriptions.push(
207+
vscode.commands.registerCommand("mesonbuild.node.runAll", async (node: IRunnableNode) => node.run()),
208+
);
209+
210+
ctx.subscriptions.push(
211+
vscode.commands.registerCommand("mesonbuild.node.run", async (node: IRunnableNode) => node.run()),
212+
);
213+
204214
if (!checkMesonIsConfigured(buildDir)) {
205215
let configureOnOpen = configurationChosen || extensionConfiguration(SettingsKey.configureOnOpen);
206216
if (configureOnOpen === "ask") {

src/tasks.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as vscode from "vscode";
22
import { getMesonTargets, getMesonTests, getMesonBenchmarks } from "./introspection";
33
import { extensionConfiguration, getOutputChannel, getTargetName, getEnvDict } from "./utils";
4-
import { Test, Target } from "./types";
4+
import { Test, Target, pseudoAllTarget } from "./types";
55
import { checkMesonIsConfigured } from "./utils";
66
import { workspaceState } from "./extension";
77

@@ -75,22 +75,22 @@ export async function getMesonTasks(buildDir: string, sourceDir: string) {
7575
"$meson-gcc",
7676
);
7777
const defaultTestTask = new vscode.Task(
78-
{ type: "meson", mode: "test" },
78+
{ type: "meson", mode: "test", target: pseudoAllTarget },
7979
"Run all tests",
8080
"Meson",
8181
new vscode.ShellExecution(
8282
extensionConfiguration("mesonPath"),
83-
["test", ...extensionConfiguration("testOptions")],
83+
["test", ...extensionConfiguration("testOptions"), pseudoAllTarget],
8484
{ cwd: buildDir },
8585
),
8686
);
8787
const defaultBenchmarkTask = new vscode.Task(
88-
{ type: "meson", mode: "benchmark" },
88+
{ type: "meson", mode: "benchmark", target: pseudoAllTarget },
8989
"Run all benchmarks",
9090
"Meson",
9191
new vscode.ShellExecution(
9292
extensionConfiguration("mesonPath"),
93-
["test", "--benchmark", ...extensionConfiguration("benchmarkOptions")],
93+
["test", "--benchmark", ...extensionConfiguration("benchmarkOptions"), pseudoAllTarget],
9494
{ cwd: buildDir },
9595
),
9696
);

src/treeview/nodes/base.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,8 @@ export abstract class BaseDirectoryNode<T> extends BaseNode {
3131

3232
abstract buildFileTree(fpaths: T[]): FolderMap<T> | Thenable<FolderMap<T>>;
3333
}
34+
35+
// A node in the meson tree view that can be run.
36+
export interface IRunnableNode {
37+
run(): Thenable<any>;
38+
}

src/treeview/nodes/tests.ts

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
import * as vscode from "vscode";
22

33
import { BaseNode } from "../basenode";
4-
import { Test, Tests } from "../../types";
4+
import { Test, Tests, pseudoAllTarget } from "../../types";
55
import { extensionRelative } from "../../utils";
6+
import { IRunnableNode } from "./base";
67

7-
export class TestRootNode extends BaseNode {
8+
function getTestCommand(isBenchmark: boolean): string {
9+
return isBenchmark ? "benchmark" : "test";
10+
}
11+
12+
export class TestRootNode extends BaseNode implements IRunnableNode {
813
constructor(
914
parentId: string,
1015
private readonly tests: Tests,
1116
private readonly isBenchmark: boolean,
1217
) {
13-
super(`${parentId}-${isBenchmark ? "benchmarks" : "tests"}`);
18+
super(`${parentId}-${getTestCommand(isBenchmark)}`);
1419
}
1520

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

29+
// To key in to "when": "view == meson-project && viewItem == meson-test-root" in package.json.
30+
item.contextValue = "meson-test-root";
31+
2432
return item;
2533
}
2634

2735
override getChildren() {
2836
return this.tests.map((test) => new TestNode(this.id, test, this.isBenchmark));
2937
}
38+
39+
run() {
40+
return vscode.commands.executeCommand(`mesonbuild.${getTestCommand(this.isBenchmark)}`, pseudoAllTarget);
41+
}
3042
}
3143

32-
class TestNode extends BaseNode {
44+
class TestNode extends BaseNode implements IRunnableNode {
45+
private readonly taskName: string;
46+
private readonly command: string;
47+
3348
constructor(
3449
parentId: string,
3550
private readonly test: Test,
3651
private readonly isBenchmark: boolean,
3752
) {
3853
super(`${parentId}-${test.suite[0]}-${test.name}`);
54+
55+
this.command = getTestCommand(this.isBenchmark);
56+
const project = this.test.suite[0].split(":")[0];
57+
this.taskName = `${project}:${this.test.name}`;
3958
}
4059

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

4663
item.label = this.test.name;
4764
item.iconPath = extensionRelative("res/meson_32.svg");
4865
item.command = {
49-
title: `Run ${this.isBenchmark ? "benchmark" : "test"}`,
50-
command: `mesonbuild.${this.isBenchmark ? "benchmark" : "test"}`,
51-
arguments: [name],
66+
title: `Run ${this.command}`,
67+
command: `mesonbuild.${this.command}`,
68+
arguments: [this.taskName],
5269
};
5370

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

74+
// To key in to "when": "view == meson-project && viewItem == meson-test" in package.json.
75+
item.contextValue = "meson-test";
76+
5777
return item;
5878
}
79+
80+
run() {
81+
return vscode.commands.executeCommand(`mesonbuild.${this.command}`, this.taskName);
82+
}
5983
}

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,5 @@ export enum SettingsKey {
130130
languageServer = "languageServer",
131131
configureOnOpen = "configureOnOpen",
132132
}
133+
134+
export const pseudoAllTarget = "'*'"; // Quoted for for ShellExecution.

0 commit comments

Comments
 (0)