Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List children of a class #1242

Merged
merged 1 commit into from
Jul 28, 2021
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
1 change: 1 addition & 0 deletions java-extension/com.microsoft.java.test.plugin/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<command id="vscode.java.test.generateTests" />
<command id="vscode.java.test.findJavaProjects" />
<command id="vscode.java.test.findTestPackagesAndTypes" />
<command id="vscode.java.test.findDirectTestChildrenForClass" />
</delegateCommandHandler>
</extension>
</plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class TestDelegateCommandHandler implements IDelegateCommandHandler {
private static final String GENERATE_TESTS = "vscode.java.test.generateTests";
private static final String FIND_JAVA_PROJECT = "vscode.java.test.findJavaProjects";
private static final String FIND_PACKAGES_AND_TYPES = "vscode.java.test.findTestPackagesAndTypes";
private static final String FIND_DIRECT_CHILDREN_FOR_CLASS = "vscode.java.test.findDirectTestChildrenForClass";

@Override
public Object executeCommand(String commandId, List<Object> arguments, IProgressMonitor monitor) throws Exception {
Expand All @@ -48,6 +49,8 @@ public Object executeCommand(String commandId, List<Object> arguments, IProgress
return TestSearchUtils.findJavaProjects(arguments, monitor);
case FIND_PACKAGES_AND_TYPES:
return TestSearchUtils.findTestPackagesAndTypes(arguments, monitor);
case FIND_DIRECT_CHILDREN_FOR_CLASS:
return TestSearchUtils.findDirectTestChildrenForClass(arguments, monitor);
default:
throw new UnsupportedOperationException(
String.format("Java test plugin doesn't support the command '%s'.", commandId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
Expand All @@ -33,10 +36,14 @@
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.manipulation.CoreASTProvider;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
import org.eclipse.jdt.ls.core.internal.handlers.DocumentLifeCycleHandler;

import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -182,6 +189,85 @@ public static List<JavaTestItem> findTestPackagesAndTypes(List<Object> arguments
return result;
}

/**
* Find the direct declared testable class and method for a given class
* @param arguments
* @param monitor
* @return
* @throws JavaModelException
* @throws OperationCanceledException
* @throws InterruptedException
*/
public static List<JavaTestItem> findDirectTestChildrenForClass(List<Object> arguments, IProgressMonitor monitor)
throws JavaModelException, OperationCanceledException, InterruptedException {
final String handlerId = (String) arguments.get(0);

// wait for the LS finishing updating
Job.getJobManager().join(DocumentLifeCycleHandler.DOCUMENT_LIFE_CYCLE_JOBS, monitor);

final IType testType = (IType) JavaCore.create(handlerId);
if (testType == null) {
return Collections.emptyList();
}

final ICompilationUnit unit = testType.getCompilationUnit();
if (unit == null) {
return Collections.emptyList();
}
final List<TestKind> testKinds = TestKindProvider.getTestKindsFromCache(unit.getJavaProject());

final List<JavaTestItem> result = new LinkedList<>();
final CompilationUnit root = (CompilationUnit) parseToAst(unit, true /* fromCache */, monitor);
for (final IType type : unit.getAllTypes()) {
if (monitor != null && monitor.isCanceled()) {
return result;
}

final IType declaringType = type.getDeclaringType();
if (declaringType != null &&
declaringType.getFullyQualifiedName().equals(testType.getFullyQualifiedName())) {
for (final TestKind kind: testKinds) {
final TestFrameworkSearcher searcher = TestFrameworkUtils.getSearcherByTestKind(kind);
if (searcher.isTestClass(type)) {
result.add(TestItemUtils.constructJavaTestItem(type, TestLevel.CLASS, kind));
break;
}
}
continue;
}

if (!type.getFullyQualifiedName().equals(testType.getFullyQualifiedName())) {
continue;
}

final ASTNode node = root.findDeclaringNode(type.getKey());
if (!(node instanceof TypeDeclaration)) {
continue;
}

final ITypeBinding binding = ((TypeDeclaration) node).resolveBinding();
if (binding == null) {
continue;
}


for (final IMethodBinding methodBinding : binding.getDeclaredMethods()) {
for (final TestKind kind: testKinds) {
final TestFrameworkSearcher searcher = TestFrameworkUtils.getSearcherByTestKind(kind);
if (searcher.isTestMethod(methodBinding)) {
result.add(TestItemUtils.constructJavaTestItem(
(IMethod) methodBinding.getJavaElement(),
TestLevel.METHOD,
kind
));
}
}
}
}

return result;
}

public static ASTNode parseToAst(final ICompilationUnit unit, final boolean fromCache,
final IProgressMonitor monitor) {
if (fromCache) {
Expand Down
11 changes: 8 additions & 3 deletions src/controller/testController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

import * as _ from 'lodash';
import { CancellationToken, TestController, TestItem, tests } from 'vscode';
import { instrumentOperation } from 'vscode-extension-telemetry-wrapper';
import { instrumentOperation, sendError } from 'vscode-extension-telemetry-wrapper';
import { isStandardServerReady } from '../extension';
import { IJavaTestItem, TestLevel } from '../types';
import { dataCache, ITestItemData } from './testItemDataCache';
import { findTestPackagesAndTypes, loadJavaProjects, synchronizeItemsRecursively } from './utils';
import { findDirectTestChildrenForClass, findTestPackagesAndTypes, loadJavaProjects, synchronizeItemsRecursively } from './utils';

export let testController: TestController | undefined;

Expand Down Expand Up @@ -39,6 +39,11 @@ export const loadChildren: (item: TestItem, token?: CancellationToken) => any =
} else if (data.testLevel === TestLevel.Package) {
// unreachable code
} else if (data.testLevel === TestLevel.Class) {
// todo
if (!data.jdtHandler) {
sendError(new Error('The class node does not have jdt handler id.'));
return;
}
const testMethods: IJavaTestItem[] = await findDirectTestChildrenForClass(data.jdtHandler, token);
synchronizeItemsRecursively(item, testMethods);
}
});
5 changes: 5 additions & 0 deletions src/controller/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,8 @@ export async function findTestPackagesAndTypes(handlerId: string, token?: Cancel
return await executeJavaLanguageServerCommand<IJavaTestItem[]>(
JavaTestRunnerDelegateCommands.FIND_TEST_PACKAGES_AND_TYPES, handlerId, token) || [];
}

export async function findDirectTestChildrenForClass(handlerId: string, token?: CancellationToken): Promise<IJavaTestItem[]> {
return await executeJavaLanguageServerCommand<IJavaTestItem[]>(
JavaTestRunnerDelegateCommands.FIND_DIRECT_CHILDREN_FOR_CLASS, handlerId, token) || [];
}