Skip to content

Commit

Permalink
149: a first implementation
Browse files Browse the repository at this point in the history
Task-Url: #149
  • Loading branch information
LorenzoBettini committed Jul 28, 2022
1 parent 029dd31 commit 440e0bd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,23 @@

import static org.pitest.pitclipse.core.PitCoreActivator.getDefault;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.junit.JUnitCore;
import org.eclipse.jdt.launching.JavaLaunchDelegate;
import org.pitest.pitclipse.core.extension.handler.ExtensionPointHandler;
import org.pitest.pitclipse.core.extension.point.PitRuntimeOptions;
import org.pitest.pitclipse.launch.config.ClassFinder;
import org.pitest.pitclipse.launch.config.LaunchConfigurationWrapper;
import org.pitest.pitclipse.launch.config.PackageFinder;
import org.pitest.pitclipse.launch.config.ProjectFinder;
import org.pitest.pitclipse.launch.config.ProjectUtils;
import org.pitest.pitclipse.launch.config.SourceDirFinder;
import org.pitest.pitclipse.runner.PitOptions;
import org.pitest.pitclipse.runner.PitOptions.PitOptionsBuilder;
Expand Down Expand Up @@ -120,60 +114,10 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun
portNumber, options, configWrapper.getMutatedProjects()));

}

private static boolean isJUnit5InClasspathOf(IJavaProject project) throws JavaModelException {
// FIXME Naive implementation, won't handle every case (e.g. JUnit 5 provided through a junit5.jar archive)
// A better implementation may rely on JDT to scan the classpath / source files for definition / use
// of JUnit 5 Test annotation
//
// See also https://github.com/redhat-developer/vscode-java/issues/204

for (IClasspathEntry classpathEntry : project.getRawClasspath()) {
if (JUnitCore.JUNIT5_CONTAINER_PATH.equals(classpathEntry.getPath())) {
return true;
}
}
for (IClasspathEntry classpathEntry : project.getResolvedClasspath(true)) {
Map<String, Object> attributes = Arrays.stream(classpathEntry.getExtraAttributes()).collect(Collectors.toMap(IClasspathAttribute::getName, IClasspathAttribute::getValue, (value1, value2) -> value1));
if (isJUnit5FromMaven(attributes)) {
return true;
}
if (isJUnit5FromGradle(classpathEntry, attributes)) {
return true;
}
if (pointsToJunitJupiterEngineJar(classpathEntry)) {
return true;
}
}
return false;
}

private static boolean isJUnit5FromMaven(Map<String, Object> attributes) {
if (!attributes.containsKey("maven.pomderived") || !attributes.containsKey("maven.groupId") || !attributes.containsKey("maven.artifactId")) {
return false;
}
return "true".equals(attributes.get("maven.pomderived"))
&& "org.junit.jupiter".equals(attributes.get("maven.groupId"))
&& "junit-jupiter-engine".equals(attributes.get("maven.artifactId"));
}

private static boolean isJUnit5FromGradle(IClasspathEntry classpathEntry, Map<String, Object> attributes) {
if (!attributes.containsKey("gradle_use_by_scope")) {
return false;
}
return pointsToJunitJupiterEngineJar(classpathEntry);
}

private static boolean pointsToJunitJupiterEngineJar(IClasspathEntry classpathEntry) {
try {
String[] pathElements = classpathEntry.getPath().toString().split("/");
String file = pathElements[pathElements.length - 1];
return file.startsWith("junit-jupiter-engine") && file.endsWith(".jar");
}
catch (IndexOutOfBoundsException e) {
// path doesn't have expected format, never mind
}
return false;

private static boolean isJUnit5InClasspathOf(IJavaProject project) throws CoreException {
String junit5Class = "org.junit.jupiter.engine.Constants";
return ProjectUtils.onClassPathOf(project, junit5Class);
}

protected abstract ProjectFinder getProjectFinder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.JavaRuntime;
import org.pitest.pitclipse.launch.AbstractPitLaunchDelegate;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

public class ProjectUtils {
Expand All @@ -47,6 +57,33 @@ public static boolean onClassPathOf(IJavaProject testProject, IJavaProject proje
return testProject.isOnClasspath(project);
}

public static boolean onClassPathOf(IJavaProject project, String fullyQualifiedName) throws CoreException {
String[] classPathEntries = JavaRuntime.computeDefaultRuntimeClassPath(project);
List<URL> urlList = new ArrayList<>();
for (int i = 0; i < classPathEntries.length; i++) {
String entry = classPathEntries[i];
IPath path = new Path(entry);
URL url;
try {
url = path.toFile().toURI().toURL();
urlList.add(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
URL[] urls = urlList.toArray(new URL[urlList.size()]);
try (URLClassLoader classLoader = new URLClassLoader(urls, AbstractPitLaunchDelegate.class.getClassLoader())) {
try {
classLoader.loadClass(fullyQualifiedName);
return true;
} catch (ClassNotFoundException e) {
return false;
}
} catch (IOException e1) {
throw new CoreException(Status.error("Closing the classloader", e1));
}
}

public static boolean sameProject(IJavaProject testProject, IJavaProject project) {
return testProject.getElementName().equals(project.getElementName());
}
Expand Down

0 comments on commit 440e0bd

Please sign in to comment.