Skip to content

Commit 46a13a7

Browse files
authored
Code Lenses for Tests (#1698)
* Code Lenses for Tests When the `swift.showTestCodeLenses` setting is `true`, show code lenses inline in the editor above suites and tests. This setting defaults to `false` and must be enabled first. The three lenses are Run, Debug, and Run w/ Coverage.
1 parent c58c5d9 commit 46a13a7

File tree

9 files changed

+347
-88
lines changed

9 files changed

+347
-88
lines changed

CHANGELOG.md

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
### Added
66

7+
- Added code lenses to run suites/tests, configurable with the `swift.showTestCodeLenses` setting ([#1698](https://github.com/swiftlang/vscode-swift/pull/1698))
8+
9+
## 2.8.0 - 2025-07-14
10+
11+
### Added
12+
713
- Add clickable toolchain selection to Swift version status bar item ([#1674](https://github.com/swiftlang/vscode-swift/pull/1674))
814
- Add macOS support for Swiftly toolchain management ([#1673](https://github.com/swiftlang/vscode-swift/pull/1673))
915
- Show revision hash or local/editing keyword in project panel dependency descriptions ([#1667](https://github.com/swiftlang/vscode-swift/pull/1667))
@@ -15,6 +21,7 @@
1521
- Fix test explorer tests not updating on document modification ([#1663](https://github.com/swiftlang/vscode-swift/pull/1663))
1622
- Fix improper parenting of tests w/ identical names in explorer ([#1664](https://github.com/swiftlang/vscode-swift/pull/1664))
1723
- Ensure document symbols are provided for folders in multi-root workspaces ([#1668](https://github.com/swiftlang/vscode-swift/pull/1668))
24+
- Fix comment regex not handling params/types/fn names containing `func` ([#1697](https://github.com/swiftlang/vscode-swift/pull/1697))
1825
- Prepend `/// ` when continuing documentation comments on a new line ([#1703](https://github.com/swiftlang/vscode-swift/pull/1703))
1926
- Respect `files.exclude` setting values set to `false` ([#1696](https://github.com/swiftlang/vscode-swift/pull/1696))
2027

@@ -83,7 +90,7 @@
8390
### Fixed
8491

8592
- Prevent duplicate reload extension notifications from appearing ([#1473](https://github.com/swiftlang/vscode-swift/pull/1473))
86-
- "Actual" and "Expected" values are shown in the right order on test failure ([#1444](https://github.com/swiftlang/vscode-swift/issues/1444))
93+
- Actual and Expected values are shown in the right order on test failure ([#1444](https://github.com/swiftlang/vscode-swift/issues/1444))
8794
- Correctly set the `DEVELOPER_DIR` environment variable when selecting between two Xcode installs ([#1433](https://github.com/swiftlang/vscode-swift/pull/1433))
8895
- Prompt to reload the extension when swiftEnvironmentVariables is changed ([#1430](https://github.com/swiftlang/vscode-swift/pull/1430))
8996
- Search for Swift packages in sub-folders of the workspace ([#1425](https://github.com/swiftlang/vscode-swift/pull/1425))
@@ -209,8 +216,8 @@ The new extension id is `swiftlang.swift-vscode`.
209216

210217
### Changed
211218

212-
- Add setting to exclude files/directories from code coverage results.
213-
- Updated and refined settings descriptions.
219+
- Add setting to exclude files/directories from code coverage results
220+
- Updated and refined settings descriptions
214221
- Added "throws" section to doc comment template
215222

216223
### Fixed
@@ -269,7 +276,7 @@ The new extension id is `swiftlang.swift-vscode`.
269276

270277
- Fix XCTest argument format when debugging multiple tests
271278
- Add user defined and optional sanitizer/diagnostics arguments to test builds
272-
- Silence Terminal on test runs.
279+
- Silence Terminal on test runs
273280

274281
## 1.10.0 - 2024-06-07
275282

@@ -299,13 +306,16 @@ The new extension id is `swiftlang.swift-vscode`.
299306
## 1.9.0 - 2024-04-15
300307

301308
### Added
309+
302310
- Running tests in parallel. It is available from the drop-down next to the run button at the top of the TestExplorer. It is not available while debugging and parsing of XCT failure messages does not work prior to Swift 6.
303311

304312
### Changed
313+
305314
- If using Swift 5.10 allow for InlayHint text edits.
306315
- If using Swift 6 name of debug adapter has changed from `lldb-vscode` to `lldb-dap`.
307316

308317
### Fixed
318+
309319
- Don't check if line above is a comment if you are on line 0 in comment completion code.
310320

311321
## 1.8.1 - 2024-03-06
@@ -317,13 +327,15 @@ The new extension id is `swiftlang.swift-vscode`.
317327
## 1.8.0 - 2024-02-21
318328

319329
### Added
330+
320331
- Platform specific settings in the swift task definition.
321332
- Environment variables to set while running a swift task.
322333
- Setting to disable all Swift Package Manager integrations.
323334
- Activate extension when debugging.
324335
- Watch for changes to swift files in test targets and flag 'test discovery is required' if a file changes or is deleted.
325336

326337
### Changed
338+
327339
- Expand `~` in swift file path setting to home directory.
328340
- Don't create test explorer if project has no tests.
329341
- Only run test discovery after a build all task.
@@ -334,21 +346,26 @@ The new extension id is `swiftlang.swift-vscode`.
334346
## 1.7.2 - 2024-01-03
335347

336348
### Added
349+
337350
- Setting to control action after a build error: focus on problems pane, focus on terminal or do nothing.
338351

339-
### Changes
352+
### Changed
353+
340354
- Don't force show test pane when testing starts. Let `Testing: Open Testing` define when test pane should open.
341355

342356
### Fixed
357+
343358
- Setup of URI on readonly document viewer. This fixes jump to symbol in a swiftinterface on Windows
344359

345360
## 1.7.1 - 2023-12-02
346361

347362
### Added
363+
348364
- Task queue operation to spawn a process and parse its output. Using this ensures a build task does not run at the same time.
349365
- Use spawn process task queue operation in test discovery and unedit of modules.
350366

351-
### Changes
367+
### Changed
368+
352369
- Don't wait for SwiftPM plugin listing to finish before allowing build and run.
353370
- If auto-resolve is disabled then also disable the initial test discovery as this can cause a resolve
354371

@@ -359,7 +376,7 @@ The new extension id is `swiftlang.swift-vscode`.
359376

360377
Merge debug adapter changes from v1.6.x prerelease builds into main release.
361378

362-
### Changes
379+
### Changed
363380

364381
- Consolidate common debug configurations when building debug configurations.
365382

@@ -369,8 +386,6 @@ Merge debug adapter changes from v1.6.x prerelease builds into main release.
369386
- Increase the size of stdout available to `llvm-cov` process. This fixes displaying test coverage for larger projects.
370387
- Build product instead of target when compiling Swift Snippets. This fixes running of Snippets on macOS.
371388

372-
### Fixed
373-
374389
## 1.6.1 - 2023-10-04 (Toolchain debug adapter preview)
375390

376391
### Added
@@ -429,17 +444,20 @@ Merge debug adapter changes from v1.6.x prerelease builds into main release.
429444
## 1.4.0 - 2023-07-05
430445

431446
### Added
447+
432448
- Add sanitizer build setting
433449
- Build tasks are not available while other tasks are running on the package
434450
- Add read-only document provider for swiftinterface files in preparation for go to definition for stdlib/framework symbols.
435451

436452
### Changed
453+
437454
- Add supported language configuration setting to replace Support C/C++ setting
438455
- deprecate Support C/C++ setting
439456
- Remove a number of unnecessary build arguments for Windows when using Swift 5.9 or later
440457
- Configure vscode-lldb to use native expressions
441458

442459
### Fixed
460+
443461
- Require a reload when using the select Xcode developer directory command
444462
- Reporting of errors returned by the compiler without a column number
445463

@@ -579,15 +597,15 @@ Merge debug adapter changes from v1.6.x prerelease builds into main release.
579597
### Added
580598

581599
- Support for Swift Snippets (requires Swift 5.7). Two new commands have been added `Run Swift Snippet` and `Debug Swift Snippet`.
582-
- Sub menu to text editor right click menu. Includes commands not acccessible elsewhere `Run Swift Script`, Snippet commands and `Clean Build`.
600+
- Sub menu to text editor right click menu. Includes commands not accessible elsewhere `Run Swift Script`, Snippet commands and `Clean Build`.
583601
- macOS: Command to choose between macOS, iOS, tvOS and watchOS targets. Switching to a non macOS target will give you symbol completion for that target, but building your package will have undefined results.
584602
- macOS: Command to choose between Swift toolchains from all versions of Xcode installed on your system.
585603

586604
### Changed
587605

588606
- When working out project dependencies traverse local dependencies to get full dependency chain
589607
- Changed settings scope for a number of settings so they can be set per workspace folder
590-
- Store hash of `Package.resolved` to compare with new `Package.resolved` whenever it has been updated, to ensure it has actaully changed before running `swift package resolve`.
608+
- Store hash of `Package.resolved` to compare with new `Package.resolved` whenever it has been updated, to ensure it has actually changed before running `swift package resolve`.
591609

592610
### Fixed
593611

@@ -662,7 +680,6 @@ Merge debug adapter changes from v1.6.x prerelease builds into main release.
662680
### Fixed
663681

664682
- Running non-Swift LLDB on Windows
665-
666683
## 0.5.0 - 2022-05-02
667684

668685
Version 0.5.0 of vscode-swift now requires v1.65.0 of Visual Studio Code
@@ -759,10 +776,10 @@ Version 0.5.0 of vscode-swift now requires v1.65.0 of Visual Studio Code
759776

760777
- Automatic generation of launch target for running tests. This is no longer needed now we have the test explorer.
761778

762-
763779
## 0.3.0 - 2022-02-22
764780

765781
### Added
782+
766783
- Function documentation comment completion. Type "///" on line above function to activate.
767784
- Package dependency view has new right click menu. Menu entries include:
768785
- Use Local Version: Use local version of package dependency.
@@ -774,6 +791,7 @@ Version 0.5.0 of vscode-swift now requires v1.65.0 of Visual Studio Code
774791
- Support for building development version of package via `npm run dev-package`.
775792

776793
### Changed
794+
777795
- Build terminal window is cleared before a build
778796
- When the Swift path or SourceKit-LSP path are changed the extension will restart to ensure the correct versions are used.
779797

@@ -785,6 +803,7 @@ Version 0.5.0 of vscode-swift now requires v1.65.0 of Visual Studio Code
785803
## 0.2.0 - 2022-01-20
786804

787805
### Added
806+
788807
- Build tasks for all folders in the workspace.
789808
- Resolve and update commands which update current folder.
790809
- Reset package and clean build commands.
@@ -795,10 +814,12 @@ Version 0.5.0 of vscode-swift now requires v1.65.0 of Visual Studio Code
795814
- Cache contents of Package.resolved for use across different systems.
796815

797816
### Changed
817+
798818
- Cleanup Language client code
799819
- Package dependency view updates based on current folder
800820

801821
### Fixed
822+
802823
- Use correct workspace folder in launch.json program name
803824

804825
## 0.1.1 - 2021-12-27

package.json

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,27 @@
306306
"category": "Test",
307307
"icon": "$(debug-coverage)"
308308
},
309+
{
310+
"command": "swift.runTest",
311+
"title": "Run Test",
312+
"category": "Test",
313+
"icon": "$(testing-run-icon)",
314+
"enablement": "false"
315+
},
316+
{
317+
"command": "swift.debugTest",
318+
"title": "Debug Test",
319+
"category": "Test",
320+
"icon": "$(testing-debug-icon)",
321+
"enablement": "false"
322+
},
323+
{
324+
"command": "swift.runTestWithCoverage",
325+
"title": "Run Test with Coverage",
326+
"category": "Test",
327+
"icon": "$(debug-coverage)",
328+
"enablement": "false"
329+
},
309330
{
310331
"command": "swift.openDocumentation",
311332
"title": "Open Documentation",
@@ -562,7 +583,7 @@
562583
}
563584
},
564585
{
565-
"title": "Code Coverage",
586+
"title": "Testing",
566587
"properties": {
567588
"swift.excludeFromCodeCoverage": {
568589
"description": "A list of paths to exclude from code coverage reports. Paths can be absolute or relative to the workspace root.",
@@ -572,6 +593,23 @@
572593
},
573594
"default": [],
574595
"scope": "machine-overridable"
596+
},
597+
"swift.showTestCodeLenses": {
598+
"type": [
599+
"boolean",
600+
"array"
601+
],
602+
"default": true,
603+
"markdownDescription": "Controls whether or not to show inline code lenses for running and debugging tests inline, above test and suite declarations. If set to an array, specify one or more of the following: 'run', 'debug', 'coverage'.",
604+
"scope": "application",
605+
"items": {
606+
"type": "string",
607+
"enum": [
608+
"run",
609+
"debug",
610+
"coverage"
611+
]
612+
}
575613
}
576614
}
577615
},
@@ -1044,6 +1082,18 @@
10441082
"command": "swift.coverAllTests",
10451083
"when": "swift.isActivated"
10461084
},
1085+
{
1086+
"command": "swift.runTest",
1087+
"when": "false"
1088+
},
1089+
{
1090+
"command": "swift.debugTest",
1091+
"when": "false"
1092+
},
1093+
{
1094+
"command": "swift.runTestWithCoverage",
1095+
"when": "false"
1096+
},
10471097
{
10481098
"command": "swift.openEducationalNote",
10491099
"when": "false"
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the VS Code Swift open source project
4+
//
5+
// Copyright (c) 2021-2025 the VS Code Swift project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of VS Code Swift project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import * as vscode from "vscode";
16+
import { TestExplorer } from "./TestExplorer";
17+
import { flattenTestItemCollection } from "./TestUtils";
18+
import configuration, { ValidCodeLens } from "../configuration";
19+
20+
export class TestCodeLensProvider implements vscode.CodeLensProvider, vscode.Disposable {
21+
private onDidChangeCodeLensesEmitter = new vscode.EventEmitter<void>();
22+
public onDidChangeCodeLenses = this.onDidChangeCodeLensesEmitter.event;
23+
private disposables: vscode.Disposable[] = [];
24+
25+
constructor(private testExplorer: TestExplorer) {
26+
this.disposables = [
27+
testExplorer.onTestItemsDidChange(() => this.onDidChangeCodeLensesEmitter.fire()),
28+
vscode.languages.registerCodeLensProvider({ language: "swift", scheme: "file" }, this),
29+
];
30+
}
31+
32+
dispose() {
33+
this.disposables.forEach(disposable => disposable.dispose());
34+
}
35+
36+
public provideCodeLenses(
37+
document: vscode.TextDocument,
38+
_token: vscode.CancellationToken
39+
): vscode.ProviderResult<vscode.CodeLens[]> {
40+
const config = configuration.showTestCodeLenses;
41+
if (config === false || (Array.isArray(config) && config.length === 0)) {
42+
return [];
43+
}
44+
45+
const items = flattenTestItemCollection(this.testExplorer.controller.items);
46+
return items
47+
.filter(item => item.uri?.fsPath === document.uri.fsPath)
48+
.flatMap(item => this.codeLensesForTestItem(item, config));
49+
}
50+
51+
private codeLensesForTestItem(
52+
item: vscode.TestItem,
53+
config: boolean | ValidCodeLens[]
54+
): vscode.CodeLens[] {
55+
if (!item.range) {
56+
return [];
57+
}
58+
59+
const lensConfigs: Array<{
60+
type: ValidCodeLens;
61+
title: string;
62+
command: string;
63+
}> = [
64+
{
65+
type: "run",
66+
title: "$(play)\u00A0Run",
67+
command: "swift.runTest",
68+
},
69+
{
70+
type: "debug",
71+
title: "$(debug)\u00A0Debug",
72+
command: "swift.debugTest",
73+
},
74+
{
75+
type: "coverage",
76+
title: "$(debug-coverage)\u00A0Run w/ Coverage",
77+
command: "swift.runTestWithCoverage",
78+
},
79+
];
80+
81+
return lensConfigs
82+
.filter(
83+
lensConfig =>
84+
config === true || (Array.isArray(config) && config.includes(lensConfig.type))
85+
)
86+
.map(
87+
lensConfig =>
88+
new vscode.CodeLens(item.range!, {
89+
title: lensConfig.title,
90+
command: lensConfig.command,
91+
arguments: [item],
92+
})
93+
);
94+
}
95+
}

0 commit comments

Comments
 (0)