diff --git a/java-extension/com.microsoft.java.test.plugin.test/META-INF/MANIFEST.MF b/java-extension/com.microsoft.java.test.plugin.test/META-INF/MANIFEST.MF
index cc743c32..ee695a30 100644
--- a/java-extension/com.microsoft.java.test.plugin.test/META-INF/MANIFEST.MF
+++ b/java-extension/com.microsoft.java.test.plugin.test/META-INF/MANIFEST.MF
@@ -9,8 +9,7 @@ Import-Package: org.osgi.framework;version="1.3.0"
Bundle-Localization: plugin
Bundle-ActivationPolicy: lazy
Require-Bundle: org.eclipse.jdt.ls.core,
- com.microsoft.java.test.plugin,
- com.google.gson,
+ com.microsoft.java.test.plugin, org.eclipse.lsp4j, com.google.gson,
org.junit,
org.apache.commons.commons-io;bundle-version="2.12.0",
org.eclipse.core.resources,
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/.classpath b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/.classpath
new file mode 100644
index 00000000..15b6944d
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/.classpath
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/.project b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/.project
new file mode 100644
index 00000000..cbbce082
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/.project
@@ -0,0 +1,15 @@
+
+
+ inheritance-binary-child
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/src/test/java/example/InheritanceBinaryChildTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/src/test/java/example/InheritanceBinaryChildTest.java
new file mode 100644
index 00000000..adfd19fe
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-child/src/test/java/example/InheritanceBinaryChildTest.java
@@ -0,0 +1,6 @@
+package example;
+
+import org.junit.jupiter.api.TestInfo;
+
+public class InheritanceBinaryChildTest extends InheritanceBinaryBaseTest {
+}
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/.classpath b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/.classpath
new file mode 100644
index 00000000..91ae659e
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/.project b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/.project
new file mode 100644
index 00000000..5e91282e
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/.project
@@ -0,0 +1,15 @@
+
+
+ inheritance-binary-parent
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/src/test/java/example/InheritanceBinaryBaseTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/src/test/java/example/InheritanceBinaryBaseTest.java
new file mode 100644
index 00000000..62844964
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-binary-parent/src/test/java/example/InheritanceBinaryBaseTest.java
@@ -0,0 +1,10 @@
+package example;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+public class InheritanceBinaryBaseTest {
+ @Test
+ void base(T info) {
+ }
+}
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/.classpath b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/.classpath
new file mode 100644
index 00000000..8d3b8c72
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/.classpath
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/.project b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/.project
new file mode 100644
index 00000000..8d1c76df
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/.project
@@ -0,0 +1,17 @@
+
+
+ inheritance-child
+
+
+ inheritance-parent
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/src/test/java/example/InheritanceChildTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/src/test/java/example/InheritanceChildTest.java
new file mode 100644
index 00000000..3e68a261
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-child/src/test/java/example/InheritanceChildTest.java
@@ -0,0 +1,9 @@
+package example;
+
+import org.junit.jupiter.api.Test;
+
+public class InheritanceChildTest extends InheritanceBaseTest {
+ @Test
+ void child() {
+ }
+}
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/.classpath b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/.classpath
new file mode 100644
index 00000000..fad9f65c
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/.project b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/.project
new file mode 100644
index 00000000..034166d6
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/.project
@@ -0,0 +1,15 @@
+
+
+ inheritance-junit4
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4BaseTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4BaseTest.java
new file mode 100644
index 00000000..481ba2e2
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4BaseTest.java
@@ -0,0 +1,9 @@
+package example;
+
+import org.junit.Test;
+
+public class JUnit4BaseTest {
+ @Test
+ public void inherited() {
+ }
+}
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4ChildTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4ChildTest.java
new file mode 100644
index 00000000..7ee71013
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4ChildTest.java
@@ -0,0 +1,7 @@
+package example;
+
+public class JUnit4ChildTest extends JUnit4MiddleTest {
+ @Override
+ public void inherited() {
+ }
+}
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4GrandparentTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4GrandparentTest.java
new file mode 100644
index 00000000..75eaf23e
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4GrandparentTest.java
@@ -0,0 +1,9 @@
+package example;
+
+import org.junit.Test;
+
+public class JUnit4GrandparentTest {
+ @Test
+ public void reannotated() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4IntermediateTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4IntermediateTest.java
new file mode 100644
index 00000000..507dc8e0
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4IntermediateTest.java
@@ -0,0 +1,7 @@
+package example;
+
+public class JUnit4IntermediateTest extends JUnit4GrandparentTest {
+ @Override
+ public void reannotated() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4MiddleTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4MiddleTest.java
new file mode 100644
index 00000000..8884120d
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4MiddleTest.java
@@ -0,0 +1,10 @@
+package example;
+
+import org.junit.Test;
+
+public class JUnit4MiddleTest extends JUnit4BaseTest {
+ @Override
+ @Test
+ public void inherited() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4ReannotatedChildTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4ReannotatedChildTest.java
new file mode 100644
index 00000000..d938bb44
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-junit4/src/test/java/example/JUnit4ReannotatedChildTest.java
@@ -0,0 +1,10 @@
+package example;
+
+import org.junit.Test;
+
+public class JUnit4ReannotatedChildTest extends JUnit4IntermediateTest {
+ @Override
+ @Test
+ public void reannotated() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/.classpath b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/.classpath
new file mode 100644
index 00000000..91ae659e
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/.project b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/.project
new file mode 100644
index 00000000..48ff273b
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/.project
@@ -0,0 +1,15 @@
+
+
+ inheritance-parent
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/src/test/java/example/InheritanceBaseTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/src/test/java/example/InheritanceBaseTest.java
new file mode 100644
index 00000000..d98c1239
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/inheritance-parent/src/test/java/example/InheritanceBaseTest.java
@@ -0,0 +1,9 @@
+package example;
+
+import org.junit.jupiter.api.Test;
+
+public class InheritanceBaseTest {
+ @Test
+ void base() {
+ }
+}
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/GenericInheritanceBaseTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/GenericInheritanceBaseTest.java
new file mode 100644
index 00000000..464e0a75
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/GenericInheritanceBaseTest.java
@@ -0,0 +1,10 @@
+package example;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+public class GenericInheritanceBaseTest {
+ @Test
+ void generic(T info) {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/GenericInheritanceChildTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/GenericInheritanceChildTest.java
new file mode 100644
index 00000000..5573a6b7
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/GenericInheritanceChildTest.java
@@ -0,0 +1,6 @@
+package example;
+
+import org.junit.jupiter.api.TestInfo;
+
+public class GenericInheritanceChildTest extends GenericInheritanceBaseTest {
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceBaseTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceBaseTest.java
new file mode 100644
index 00000000..8568f7e1
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceBaseTest.java
@@ -0,0 +1,9 @@
+package example;
+
+import org.junit.jupiter.api.Test;
+
+public class InheritanceBaseTest {
+ @Test
+ void base() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceChildTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceChildTest.java
new file mode 100644
index 00000000..6188c65d
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceChildTest.java
@@ -0,0 +1,9 @@
+package example;
+
+import org.junit.jupiter.api.Test;
+
+public class InheritanceChildTest extends InheritanceBaseTest {
+ @Test
+ void child() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceOverrideTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceOverrideTest.java
new file mode 100644
index 00000000..e9411368
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceOverrideTest.java
@@ -0,0 +1,14 @@
+package example;
+
+import org.junit.jupiter.api.Test;
+
+public class InheritanceOverrideTest extends InheritanceBaseTest {
+ @Test
+ @Override
+ void base() {
+ }
+
+ @Test
+ void extra() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceUnannotatedOverrideTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceUnannotatedOverrideTest.java
new file mode 100644
index 00000000..fcd2d51f
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/InheritanceUnannotatedOverrideTest.java
@@ -0,0 +1,7 @@
+package example;
+
+public class InheritanceUnannotatedOverrideTest extends InheritanceBaseTest {
+ @Override
+ void base() {
+ }
+}
\ No newline at end of file
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/UnboundedGenericInheritanceBaseTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/UnboundedGenericInheritanceBaseTest.java
new file mode 100644
index 00000000..ef411198
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/UnboundedGenericInheritanceBaseTest.java
@@ -0,0 +1,9 @@
+package example;
+
+import org.junit.jupiter.api.Test;
+
+public class UnboundedGenericInheritanceBaseTest {
+ @Test
+ void generic(T info) {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/UnboundedGenericInheritanceChildTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/UnboundedGenericInheritanceChildTest.java
new file mode 100644
index 00000000..472a2ded
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/UnboundedGenericInheritanceChildTest.java
@@ -0,0 +1,4 @@
+package example;
+
+public class UnboundedGenericInheritanceChildTest extends UnboundedGenericInheritanceBaseTest {
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/child/CrossPackageSameSignatureTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/child/CrossPackageSameSignatureTest.java
new file mode 100644
index 00000000..e9d787af
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/child/CrossPackageSameSignatureTest.java
@@ -0,0 +1,8 @@
+package example.child;
+
+import example.parent.PackagePrivateBaseTest;
+
+public class CrossPackageSameSignatureTest extends PackagePrivateBaseTest {
+ void packagePrivateTest() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/parent/PackagePrivateBaseTest.java b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/parent/PackagePrivateBaseTest.java
new file mode 100644
index 00000000..fa01667e
--- /dev/null
+++ b/java-extension/com.microsoft.java.test.plugin.test/projects/preview-junit/src/test/java/example/parent/PackagePrivateBaseTest.java
@@ -0,0 +1,9 @@
+package example.parent;
+
+import org.junit.jupiter.api.Test;
+
+public class PackagePrivateBaseTest {
+ @Test
+ void packagePrivateTest() {
+ }
+}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/src/com/microsoft/java/test/plugin/launchers/JUnitLaunchConfigurationDelegateTest.java b/java-extension/com.microsoft.java.test.plugin.test/src/com/microsoft/java/test/plugin/launchers/JUnitLaunchConfigurationDelegateTest.java
index 6baaf304..5f68ed0b 100644
--- a/java-extension/com.microsoft.java.test.plugin.test/src/com/microsoft/java/test/plugin/launchers/JUnitLaunchConfigurationDelegateTest.java
+++ b/java-extension/com.microsoft.java.test.plugin.test/src/com/microsoft/java/test/plugin/launchers/JUnitLaunchConfigurationDelegateTest.java
@@ -13,8 +13,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.net.URI;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
@@ -23,12 +25,16 @@
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.junit.Test;
import com.microsoft.java.test.plugin.AbstractProjectsManagerBasedTest;
+import com.microsoft.java.test.plugin.WorkspaceHelper;
import com.microsoft.java.test.plugin.model.Response;
+import com.microsoft.java.test.plugin.model.JavaTestItem;
+import com.microsoft.java.test.plugin.util.TestSearchUtils;
import com.google.gson.Gson;
public class JUnitLaunchConfigurationDelegateTest extends AbstractProjectsManagerBasedTest {
@@ -82,4 +88,140 @@ public void testAddOpensForAllSelectedPackagesInModularProject() throws Exceptio
assertEquals("--add-opens", vmArguments.get(vmArguments.indexOf(secondPackageOpen) - 1));
}
+ @Test
+ public void testInheritedMethodLaunchesAgainstChildClass() throws Exception {
+ importProjects(Arrays.asList("inheritance-parent", "inheritance-child"));
+ final IProject childProject = WorkspaceHelper.getProject("inheritance-child");
+ final IJavaProject childJavaProject = JavaCore.create(childProject);
+ final IType parentType = JavaCore.create(WorkspaceHelper.getProject("inheritance-parent"))
+ .findType("example.InheritanceBaseTest");
+
+ final Map request = new LinkedHashMap<>();
+ request.put("projectName", childProject.getName());
+ request.put("testLevel", 6);
+ request.put("testKind", 0);
+ request.put("testNames", Arrays.asList(parentType.getMethod("base", new String[0]).getHandleIdentifier()));
+ request.put("executionClassNames", Arrays.asList("example.InheritanceChildTest"));
+
+ final Response response = JUnitLaunchUtils.resolveLaunchArgument(
+ Arrays.asList(new Gson().toJson(request)), new NullProgressMonitor());
+
+ assertEquals(0, response.getStatus());
+ assertEquals(childJavaProject.getElementName(), response.getBody().projectName);
+ assertTrue(Arrays.asList(response.getBody().programArguments)
+ .contains("example.InheritanceChildTest:base"));
+ }
+
+ @Test
+ public void testBinaryMethodWithParametersLaunchesAgainstChildClass() throws Exception {
+ final IProject project = importProjects("preview-junit").get(0);
+ final IJavaProject javaProject = JavaCore.create(project);
+ final IType assertions = javaProject.findType("org.junit.jupiter.api.Assertions");
+ assertNotNull(assertions);
+ final IMethod binaryMethod = assertions.getMethod("assertEquals",
+ new String[] { "Ljava.lang.Object;", "Ljava.lang.Object;" });
+ assertTrue(binaryMethod.exists());
+ assertTrue(binaryMethod.getCompilationUnit() == null);
+
+ final Map request = new LinkedHashMap<>();
+ request.put("projectName", javaProject.getElementName());
+ request.put("testLevel", 6);
+ request.put("testKind", 0);
+ request.put("testNames", Arrays.asList(binaryMethod.getHandleIdentifier()));
+ request.put("executionClassNames", Arrays.asList("example.InheritanceChildTest"));
+
+ final Response response = JUnitLaunchUtils.resolveLaunchArgument(
+ Arrays.asList(new Gson().toJson(request)), new NullProgressMonitor());
+
+ assertEquals(0, response.getStatus());
+ assertTrue(Arrays.asList(response.getBody().programArguments)
+ .contains("example.InheritanceChildTest:assertEquals(java.lang.Object,java.lang.Object)"));
+ }
+
+ @Test
+ public void testGenericSourceMethodLaunchesWithErasedParameterType() throws Exception {
+ final IProject project = importProjects("preview-junit").get(0);
+ final IJavaProject javaProject = JavaCore.create(project);
+ final IType parentType = javaProject.findType("example.GenericInheritanceBaseTest");
+ assertNotNull(parentType);
+ final IMethod genericMethod = Arrays.stream(parentType.getMethods())
+ .filter(method -> "generic".equals(method.getElementName()))
+ .findFirst().orElse(null);
+ assertNotNull(genericMethod);
+
+ final Map request = new LinkedHashMap<>();
+ request.put("projectName", javaProject.getElementName());
+ request.put("testLevel", 6);
+ request.put("testKind", 0);
+ request.put("testNames", Arrays.asList(genericMethod.getHandleIdentifier()));
+ request.put("executionClassNames", Arrays.asList("example.GenericInheritanceChildTest"));
+
+ final Response response = JUnitLaunchUtils.resolveLaunchArgument(
+ Arrays.asList(new Gson().toJson(request)), new NullProgressMonitor());
+
+ assertEquals(0, response.getStatus());
+ assertTrue(Arrays.asList(response.getBody().programArguments)
+ .contains("example.GenericInheritanceChildTest:generic(org.junit.jupiter.api.TestInfo)"));
+ }
+
+ @Test
+ public void testUnboundedGenericSourceMethodLaunchesWithObjectParameterType() throws Exception {
+ final IProject project = importProjects("preview-junit").get(0);
+ final IJavaProject javaProject = JavaCore.create(project);
+ final IType parentType = javaProject.findType("example.UnboundedGenericInheritanceBaseTest");
+ assertNotNull(parentType);
+ final IMethod genericMethod = Arrays.stream(parentType.getMethods())
+ .filter(method -> "generic".equals(method.getElementName()))
+ .findFirst().orElse(null);
+ assertNotNull(genericMethod);
+
+ final Map request = new LinkedHashMap<>();
+ request.put("projectName", javaProject.getElementName());
+ request.put("testLevel", 6);
+ request.put("testKind", 0);
+ request.put("testNames", Arrays.asList(genericMethod.getHandleIdentifier()));
+ request.put("executionClassNames", Arrays.asList("example.UnboundedGenericInheritanceChildTest"));
+
+ final Response response = JUnitLaunchUtils.resolveLaunchArgument(
+ Arrays.asList(new Gson().toJson(request)), new NullProgressMonitor());
+
+ assertEquals(0, response.getStatus());
+ assertTrue(Arrays.asList(response.getBody().programArguments)
+ .contains("example.UnboundedGenericInheritanceChildTest:generic(java.lang.Object)"));
+ }
+
+ @Test
+ public void testInheritedBinaryMethodWithParametersLaunchesAgainstChildClass() throws Exception {
+ importProjects(Arrays.asList("inheritance-binary-parent", "inheritance-binary-child"));
+ final IJavaProject javaProject = JavaCore.create(WorkspaceHelper.getProject("inheritance-binary-child"));
+ final IType childType = javaProject.findType("example.InheritanceBinaryChildTest");
+ assertNotNull(childType);
+
+ final List methods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(childType.getHandleIdentifier()), new NullProgressMonitor());
+ final JavaTestItem inherited = methods.stream()
+ .filter(item -> item.getFullName().contains("#base"))
+ .findFirst().orElse(null);
+ assertNotNull(inherited);
+ assertEquals(childType.getResource().getLocationURI(), URI.create(inherited.getUri()));
+ assertNull(inherited.getRange());
+ final IMethod binaryMethod = (IMethod)
+ JavaCore.create(inherited.getJdtHandler());
+ assertTrue(binaryMethod.getCompilationUnit() == null);
+
+ final Map request = new LinkedHashMap<>();
+ request.put("projectName", javaProject.getElementName());
+ request.put("testLevel", 6);
+ request.put("testKind", 0);
+ request.put("testNames", Arrays.asList(inherited.getJdtHandler()));
+ request.put("executionClassNames", Arrays.asList("example.InheritanceBinaryChildTest"));
+
+ final Response response = JUnitLaunchUtils.resolveLaunchArgument(
+ Arrays.asList(new Gson().toJson(request)), new NullProgressMonitor());
+
+ assertEquals(0, response.getStatus());
+ assertTrue(Arrays.asList(response.getBody().programArguments)
+ .contains("example.InheritanceBinaryChildTest:base(org.junit.jupiter.api.TestInfo)"));
+ }
+
}
diff --git a/java-extension/com.microsoft.java.test.plugin.test/src/com/microsoft/java/test/plugin/util/TestSearchUtilsTest.java b/java-extension/com.microsoft.java.test.plugin.test/src/com/microsoft/java/test/plugin/util/TestSearchUtilsTest.java
index f88fe470..a98f48ab 100644
--- a/java-extension/com.microsoft.java.test.plugin.test/src/com/microsoft/java/test/plugin/util/TestSearchUtilsTest.java
+++ b/java-extension/com.microsoft.java.test.plugin.test/src/com/microsoft/java/test/plugin/util/TestSearchUtilsTest.java
@@ -16,6 +16,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.net.URI;
import java.util.Arrays;
import java.util.List;
@@ -34,6 +35,7 @@
import com.microsoft.java.test.plugin.AbstractProjectsManagerBasedTest;
import com.microsoft.java.test.plugin.model.JavaTestItem;
+import com.microsoft.java.test.plugin.WorkspaceHelper;
public class TestSearchUtilsTest extends AbstractProjectsManagerBasedTest {
@@ -76,11 +78,20 @@ public void testDiscoverJUnit5TestsWithOlderPreviewSource() throws Exception {
final List packages = TestSearchUtils.findTestPackagesAndTypes(
Arrays.asList(javaProject.getHandleIdentifier()), new NullProgressMonitor());
- assertEquals(1, packages.size());
- assertEquals(3, packages.get(0).getChildren().size());
- assertTrue(packages.get(0).getChildren().stream().anyMatch(item -> "MiniTest".equals(item.getLabel())));
- assertTrue(packages.get(0).getChildren().stream().anyMatch(item -> "SiblingTest".equals(item.getLabel())));
- assertTrue(packages.get(0).getChildren().stream().anyMatch(item -> "NestedOnlyTest".equals(item.getLabel())));
+ final JavaTestItem examplePackage = packages.stream()
+ .filter(item -> "example".equals(item.getLabel()))
+ .findFirst().orElse(null);
+ assertNotNull(examplePackage);
+ assertEquals(11, examplePackage.getChildren().size());
+ assertTrue(examplePackage.getChildren().stream().anyMatch(item -> "MiniTest".equals(item.getLabel())));
+ assertTrue(examplePackage.getChildren().stream().anyMatch(item -> "SiblingTest".equals(item.getLabel())));
+ assertTrue(examplePackage.getChildren().stream().anyMatch(item -> "NestedOnlyTest".equals(item.getLabel())));
+ assertTrue(examplePackage.getChildren().stream()
+ .anyMatch(item -> "InheritanceChildTest".equals(item.getLabel())));
+ assertTrue(examplePackage.getChildren().stream()
+ .anyMatch(item -> "GenericInheritanceChildTest".equals(item.getLabel())));
+ assertTrue(examplePackage.getChildren().stream()
+ .anyMatch(item -> "UnboundedGenericInheritanceChildTest".equals(item.getLabel())));
final List methods = TestSearchUtils.findDirectTestChildrenForClass(
Arrays.asList(type.getHandleIdentifier()), new NullProgressMonitor());
@@ -94,4 +105,129 @@ public void testDiscoverJUnit5TestsWithOlderPreviewSource() throws Exception {
assertEquals("Child", nestedChildren.get(0).getLabel());
assertEquals(JavaCore.ENABLED, javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true));
}
+
+ @Test
+ public void testDiscoverInheritedTestMethods() throws Exception {
+ final IProject project = importProjects("preview-junit").get(0);
+ final IJavaProject javaProject = JavaCore.create(project);
+ final IType childType = javaProject.findType("example.InheritanceChildTest");
+ assertNotNull(childType);
+
+ final List childMethods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(childType.getHandleIdentifier()), new NullProgressMonitor());
+ assertEquals(2, childMethods.size());
+ assertTrue(childMethods.stream().anyMatch(
+ item -> "example.InheritanceChildTest#child()".equals(item.getFullName())));
+ assertTrue(childMethods.stream().anyMatch(
+ item -> "example.InheritanceChildTest#base()".equals(item.getFullName())));
+ for (final JavaTestItem item : childMethods) {
+ assertTrue(item.getId().startsWith(item.getProjectName() + "@example.InheritanceChildTest#"));
+ }
+
+ final IType baseType = javaProject.findType("example.InheritanceBaseTest");
+ final List baseMethods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(baseType.getHandleIdentifier()), new NullProgressMonitor());
+ assertEquals(1, baseMethods.size());
+ assertEquals("example.InheritanceBaseTest#base()", baseMethods.get(0).getFullName());
+
+ final IType overrideType = javaProject.findType("example.InheritanceOverrideTest");
+ final List overrideMethods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(overrideType.getHandleIdentifier()), new NullProgressMonitor());
+ assertEquals(2, overrideMethods.size());
+ assertTrue(overrideMethods.stream().anyMatch(
+ item -> "example.InheritanceOverrideTest#base()".equals(item.getFullName())));
+ assertTrue(overrideMethods.stream().anyMatch(
+ item -> "example.InheritanceOverrideTest#extra()".equals(item.getFullName())));
+ }
+
+ @Test
+ public void testInheritedMethodUsesChildProjectAndExecutionClass() throws Exception {
+ importProjects(Arrays.asList("inheritance-parent", "inheritance-child"));
+ final IProject childProject = WorkspaceHelper.getProject("inheritance-child");
+ final IJavaProject javaProject = JavaCore.create(childProject);
+ final IType childType = javaProject.findType("example.InheritanceChildTest");
+ final IType parentType = JavaCore.create(WorkspaceHelper.getProject("inheritance-parent"))
+ .findType("example.InheritanceBaseTest");
+ assertNotNull(childType);
+ assertNotNull(parentType);
+
+ final List methods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(childType.getHandleIdentifier()), new NullProgressMonitor());
+ final JavaTestItem inherited = methods.stream()
+ .filter(item -> item.getFullName().endsWith("#base()"))
+ .findFirst().orElse(null);
+ assertNotNull(inherited);
+ assertEquals(childProject.getName(), inherited.getProjectName());
+ assertEquals(childProject.getName() + "@example.InheritanceChildTest#base()", inherited.getId());
+ assertEquals("example.InheritanceChildTest", inherited.getExecutionClassName());
+ assertEquals(parentType.getMethod("base", new String[0]).getHandleIdentifier(), inherited.getJdtHandler());
+ assertEquals(childType.getResource().getLocationURI(), URI.create(inherited.getUri()));
+ assertNull(inherited.getRange());
+ }
+
+ @Test
+ public void testJUnit4TestSurvivesUnannotatedOverride() throws Exception {
+ importProjects("inheritance-junit4");
+ final IJavaProject javaProject = JavaCore.create(WorkspaceHelper.getProject("inheritance-junit4"));
+ final IType childType = javaProject.findType("example.JUnit4ChildTest");
+ assertNotNull(childType);
+
+ final List methods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(childType.getHandleIdentifier()), new NullProgressMonitor());
+ assertEquals(1, methods.size());
+ assertEquals("example.JUnit4ChildTest#inherited", methods.get(0).getFullName());
+ assertEquals("example.JUnit4ChildTest", methods.get(0).getExecutionClassName());
+ }
+
+ @Test
+ public void testJUnit4AnnotatedChildOverrideSurvivesUnannotatedMiddleOverride() throws Exception {
+ importProjects("inheritance-junit4");
+ final IJavaProject javaProject = JavaCore.create(WorkspaceHelper.getProject("inheritance-junit4"));
+ final IType childType = javaProject.findType("example.JUnit4ReannotatedChildTest");
+ assertNotNull(childType);
+
+ final List methods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(childType.getHandleIdentifier()), new NullProgressMonitor());
+ assertEquals(1, methods.size());
+ assertEquals("example.JUnit4ReannotatedChildTest#reannotated", methods.get(0).getFullName());
+ assertEquals(childType.getMethod("reannotated", new String[0]).getHandleIdentifier(),
+ methods.get(0).getJdtHandler());
+ }
+
+ @Test
+ public void testJUnit5UnannotatedOverrideSuppressesInheritedTest() throws Exception {
+ final IProject project = importProjects("preview-junit").get(0);
+ final IType childType = JavaCore.create(project).findType("example.InheritanceUnannotatedOverrideTest");
+ assertNotNull(childType);
+
+ final List methods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(childType.getHandleIdentifier()), new NullProgressMonitor());
+ assertTrue(methods.isEmpty());
+ }
+
+ @Test
+ public void testPackagePrivateTestMethodIsInheritedAcrossPackages() throws Exception {
+ final IProject project = importProjects("preview-junit").get(0);
+ final IType childType = JavaCore.create(project)
+ .findType("example.child.CrossPackageSameSignatureTest");
+ assertNotNull(childType);
+
+ final List methods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(childType.getHandleIdentifier()), new NullProgressMonitor());
+ assertEquals(1, methods.size());
+ assertEquals("example.child.CrossPackageSameSignatureTest#packagePrivateTest()",
+ methods.get(0).getFullName());
+ }
+
+ @Test
+ public void testDiscoverGenericInheritedMethod() throws Exception {
+ final IProject project = importProjects("preview-junit").get(0);
+ final IType childType = JavaCore.create(project).findType("example.GenericInheritanceChildTest");
+ assertNotNull(childType);
+
+ final List methods = TestSearchUtils.findDirectTestChildrenForClass(
+ Arrays.asList(childType.getHandleIdentifier()), new NullProgressMonitor());
+ assertEquals(1, methods.size());
+ assertEquals("example.GenericInheritanceChildTest", methods.get(0).getExecutionClassName());
+ }
}
diff --git a/java-extension/com.microsoft.java.test.plugin/src/main/java/com/microsoft/java/test/plugin/launchers/JUnitLaunchConfigurationDelegate.java b/java-extension/com.microsoft.java.test.plugin/src/main/java/com/microsoft/java/test/plugin/launchers/JUnitLaunchConfigurationDelegate.java
index c0711c5c..2c20699c 100644
--- a/java-extension/com.microsoft.java.test.plugin/src/main/java/com/microsoft/java/test/plugin/launchers/JUnitLaunchConfigurationDelegate.java
+++ b/java-extension/com.microsoft.java.test.plugin/src/main/java/com/microsoft/java/test/plugin/launchers/JUnitLaunchConfigurationDelegate.java
@@ -16,7 +16,6 @@
import com.microsoft.java.test.plugin.model.TestKind;
import com.microsoft.java.test.plugin.model.TestLevel;
import com.microsoft.java.test.plugin.util.JUnitPlugin;
-import com.microsoft.java.test.plugin.util.TestSearchUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.CoreException;
@@ -27,18 +26,17 @@
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.Launch;
-import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
-import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
import org.eclipse.jdt.launching.VMRunnerConfiguration;
import java.io.BufferedWriter;
@@ -192,7 +190,7 @@ private void addTestItemArgs(List arguments) throws CoreException {
arguments.add(fileName);
} else {
arguments.add("-test");
- arguments.add(resolveMethodTestName(this.args.testNames[0]));
+ arguments.add(resolveMethodTestName(this.args.testNames[0], getExecutionClassName(0)));
if (StringUtils.isNotBlank(this.args.uniqueId)) {
arguments.add("-uniqueId");
@@ -202,44 +200,43 @@ private void addTestItemArgs(List arguments) throws CoreException {
}
}
- private String resolveMethodTestName(String handleId) throws CoreException {
+ private String resolveMethodTestName(String handleId, String executionClassName) throws CoreException {
final IMethod method = (IMethod) JavaCore.create(handleId);
String testName = method.getElementName();
if ((this.args.testKind == TestKind.JUnit5 || this.args.testKind == TestKind.JUnit6) &&
method.getParameters().length > 0) {
- final ICompilationUnit unit = method.getCompilationUnit();
- if (unit == null) {
+ final ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
+ parser.setProject(method.getJavaProject());
+ final IBinding[] bindings = parser.createBindings(new IJavaElement[] { method },
+ new NullProgressMonitor());
+ if (bindings.length != 1 || !(bindings[0] instanceof IMethodBinding)) {
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,
- "Cannot get method declaration of method" + method.getElementName(), null)); //$NON-NLS-1$
+ "Cannot resolve method " + method.getElementName(), null)); //$NON-NLS-1$
}
+ testName += formatParameterTypes((IMethodBinding) bindings[0]);
+ }
+ final String className = StringUtils.isNotBlank(executionClassName) ? executionClassName :
+ method.getDeclaringType().getFullyQualifiedName();
+ return className + ':' + testName;
+ }
- final List 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 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) + ")";
- }
+ private String formatParameterTypes(IMethodBinding methodBinding) {
+ final List parameters = new LinkedList<>();
+ for (final ITypeBinding parameterType : methodBinding.getParameterTypes()) {
+ parameters.add(formatParameterType(parameterType));
}
- return method.getDeclaringType().getFullyQualifiedName() + ':' + testName;
+ return parameters.isEmpty() ? "" : "(" + String.join(",", parameters) + ")";
+ }
+
+ private String formatParameterType(ITypeBinding parameterType) {
+ final ITypeBinding erasedType = parameterType.getErasure();
+ final ITypeBinding type = erasedType != null ? erasedType : parameterType;
+ return type.isPrimitive() ? type.getQualifiedName() : type.getBinaryName();
+ }
+
+ private String getExecutionClassName(int index) {
+ return this.args.executionClassNames != null && index < this.args.executionClassNames.length ?
+ this.args.executionClassNames[index] : null;
}
private String createTestNamesFile(String[] testNames) throws CoreException {
@@ -266,8 +263,8 @@ private String createMethodTestNamesFile(String[] testNames) throws CoreExceptio
file.deleteOnExit();
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file), StandardCharsets.UTF_8));) {
- for (final String handleId : testNames) {
- bw.write(resolveMethodTestName(handleId));
+ for (int index = 0; index < testNames.length; index++) {
+ bw.write(resolveMethodTestName(testNames[index], getExecutionClassName(index)));
bw.newLine();
}
}
diff --git a/java-extension/com.microsoft.java.test.plugin/src/main/java/com/microsoft/java/test/plugin/launchers/JUnitLaunchUtils.java b/java-extension/com.microsoft.java.test.plugin/src/main/java/com/microsoft/java/test/plugin/launchers/JUnitLaunchUtils.java
index 738ba41a..55d3c5ae 100644
--- a/java-extension/com.microsoft.java.test.plugin/src/main/java/com/microsoft/java/test/plugin/launchers/JUnitLaunchUtils.java
+++ b/java-extension/com.microsoft.java.test.plugin/src/main/java/com/microsoft/java/test/plugin/launchers/JUnitLaunchUtils.java
@@ -18,6 +18,7 @@
import com.microsoft.java.test.plugin.util.JUnitPlugin;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -120,8 +121,13 @@ public static Response resolveLaunchArgument(List