Skip to content

Commit 3418b76

Browse files
authored
enhancement: refresh test unit treeview with specific path (#1842)
* enhancement: refresh test unit treeview for specfic ur; * fix: update
1 parent 4efa9fa commit 3418b76

3 files changed

Lines changed: 51 additions & 7 deletions

File tree

src/commands/testExplorerCommands.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import { DebugConfiguration, TestItem, TestRunRequest } from 'vscode';
4+
import { DebugConfiguration, TestItem, TestRunRequest, Uri } from 'vscode';
55
import { sendInfo } from 'vscode-extension-telemetry-wrapper';
6-
import { runTests, testController } from '../controller/testController';
6+
import { loadChildren, runTests, testController } from '../controller/testController';
77
import { loadJavaProjects } from '../controller/utils';
88
import { showTestItemsInCurrentFile } from '../extension';
99

@@ -39,10 +39,46 @@ export async function runTestsFromTestExplorer(testItem: TestItem, launchConfigu
3939

4040
export async function refreshExplorer(): Promise<void> {
4141
sendInfo('', { name: 'refreshTests' });
42+
43+
await loadJavaProjects();
44+
45+
// Force re-resolution of all existing project roots
46+
const loadPromises: Promise<void>[] = [];
4247
testController?.items.forEach((root: TestItem) => {
43-
testController?.items.delete(root.id);
48+
loadPromises.push(loadChildren(root));
4449
});
50+
await Promise.all(loadPromises);
4551

46-
await loadJavaProjects();
52+
await showTestItemsInCurrentFile();
53+
}
54+
55+
/**
56+
* Refresh only the project subtree that matches the given classpath-change URI.
57+
* Falls back to a full (incremental) refresh if no matching project is found.
58+
*/
59+
export async function refreshProject(classpathUri: Uri): Promise<void> {
60+
sendInfo('', { name: 'refreshProject' });
61+
const uriString: string = classpathUri.toString();
62+
63+
// Find the project root with the longest matching URI prefix (most specific match)
64+
let matchedProject: TestItem | undefined;
65+
let matchedUriLength: number = 0;
66+
testController?.items.forEach((root: TestItem) => {
67+
if (root.uri) {
68+
const rootUriString: string = root.uri.toString();
69+
if (uriString.startsWith(rootUriString) && rootUriString.length > matchedUriLength) {
70+
matchedProject = root;
71+
matchedUriLength = rootUriString.length;
72+
}
73+
}
74+
});
75+
76+
if (matchedProject) {
77+
// Re-resolve only the matched project's children
78+
await loadChildren(matchedProject);
79+
} else {
80+
// No matching project found – do incremental full refresh
81+
await loadJavaProjects();
82+
}
4783
await showTestItemsInCurrentFile();
4884
}

src/controller/utils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ export async function loadJavaProjects(): Promise<void> {
3434
return project.testKind !== TestKind.None;
3535
});
3636

37+
// Remove projects that no longer exist
38+
const projectIds: Set<string> = new Set(testProjects.map((p: IJavaTestItem) => p.id));
39+
testController?.items.forEach((root: TestItem) => {
40+
if (!projectIds.has(root.id)) {
41+
testController?.items.delete(root.id);
42+
}
43+
});
44+
3745
for (const project of testProjects) {
3846
if (testController?.items.get(project.id)) {
3947
continue;

src/extension.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentO
77
import { navigateToTestOrTarget } from './commands/navigation/navigationCommands';
88
import { generateTests } from './commands/generationCommands';
99
import { runTestsFromJavaProjectExplorer } from './commands/projectExplorerCommands';
10-
import { refreshExplorer, runTestsFromTestExplorer } from './commands/testExplorerCommands';
10+
import { refreshExplorer, refreshProject, runTestsFromTestExplorer } from './commands/testExplorerCommands';
1111
import { openStackTrace } from './commands/testReportCommands';
1212
import { Context, ExtensionName, JavaTestRunnerCommands, VSCodeCommands } from './constants';
1313
import { createTestController, testController, watchers } from './controller/testController';
@@ -76,11 +76,11 @@ async function doActivate(_operationId: string, context: ExtensionContext): Prom
7676

7777
if (extensionApi.onDidClasspathUpdate) {
7878
const onDidClasspathUpdate: Event<Uri> = extensionApi.onDidClasspathUpdate;
79-
context.subscriptions.push(onDidClasspathUpdate(async () => {
79+
context.subscriptions.push(onDidClasspathUpdate(async (uri: Uri) => {
8080
// workaround: wait more time to make sure Language Server has updated all caches
8181
setTimeout(() => {
8282
testSourceProvider.clear();
83-
refreshExplorer();
83+
refreshProject(uri);
8484
}, 1000 /* ms */);
8585
}));
8686
}

0 commit comments

Comments
 (0)