Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,44 +74,44 @@
"view/title": [
{
"command": "java.test.explorer.runAll",
"when": "view == testExplorer",
"when": "view == testExplorer && java:serverMode != LightWeight",
"group": "navigation@0"
},
{
"command": "java.test.explorer.debugAll",
"when": "view == testExplorer",
"when": "view == testExplorer && java:serverMode != LightWeight",
"group": "navigation@1"
},
{
"command": "java.test.explorer.refresh",
"when": "view == testExplorer",
"when": "view == testExplorer && java:serverMode != LightWeight",
"group": "navigation@2"
}
],
"view/item/context": [
{
"command": "java.test.explorer.run",
"when": "view == testExplorer",
"when": "view == testExplorer && viewItem != UNTESTABLE_NODE",
"group": "testExplorer@0"
},
{
"command": "java.test.explorer.debug",
"when": "view == testExplorer",
"when": "view == testExplorer && viewItem != UNTESTABLE_NODE",
"group": "testExplorer@1"
},
{
"command": "java.test.explorer.refresh",
"when": "view == testExplorer",
"when": "view == testExplorer && viewItem != UNTESTABLE_NODE",
"group": "testExplorer@4"
},
{
"command": "java.test.explorer.run",
"when": "view == testExplorer",
"when": "view == testExplorer && viewItem != UNTESTABLE_NODE",
"group": "inline@0"
},
{
"command": "java.test.explorer.debug",
"when": "view == testExplorer",
"when": "view == testExplorer && viewItem != UNTESTABLE_NODE",
"group": "inline@1"
}
],
Expand All @@ -127,6 +127,18 @@
{
"command": "java.test.explorer.refresh",
"when": "never"
},
{
"command": "java.test.explorer.runAll",
"when": "java:serverMode != LightWeight"
},
{
"command": "java.test.explorer.debugAll",
"when": "java:serverMode != LightWeight"
},
{
"command": "java.test.cancel",
"when": "java:serverMode != LightWeight"
}
]
},
Expand Down
2 changes: 2 additions & 0 deletions src/constants/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

export namespace JavaLanguageServerCommands {
export const EXECUTE_WORKSPACE_COMMAND: string = 'java.execute.workspaceCommand';
export const SWITCH_SERVER_MODE: string = 'java.server.mode.switch';
}

export namespace JavaTestRunnerDelegateCommands {
Expand All @@ -28,4 +29,5 @@ export namespace JavaTestRunnerCommands {
export const OPEN_TEST_LOG: string = 'java.test.open.log';
export const JAVA_TEST_CANCEL: string = 'java.test.cancel';
export const JAVA_CONFIG_MIGRATE: string = 'java.test.config.migrate';
export const JAVA_TEST_SWITCH_SERVER_MODE: string = 'java.test.switch.server.mode';
}
41 changes: 40 additions & 1 deletion src/explorer/testExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
// Licensed under the MIT license.

import * as path from 'path';
import { Command, Disposable, Event, EventEmitter, ExtensionContext, Range, ThemeIcon, TreeDataProvider, TreeItem, TreeItemCollapsibleState, Uri, workspace, WorkspaceFolder } from 'vscode';
import { Command, Disposable, Event, EventEmitter, ExtensionContext, extensions, Range, ThemeIcon, TreeDataProvider, TreeItem, TreeItemCollapsibleState, Uri, workspace, WorkspaceFolder } from 'vscode';
import { JavaTestRunnerCommands } from '../constants/commands';
import { isStandardServerReady, isSwitchingServer } from '../extension';
import { ITestItem, TestKind, TestLevel } from '../protocols';
import { ITestResult, TestStatus } from '../runners/models';
import { testFileWatcher } from '../testFileWatcher';
import { testItemModel } from '../testItemModel';
import { testResultManager } from '../testResultManager';

const LIGHTWEIGHT_NODE_ID: string = ':LIGHTWEIGHT_MODE:';
export class TestExplorer implements TreeDataProvider<ITestItem>, Disposable {
public readonly testExplorerViewId: string = 'testExplorer';

Expand All @@ -24,6 +26,20 @@ export class TestExplorer implements TreeDataProvider<ITestItem>, Disposable {
}

public getTreeItem(element: ITestItem): TreeItem | Thenable<TreeItem> {
if (element.id === LIGHTWEIGHT_NODE_ID) {
return {
label: element.displayName,
collapsibleState: TreeItemCollapsibleState.None,
command: {
command: JavaTestRunnerCommands.JAVA_TEST_SWITCH_SERVER_MODE,
title: 'Switch to Standard mode',
},
contextValue: 'UNTESTABLE_NODE',
tooltip: 'Switch the Java Language Server to Standard mode to show all the test cases',
iconPath: new ThemeIcon('info'),
};
}

return {
label: element.displayName,
collapsibleState: this.resolveCollapsibleState(element),
Expand All @@ -34,6 +50,29 @@ export class TestExplorer implements TreeDataProvider<ITestItem>, Disposable {
}

public async getChildren(element?: ITestItem): Promise<ITestItem[]> {
if (isSwitchingServer()) {
await new Promise<void>((resolve: () => void): void => {
extensions.getExtension('redhat.java')!.exports.onDidServerModeChange(resolve);
});
}
if (!isStandardServerReady()) {
return [
{
id: LIGHTWEIGHT_NODE_ID,
displayName: 'Click to load test cases...',
fullName: LIGHTWEIGHT_NODE_ID,
kind: TestKind.None,
project: '',
level: TestLevel.Folder,
paramTypes: [],
location: {
uri: '',
range: new Range(0, 0, 0, 0),
},
children: undefined,
},
];
}
let nodes: ITestItem[] = [];
if (!element) {
nodes = this.getWorkspaceFolders();
Expand Down
70 changes: 58 additions & 12 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import * as fse from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import { DebugConfiguration, Event, Extension, ExtensionContext, extensions, Range, Uri, window } from 'vscode';
import { commands, DebugConfiguration, Event, Extension, ExtensionContext, extensions, Range, Uri, window } from 'vscode';
import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation, instrumentOperationAsVsCodeCommand } from 'vscode-extension-telemetry-wrapper';
import { testCodeLensController } from './codelens/TestCodeLensController';
import { debugTestsFromExplorer, openTextDocument, runTestsFromExplorer } from './commands/explorerCommands';
import { openLogFile, showOutputChannel } from './commands/logCommands';
import { runFromCodeLens } from './commands/runFromCodeLens';
import { JavaTestRunnerCommands } from './constants/commands';
import { JavaLanguageServerCommands, JavaTestRunnerCommands } from './constants/commands';
import { testExplorer } from './explorer/testExplorer';
import { logger } from './logger/logger';
import { ITestItem } from './protocols';
Expand All @@ -34,6 +34,39 @@ export async function deactivate(): Promise<void> {
}

async function doActivate(_operationId: string, context: ExtensionContext): Promise<void> {
const extension: Extension<any> | undefined = extensions.getExtension('redhat.java');
if (extension && extension.isActive) {
const extensionApi: any = extension.exports;
if (!extensionApi) {
return;
}

serverMode = extensionApi.serverMode;

if (extensionApi.onDidClasspathUpdate) {
const onDidClasspathUpdate: Event<Uri> = extensionApi.onDidClasspathUpdate;
context.subscriptions.push(onDidClasspathUpdate(async () => {
await testFileWatcher.registerListeners(true /*enableDebounce*/);
}));
}

if (extensionApi.onDidServerModeChange) {
const onDidServerModeChange: Event<string> = extensionApi.onDidServerModeChange;
context.subscriptions.push(onDidServerModeChange(async (mode: string) => {
serverMode = mode;
testExplorer.refresh();
await testFileWatcher.registerListeners();
}));
}

if (extensionApi.onDidProjectsImport) {
const onDidProjectsImport: Event<Uri[]> = extensionApi.onDidProjectsImport;
context.subscriptions.push(onDidProjectsImport(async () => {
await testFileWatcher.registerListeners(true /*enableDebounce*/);
}));
}
}

await testFileWatcher.registerListeners();
testExplorer.initialize(context);
runnerScheduler.initialize(context);
Expand Down Expand Up @@ -66,17 +99,30 @@ async function doActivate(_operationId: string, context: ExtensionContext): Prom
instrumentOperationAsVsCodeCommand(JavaTestRunnerCommands.OPEN_TEST_LOG, async () => await openLogFile(storagePath)),
instrumentOperationAsVsCodeCommand(JavaTestRunnerCommands.JAVA_TEST_CANCEL, async () => await runnerScheduler.cleanUp(true /* isCancel */)),
instrumentOperationAsVsCodeCommand(JavaTestRunnerCommands.JAVA_CONFIG_MIGRATE, async () => await migrateTestConfig()),
instrumentOperationAsVsCodeCommand(JavaTestRunnerCommands.JAVA_TEST_SWITCH_SERVER_MODE, async () => {
if (isSwitchingServer()) {
return;
}
await commands.executeCommand(JavaLanguageServerCommands.SWITCH_SERVER_MODE);
}),
);
}

// refetch the test source path on projectss classpath updated.
const extension: Extension<any> | undefined = extensions.getExtension('redhat.java');
if (extension && extension.isActive) {
const extensionApi: any = extension.exports;
if (extensionApi && extensionApi.onDidClasspathUpdate) {
const onDidClasspathUpdate: Event<Uri> = extensionApi.onDidClasspathUpdate;
context.subscriptions.push(onDidClasspathUpdate(async () => {
await testFileWatcher.registerListeners(true /*enableDebounce*/);
}));
}
export function isStandardServerReady(): boolean {
// undefined serverMode indicates an older version language server
if (serverMode === undefined) {
return true;
}

if (serverMode !== 'Standard') {
return false;
}

return true;
}

export function isSwitchingServer(): boolean {
return serverMode === 'Hybrid';
}

let serverMode: string | undefined;
4 changes: 4 additions & 0 deletions src/testFileWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as _ from 'lodash';
import { Disposable, FileSystemWatcher, RelativePattern, Uri, workspace, WorkspaceFolder } from 'vscode';
import { testCodeLensController } from './codelens/TestCodeLensController';
import { testExplorer } from './explorer/testExplorer';
import { isStandardServerReady } from './extension';
import { logger } from './logger/logger';
import { ITestItem, TestLevel } from './protocols';
import { testItemModel } from './testItemModel';
Expand Down Expand Up @@ -36,6 +37,9 @@ class TestFileWatcher implements Disposable {
}

protected async registerListenersInternal(): Promise<void> {
if (!isStandardServerReady()) {
return;
}
this.dispose();
if (workspace.workspaceFolders) {
try {
Expand Down