Skip to content

Commit 9ddd56b

Browse files
committed
Refactor to use inline action buttons
1 parent 1bf93d2 commit 9ddd56b

File tree

15 files changed

+252
-161
lines changed

15 files changed

+252
-161
lines changed

assets/test/.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,9 @@
88
"-DTEST_ARGUMENT_SET_VIA_TEST_BUILD_ARGUMENTS_SETTING"
99
],
1010
"lldb.verboseLogging": true,
11-
"swift.backgroundCompilation": false
11+
"swift.backgroundCompilation": false,
12+
"swift.debugger.useDebugAdapterFromToolchain": false,
13+
"lldb.library": "/usr/lib/liblldb.so",
14+
"lldb.launch.expressions": "native",
15+
"swift.pluginPermissions": {}
1216
}

assets/test/targets/Package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,9 @@ let package = Package(
4040
name: "TargetsTests",
4141
dependencies: ["LibraryTarget"]
4242
),
43+
.testTarget(
44+
name: "AnotherTests",
45+
dependencies: ["LibraryTarget"]
46+
),
4347
]
4448
)
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// The Swift Programming Language
22
// https://docs.swift.org/swift-book
33

4-
func foo() {
4+
public func foo() {
55
print("foo")
6+
}
7+
public func bar() {
8+
print("bar")
69
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import LibraryTarget
2+
import XCTest
3+
4+
class AnotherTests: XCTestCase {
5+
func testExample() {
6+
bar()
7+
}
8+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import LibraryTarget
12
import XCTest
23

34
class TargetsTests: XCTestCase {
45
func testExample() {
6+
foo()
57
}
68
}

package.json

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,14 @@
222222
{
223223
"command": "swift.runSnippet",
224224
"title": "Run Swift Snippet",
225-
"category": "Swift"
225+
"category": "Swift",
226+
"icon": "$(play)"
226227
},
227228
{
228229
"command": "swift.debugSnippet",
229230
"title": "Debug Swift Snippet",
230-
"category": "Swift"
231+
"category": "Swift",
232+
"icon": "$(debug)"
231233
},
232234
{
233235
"command": "swift.runPluginTask",
@@ -266,13 +268,27 @@
266268
},
267269
{
268270
"command": "swift.runAllTestsParallel",
269-
"title": "Run All Tests in Parallel",
270-
"category": "Test"
271+
"title": "Run Tests in Parallel",
272+
"category": "Test",
273+
"icon": "$(testing-run-all-icon)"
271274
},
272275
{
273276
"command": "swift.runAllTests",
274-
"title": "Run All Tests",
275-
"category": "Test"
277+
"title": "Run Tests",
278+
"category": "Test",
279+
"icon": "$(testing-run-icon)"
280+
},
281+
{
282+
"command": "swift.debugAllTests",
283+
"title": "Debug Tests",
284+
"category": "Test",
285+
"icon": "$(testing-debug-icon)"
286+
},
287+
{
288+
"command": "swift.coverAllTests",
289+
"title": "Run Tests with Coverage",
290+
"category": "Test",
291+
"icon": "$(debug-coverage)"
276292
}
277293
],
278294
"configuration": [
@@ -915,6 +931,18 @@
915931
{
916932
"command": "swift.runAllTestsParallel",
917933
"when": "swift.isActivated"
934+
},
935+
{
936+
"command": "swift.runAllTests",
937+
"when": "false"
938+
},
939+
{
940+
"command": "swift.debugAllTests",
941+
"when": "false"
942+
},
943+
{
944+
"command": "swift.coverAllTests",
945+
"when": "false"
918946
}
919947
],
920948
"editor/context": [
@@ -1020,6 +1048,46 @@
10201048
{
10211049
"command": "swift.openExternal",
10221050
"when": "view == projectPanel && (viewItem == 'editing' || viewItem == 'remote')"
1051+
},
1052+
{
1053+
"command": "swift.run",
1054+
"when": "view == projectPanel && viewItem == 'runnable'",
1055+
"group": "inline@0"
1056+
},
1057+
{
1058+
"command": "swift.debug",
1059+
"when": "view == projectPanel && viewItem == 'runnable'",
1060+
"group": "inline@1"
1061+
},
1062+
{
1063+
"command": "swift.runSnippet",
1064+
"when": "view == projectPanel && viewItem == 'snippet_runnable'",
1065+
"group": "inline@0"
1066+
},
1067+
{
1068+
"command": "swift.debugSnippet",
1069+
"when": "view == projectPanel && viewItem == 'snippet_runnable'",
1070+
"group": "inline@1"
1071+
},
1072+
{
1073+
"command": "swift.runAllTests",
1074+
"when": "view == projectPanel && viewItem == 'test_runnable'",
1075+
"group": "inline@0"
1076+
},
1077+
{
1078+
"command": "swift.debugAllTests",
1079+
"when": "view == projectPanel && viewItem == 'test_runnable'",
1080+
"group": "inline@1"
1081+
},
1082+
{
1083+
"command": "swift.runAllTestsParallel",
1084+
"when": "view == projectPanel && viewItem == 'test_runnable'",
1085+
"group": "inline@2"
1086+
},
1087+
{
1088+
"command": "swift.coverAllTests",
1089+
"when": "view == projectPanel && viewItem == 'test_runnable'",
1090+
"group": "inline@3"
10231091
}
10241092
]
10251093
},

src/TestExplorer/TestRunner.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,14 +520,27 @@ export class TestRunner {
520520
];
521521
}
522522

523+
/**
524+
* Extracts a list of unique test Targets from the list of test items.
525+
*/
526+
private testTargets(items: vscode.TestItem[]): string[] {
527+
const targets = new Set<string>();
528+
for (const item of items) {
529+
const target = item.id.split(".")[0];
530+
targets.add(target);
531+
}
532+
return Array.from(targets);
533+
}
534+
523535
/**
524536
* Test run handler. Run a series of tests and extracts the results from the output
525537
* @param shouldDebug Should we run the debugger
526538
* @param token Cancellation token
527539
* @returns When complete
528540
*/
529541
async runHandler() {
530-
this.workspaceContext.testsStarted(this.folderContext, this.testKind);
542+
const testTargets = this.testTargets(this.testArgs.testItems);
543+
this.workspaceContext.testsStarted(this.folderContext, this.testKind, testTargets);
531544

532545
const runState = new TestRunnerTestRunState(this.testRun);
533546

@@ -554,7 +567,7 @@ export class TestRunner {
554567
cancellationDisposable.dispose();
555568
await this.testRun.end();
556569

557-
this.workspaceContext.testsFinished(this.folderContext, this.testKind);
570+
this.workspaceContext.testsFinished(this.folderContext, this.testKind, testTargets);
558571
}
559572

560573
/** Run test session without attaching to a debugger */

src/WorkspaceContext.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,12 @@ export class WorkspaceContext implements vscode.Disposable {
348348
await this.fireEvent(folderContext, FolderOperation.focus);
349349
}
350350

351-
public testsFinished(folder: FolderContext, kind: TestKind) {
352-
this.testFinishEmitter.fire({ kind, folder });
351+
public testsFinished(folder: FolderContext, kind: TestKind, targets: string[]) {
352+
this.testFinishEmitter.fire({ kind, folder, targets });
353353
}
354354

355-
public testsStarted(folder: FolderContext, kind: TestKind) {
356-
this.testStartEmitter.fire({ kind, folder });
355+
public testsStarted(folder: FolderContext, kind: TestKind, targets: string[]) {
356+
this.testStartEmitter.fire({ kind, folder, targets });
357357
}
358358

359359
public buildStarted(
@@ -634,6 +634,7 @@ export class WorkspaceContext implements vscode.Disposable {
634634
interface TestEvent {
635635
kind: TestKind;
636636
folder: FolderContext;
637+
targets: string[];
637638
}
638639

639640
/** Build events for build + run start/stop */

src/commands.ts

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { updateDependencies } from "./commands/dependencies/update";
3838
import { runPluginTask } from "./commands/runPluginTask";
3939
import { runTestMultipleTimes } from "./commands/testMultipleTimes";
4040
import { newSwiftFile } from "./commands/newFile";
41-
import { runAllTests, runAllTestsParallel } from "./commands/runAllTests";
41+
import { runAllTests } from "./commands/runAllTests";
4242
import { updateDependenciesViewList } from "./commands/dependencies/updateDepViewList";
4343
import { runTask } from "./commands/runTask";
4444
import { TestKind } from "./TestExplorer/TestKind";
@@ -84,6 +84,10 @@ export enum Commands {
8484
RUN_SNIPPET = "swift.runSnippet",
8585
DEBUG_SNIPPET = "swift.debugSnippet",
8686
PREVIEW_DOCUMENTATION = "swift.previewDocumentation",
87+
RUN_ALL_TESTS = "swift.runAllTests",
88+
RUN_ALL_TESTS_PARALLEL = "swift.runAllTestsParallel",
89+
DEBUG_ALL_TESTS = "swift.debugAllTests",
90+
COVER_ALL_TESTS = "swift.coverAllTests",
8791
}
8892

8993
/**
@@ -98,8 +102,12 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] {
98102
vscode.commands.registerCommand(Commands.UPDATE_DEPENDENCIES, () =>
99103
updateDependencies(ctx)
100104
),
101-
vscode.commands.registerCommand(Commands.RUN, target => runBuild(ctx, target)),
102-
vscode.commands.registerCommand(Commands.DEBUG, target => debugBuild(ctx, target)),
105+
vscode.commands.registerCommand(Commands.RUN, target =>
106+
runBuild(ctx, ...unwrapTreeItem(target))
107+
),
108+
vscode.commands.registerCommand(Commands.DEBUG, target =>
109+
debugBuild(ctx, ...unwrapTreeItem(target))
110+
),
103111
vscode.commands.registerCommand(Commands.CLEAN_BUILD, () => cleanBuild(ctx)),
104112
vscode.commands.registerCommand(Commands.RUN_TESTS_MULTIPLE_TIMES, item => {
105113
if (ctx.currentFolder) {
@@ -120,9 +128,11 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] {
120128
return openPackage(ctx.toolchain.swiftVersion, ctx.currentFolder.folder);
121129
}
122130
}),
123-
vscode.commands.registerCommand(Commands.RUN_SNIPPET, target => runSnippet(ctx, target)),
131+
vscode.commands.registerCommand(Commands.RUN_SNIPPET, target =>
132+
runSnippet(ctx, ...unwrapTreeItem(target))
133+
),
124134
vscode.commands.registerCommand(Commands.DEBUG_SNIPPET, target =>
125-
debugSnippet(ctx, target)
135+
debugSnippet(ctx, ...unwrapTreeItem(target))
126136
),
127137
vscode.commands.registerCommand(Commands.RUN_PLUGIN_TASK, () => runPluginTask()),
128138
vscode.commands.registerCommand(Commands.RUN_TASK, name => runTask(ctx, name)),
@@ -164,12 +174,20 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] {
164174
),
165175
vscode.commands.registerCommand("swift.captureDiagnostics", () => captureDiagnostics(ctx)),
166176
vscode.commands.registerCommand(
167-
"swift.runAllTestsParallel",
168-
async () => await runAllTestsParallel(ctx)
177+
Commands.RUN_ALL_TESTS_PARALLEL,
178+
async item => await runAllTests(ctx, TestKind.parallel, ...unwrapTreeItem(item))
169179
),
170180
vscode.commands.registerCommand(
171-
"swift.runAllTests",
172-
async (testKind: TestKind) => await runAllTests(ctx, testKind)
181+
Commands.RUN_ALL_TESTS,
182+
async item => await runAllTests(ctx, TestKind.standard, ...unwrapTreeItem(item))
183+
),
184+
vscode.commands.registerCommand(
185+
Commands.DEBUG_ALL_TESTS,
186+
async item => await runAllTests(ctx, TestKind.debug, ...unwrapTreeItem(item))
187+
),
188+
vscode.commands.registerCommand(
189+
Commands.COVER_ALL_TESTS,
190+
async item => await runAllTests(ctx, TestKind.coverage, ...unwrapTreeItem(item))
173191
),
174192
vscode.commands.registerCommand(
175193
Commands.PREVIEW_DOCUMENTATION,
@@ -183,3 +201,16 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] {
183201
),
184202
];
185203
}
204+
205+
/**
206+
* Certain commands can be called via a vscode TreeView, which will pass a {@link CommandNode} object.
207+
* If the command is called via a command palette or other means, the target will be a string.
208+
*/
209+
function unwrapTreeItem(target?: string | { args: string[] }): string[] {
210+
if (typeof target === "object" && target !== null && "args" in target) {
211+
return target.args ?? [];
212+
} else if (typeof target === "string") {
213+
return [target];
214+
}
215+
return [];
216+
}

src/commands/runAllTests.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { TestKind } from "../TestExplorer/TestKind";
1717
import { WorkspaceContext } from "../WorkspaceContext";
1818
import { flattenTestItemCollection } from "../TestExplorer/TestUtils";
1919

20-
export async function runAllTests(ctx: WorkspaceContext, testKind: TestKind) {
20+
export async function runAllTests(ctx: WorkspaceContext, testKind: TestKind, target?: string) {
2121
const testExplorer = ctx.currentFolder?.testExplorer;
2222
if (testExplorer === undefined) {
2323
return;
@@ -28,7 +28,13 @@ export async function runAllTests(ctx: WorkspaceContext, testKind: TestKind) {
2828
return;
2929
}
3030

31-
const tests = flattenTestItemCollection(testExplorer.controller.items);
31+
let tests = flattenTestItemCollection(testExplorer.controller.items);
32+
33+
// If a target is specified, filter the tests to only run those that match the target.
34+
if (target) {
35+
const targetRegex = new RegExp(`^${target}(\\.|$)`);
36+
tests = tests.filter(test => targetRegex.test(test.id));
37+
}
3238
const tokenSource = new vscode.CancellationTokenSource();
3339
await profile.runHandler(
3440
new vscode.TestRunRequest(tests, undefined, profile),
@@ -37,7 +43,3 @@ export async function runAllTests(ctx: WorkspaceContext, testKind: TestKind) {
3743

3844
await vscode.commands.executeCommand("testing.showMostRecentOutput");
3945
}
40-
41-
export async function runAllTestsParallel(ctx: WorkspaceContext) {
42-
await runAllTests(ctx, TestKind.parallel);
43-
}

0 commit comments

Comments
 (0)