Skip to content

Commit a962066

Browse files
authored
Show setup message when no targets returned from sync (#15)
When a sync completes and returns no targets, it's likely that the user needs to make adjustments to their .bazelproject file. This change adds guidance for the user to resolve issues and re-sync: - When no targets are returned, error message shown immediately below the root item, with access to .bazelproject file. This only supports one line, so we can't include full details here. - Detailed instructions will be surfaced at the top of the .bazelproject file, and in the lower test results panel: ![image](https://github.com/uber/vscode-bazel-bsp/assets/92764374/38d3d462-a935-47eb-b6fa-0c988609e946) ![image](https://github.com/uber/vscode-bazel-bsp/assets/92764374/af770943-4193-4e0e-8cdd-abd85ddcb9a7)
1 parent 956cbaf commit a962066

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

src/test-explorer/resolver.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
159159
parentTest,
160160
'Loading: waiting for build server connection'
161161
)
162+
parentTest.error = undefined
162163
const conn = await this.buildServer.getConnection()
163164

164165
updateDescription(parentTest, 'Loading: fetching available targets')
@@ -212,6 +213,25 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
212213
relevantParent.children.add(newTest)
213214
})
214215

216+
// If no test items were added, show the getting started message as a test message overlaid on the .bazelproject file.
217+
// This provides an opportunity for the user to make adjustments and re-sync.
218+
if (parentTest.children.size === 0) {
219+
// Dummy test run that overlays the getting started message on the .bazelproject file.
220+
const run = this.store.testController.createTestRun(
221+
new vscode.TestRunRequest()
222+
)
223+
run.errored(parentTest, new vscode.TestMessage(gettingStartedMessage))
224+
run.end()
225+
226+
// Link in the test explorer tree to set up the project.
227+
const encodedFileUri = encodeURIComponent(JSON.stringify(parentTest.uri))
228+
const syncFailMessage = new vscode.MarkdownString(
229+
`No test targets found. [Setup your project](command:vscode.open?${encodedFileUri})`
230+
)
231+
syncFailMessage.isTrusted = true
232+
parentTest.error = syncFailMessage
233+
}
234+
215235
// Replace all children with the newly returned test cases.
216236
this.condenseTestItems(parentTest)
217237
updateDescription(parentTest)
@@ -413,3 +433,19 @@ function combineCancelTokens(
413433
token2?.onCancellationRequested(() => combinedSource.cancel())
414434
return combinedSource.token
415435
}
436+
437+
const gettingStartedMessage = new vscode.MarkdownString(
438+
`To use the Test Explorer, please configure your project.
439+
440+
Getting started tips:
441+
- Update this file with some paths that include test targets.
442+
- Use the directories key to specify by directory
443+
- Use the targets key to specify by Bazel target pattern
444+
- Ensure that the bazel_binary field in this file matches the path to your Bazel binary.
445+
- Re-sync at any time by clicking the $(extensions-refresh) refresh icon at the very top of the testing panel.
446+
447+
Think something else went wrong? Check the output [here](command:bazelbsp.showServerOutput).
448+
`,
449+
true
450+
)
451+
gettingStartedMessage.isTrusted = true

src/test-info/test-item-factory.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export class TestItemFactory {
3636
'Bazel Test Targets',
3737
uri
3838
)
39+
newTest.range = new vscode.Range(0, 0, 0, 0)
3940
newTest.canResolveChildren = true
4041
this.store.testCaseMetadata.set(
4142
newTest,

src/test/suite/resolver.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,30 @@ suite('Test Resolver', () => {
344344
}
345345
})
346346

347+
test('no targets returned', async () => {
348+
const root = testCaseStore.testController.createTestItem(
349+
'root',
350+
'Bazel Test Targets'
351+
)
352+
testCaseStore.testController.items.add(root)
353+
testCaseStore.testCaseMetadata.set(
354+
root,
355+
new TestCaseInfo(root, undefined, TestItemType.Root)
356+
)
357+
assert.ok(testCaseStore.testController.resolveHandler)
358+
359+
// Simulate an empty result from requesting targets.
360+
const emptyResult: bsp.WorkspaceBuildTargetsResult = {
361+
targets: [],
362+
}
363+
const sendRequestStub = sandbox
364+
.stub(sampleConn, 'sendRequest')
365+
.resolves(emptyResult)
366+
await testCaseStore.testController.resolveHandler(root)
367+
const message = root.error as vscode.MarkdownString
368+
assert.ok(message.value.includes('No test targets found'))
369+
})
370+
347371
test('source files within a target', async () => {
348372
const buildTarget = sampleBuildTargetsResult.targets[0]
349373
const sendRequestStub = sandbox

0 commit comments

Comments
 (0)