Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -151,34 +151,39 @@ private void addTestItemArgs(List<String> arguments) throws CoreException {
method.getParameters().length > 0) {
final ICompilationUnit unit = method.getCompilationUnit();
if (unit == null) {
throw new CoreException(new Status(IStatus.ERROR, JUnitPlugin.PLUGIN_ID, IStatus.ERROR,
"Cannot get compilation unit of method" + method.getElementName(), null)); //$NON-NLS-1$
}
final CompilationUnit root = (CompilationUnit) TestSearchUtils.parseToAst(unit,
false /*fromCache*/, new NullProgressMonitor());
final MethodDeclaration methodDeclaration = ASTNodeSearchUtil.getMethodDeclarationNode(method, root);
if (methodDeclaration == null) {
throw new CoreException(new Status(IStatus.ERROR, JUnitPlugin.PLUGIN_ID, IStatus.ERROR,
// binary method
if (method.getDeclaringType() == null) {
throw new CoreException(new Status(IStatus.ERROR, JUnitPlugin.PLUGIN_ID, IStatus.ERROR,
"Cannot get compilation unit of method" + method.getElementName(), null)); //$NON-NLS-1$
}
} else {
final CompilationUnit root = (CompilationUnit) TestSearchUtils.parseToAst(unit,
false /* fromCache */, new NullProgressMonitor());
final MethodDeclaration methodDeclaration = ASTNodeSearchUtil.getMethodDeclarationNode(method,
root);
if (methodDeclaration == null) {
throw new CoreException(new Status(IStatus.ERROR, JUnitPlugin.PLUGIN_ID, IStatus.ERROR,
"Cannot get method declaration of method" + method.getElementName(), null)); //$NON-NLS-1$
}
}

final List<String> parameters = new LinkedList<>();
for (final Object obj : methodDeclaration.parameters()) {
if (obj instanceof SingleVariableDeclaration) {
final ITypeBinding paramTypeBinding = ((SingleVariableDeclaration) obj)
.getType().resolveBinding();
if (paramTypeBinding == null) {
throw new CoreException(new Status(IStatus.ERROR, JUnitPlugin.PLUGIN_ID, IStatus.ERROR,
"Cannot set set argument for method" + methodDeclaration.toString(), null));
} else if (paramTypeBinding.isPrimitive()) {
parameters.add(paramTypeBinding.getQualifiedName());
} else {
parameters.add(paramTypeBinding.getBinaryName());
final List<String> parameters = new LinkedList<>();
for (final Object obj : methodDeclaration.parameters()) {
if (obj instanceof SingleVariableDeclaration) {
final ITypeBinding paramTypeBinding = ((SingleVariableDeclaration) obj).getType()
.resolveBinding();
if (paramTypeBinding == null) {
throw new CoreException(new Status(IStatus.ERROR, JUnitPlugin.PLUGIN_ID, IStatus.ERROR,
"Cannot set set argument for method" + methodDeclaration.toString(), null));
} else if (paramTypeBinding.isPrimitive()) {
parameters.add(paramTypeBinding.getQualifiedName());
} else {
parameters.add(paramTypeBinding.getBinaryName());
}
}
}
}
if (parameters.size() > 0) {
testName += "(" + String.join(",", parameters) + ")";
if (parameters.size() > 0) {
testName += "(" + String.join(",", parameters) + ")";
}
}
}
arguments.add(method.getDeclaringType().getFullyQualifiedName() + ':' + testName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,33 @@
import com.microsoft.java.test.plugin.util.TestItemUtils;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.BinaryMember;
import org.eclipse.jdt.internal.core.BinaryMethod;
import org.eclipse.jdt.internal.core.BinaryType;
import org.eclipse.jdt.internal.core.PackageFragmentRoot;
import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore;
import org.eclipse.jdt.ls.core.internal.JDTUtils;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
* Builder class to build {@link com.microsoft.java.test.plugin.model.JavaTestItem}
Expand All @@ -36,6 +54,7 @@ public class JavaTestItemBuilder {
private IJavaElement element;
private TestLevel level;
private TestKind kind;
private String displayName;

public JavaTestItemBuilder setJavaElement(IJavaElement element) {
this.element = element;
Expand All @@ -52,34 +71,124 @@ public JavaTestItemBuilder setKind(TestKind kind) {
return this;
}

public JavaTestItemBuilder setDisplayName(String displayName) {
this.displayName = displayName;
return this;
}

public JavaTestItem build() throws JavaModelException {
if (this.element == null || this.level == null || this.kind == null) {
throw new IllegalArgumentException("Failed to build Java test item due to missing arguments");
}

final String displayName;
String uri = null;
if (this.element instanceof IJavaProject) {
final IJavaProject javaProject = (IJavaProject) this.element;
final IProject project = javaProject.getProject();
if (ProjectUtils.isVisibleProject(project)) {
displayName = project.getName();
if (this.displayName == null) {
if (this.element instanceof IJavaProject) {
final IJavaProject javaProject = (IJavaProject) this.element;
final IProject project = javaProject.getProject();
if (ProjectUtils.isVisibleProject(project)) {
displayName = project.getName();
} else {
final IPath realPath = ProjectUtils.getProjectRealFolder(project);
displayName = realPath.lastSegment();
uri = realPath.toFile().toURI().toString();
}
} else if (this.element instanceof IPackageFragment &&
((IPackageFragment) this.element).isDefaultPackage()) {
displayName = DEFAULT_PACKAGE_NAME;
final IResource resource = getResource((IPackageFragment) this.element);
if (resource == null || !resource.exists()) {
return null;
}
uri = JDTUtils.getFileURI(resource);
} else {
final IPath realPath = ProjectUtils.getProjectRealFolder(project);
displayName = realPath.lastSegment();
uri = realPath.toFile().toURI().toString();
displayName = JavaElementLabelsCore.getElementLabel(this.element, JavaElementLabelsCore.ALL_DEFAULT);
}
} else if (this.element instanceof IPackageFragment && ((IPackageFragment) this.element).isDefaultPackage()) {
displayName = DEFAULT_PACKAGE_NAME;
} else {
displayName = JavaElementLabelsCore.getElementLabel(this.element, JavaElementLabelsCore.ALL_DEFAULT);
}
Range range = null;
final String fullName = TestItemUtils.parseFullName(this.element, this.level, this.kind);
if (uri == null) {
uri = JDTUtils.getFileURI(this.element.getResource());
IResource resource = this.element.getResource();
if (resource == null && this.element instanceof IPackageFragment) {
resource = getResource((IPackageFragment) this.element);
}
if (resource == null || !resource.exists()) {
return null;
}
if (element instanceof BinaryMember) {
final String[] sources = new String[1];
final int[] lines = {-1};
final IClassFile classFile = ((BinaryMember) element).getClassFile();
try (InputStream is = new ByteArrayInputStream(classFile.getBytes())) {
final ClassReader cr = new ClassReader(is);
if (element instanceof BinaryType) {
cr.accept(new ClassVisitor(Opcodes.ASM9) {
@Override
public void visitSource(String source, String debug) {
sources[0] = source;
}
}, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES);
} else if (element instanceof BinaryMethod) {
final String methodDescriptor = ((BinaryMethod) element).getSignature();
cr.accept(new ClassVisitor(Opcodes.ASM9) {
@Override
public void visitSource(String source, String debug) {
sources[0] = source;
}

public MethodVisitor visitMethod(int access, String name, String descriptor,
String signature, String[] exceptions) {
if (name.equals(element.getElementName()) && descriptor.equals(methodDescriptor)) {
return new MethodVisitor(Opcodes.ASM9) {
@Override
public void visitLineNumber(int line, Label start) {
if (lines[0] < 0) {
lines[0] = line;
if (line > 0) {
lines[0]--;
}
}
}
};
}
return null;
}
}, ClassReader.SKIP_FRAMES);
}
} catch (Exception e) {
JavaLanguageServerPlugin.logException(e);
}
if (sources[0] != null) {
final IPackageFragment packageFragment = (IPackageFragment) element
.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
if (packageFragment != null) {
final String packageName = packageFragment.getElementName();
final IJavaProject project = element.getJavaProject();
final String packagePath = packageName.replace('.', '/');
for (final IClasspathEntry entry : project.getRawClasspath()) {
if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
final IPath sourceFolderPath = entry.getPath();
final IPath fullPath = sourceFolderPath.append(packagePath).append(sources[0]);
final IResource candidate = ResourcesPlugin.getWorkspace().getRoot()
.findMember(fullPath);
if (candidate != null && candidate.exists()) {
resource = candidate;
break;
}
}
}
}
}
if (lines[0] > 0) {
final Position line = new Position(lines[0] - 1, 0);
range = new Range(line, line);
}
}
if (uri == null) {
uri = JDTUtils.getFileURI(resource);
}
}
Range range = null;
if (this.level == TestLevel.CLASS || this.level == TestLevel.METHOD) {
if (range == null && (this.level == TestLevel.CLASS || this.level == TestLevel.METHOD)) {
range = TestItemUtils.parseTestItemRange(this.element);
}

Expand All @@ -89,4 +198,22 @@ public JavaTestItem build() throws JavaModelException {

return result;
}

private IResource getResource(IPackageFragment packageFragment) {
if (packageFragment == null) {
return null;
}
IResource resource = packageFragment.getResource();
if (resource == null) {
final IJavaElement e = packageFragment.getParent();
if (e instanceof PackageFragmentRoot) {
final PackageFragmentRoot root = (PackageFragmentRoot) e;
resource = root.getResource();
if (resource == null) {
resource = root.resource(root);
}
}
}
return resource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,9 @@ public Set<IType> findTestItemsInContainer(IJavaElement element, IProgressMonito

return types;
}

@Override
public String getDisplayName(IMethodBinding methodBinding) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IMemberValuePairBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Modifier;
Expand All @@ -40,9 +41,11 @@ public class JUnit5TestSearcher extends BaseFrameworkSearcher {

protected static final String DISPLAY_NAME_ANNOTATION_JUNIT5 = "org.junit.jupiter.api.DisplayName";

protected static final String SPOCK_FEATURE_METADATA = "org.spockframework.runtime.model.FeatureMetadata";

public JUnit5TestSearcher() {
super();
this.testMethodAnnotations = new String[] { JUNIT_PLATFORM_TESTABLE };
this.testMethodAnnotations = new String[] { JUNIT_PLATFORM_TESTABLE, SPOCK_FEATURE_METADATA };
}

@Override
Expand Down Expand Up @@ -133,4 +136,19 @@ public Set<IType> findTestItemsInContainer(IJavaElement element, IProgressMonito
}
return types;
}

@Override
public String getDisplayName(IMethodBinding methodBinding) {
for (final IAnnotationBinding annotation : methodBinding.getAnnotations()) {
if (matchesName(annotation.getAnnotationType(), SPOCK_FEATURE_METADATA)) {
final IMemberValuePairBinding[] pairs = annotation.getDeclaredMemberValuePairs();
for (final IMemberValuePairBinding pair : pairs) {
if ("name".equals(pair.getName()) && (pair.getValue() instanceof String)) {
return (String) pair.getValue();
}
}
}
}
return null;
}
}
Loading