From 7c023430fdbf7999f70d520de94b2ed821c7faad Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 28 May 2019 17:44:15 +0200 Subject: [PATCH] junit: fix pattern configurations by method in abstract class (IDEA-215065) GitOrigin-RevId: 3730b67a4f0c697f59cd7c1008ae1e4565203e73 --- .../module1/abstractPattern/TestA.java | 7 +++ .../module1/abstractPattern/TestB.java | 2 + .../module1/abstractPattern/TestC.java | 2 + .../java/execution/ConfigurationsTest.java | 20 ++++++++- .../execution/junit/TestDirectory.java | 11 ++--- .../intellij/execution/junit/TestObject.java | 3 ++ .../intellij/execution/junit/TestPackage.java | 43 ++++++++++--------- .../execution/junit/TestsPattern.java | 26 +++++------ 8 files changed, 75 insertions(+), 39 deletions(-) create mode 100644 java/java-tests/testData/junit/configurations/module1/abstractPattern/TestA.java create mode 100644 java/java-tests/testData/junit/configurations/module1/abstractPattern/TestB.java create mode 100644 java/java-tests/testData/junit/configurations/module1/abstractPattern/TestC.java diff --git a/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestA.java b/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestA.java new file mode 100644 index 000000000000..1a5480d94e63 --- /dev/null +++ b/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestA.java @@ -0,0 +1,7 @@ +package abstractPattern; +import junit.framework.TestCase; + +class TestA extends TestCase { + public void test1() {} + public void test2() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestB.java b/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestB.java new file mode 100644 index 000000000000..d20b6428ef4f --- /dev/null +++ b/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestB.java @@ -0,0 +1,2 @@ +package abstractPattern; +public class TestB extends TestA {} \ No newline at end of file diff --git a/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestC.java b/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestC.java new file mode 100644 index 000000000000..fa41d673a947 --- /dev/null +++ b/java/java-tests/testData/junit/configurations/module1/abstractPattern/TestC.java @@ -0,0 +1,2 @@ +package abstractPattern; +public class TestC extends TestA {} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/execution/ConfigurationsTest.java b/java/java-tests/testSrc/com/intellij/java/execution/ConfigurationsTest.java index 3991776f00d1..9d78a0c9da85 100644 --- a/java/java-tests/testSrc/com/intellij/java/execution/ConfigurationsTest.java +++ b/java/java-tests/testSrc/com/intellij/java/execution/ConfigurationsTest.java @@ -216,7 +216,7 @@ public class ConfigurationsTest extends BaseConfigurationTestCase { lines.remove(0); Assertion.compareUnordered( //category, filters, classNames... - new Object[]{"", "", "", psiClass.getQualifiedName(), + new Object[]{"", "", "pattern.TestA", "abstractPattern.TestB", "abstractPattern.TestC", psiClass.getQualifiedName(), "test1.DerivedTest", RT_INNER_TEST_NAME, "test1.nested.TestA", "test1.nested.TestWithJunit4", @@ -243,6 +243,24 @@ public class ConfigurationsTest extends BaseConfigurationTestCase { lines); } + public void testSameMethodPattern() throws IOException, ExecutionException { + Module module1 = getModule1(); + + JUnitConfiguration configuration = new JUnitConfiguration("", myProject); + configuration.getPersistentData().TEST_OBJECT = JUnitConfiguration.TEST_PATTERN; + configuration.getPersistentData().setPatterns(ContainerUtil.newLinkedHashSet("abstractPattern.TestB,test1", "abstractPattern.TestC,test1")); + configuration.setModule(module1); + JavaParameters parameters = checkCanRun(configuration); + String filePath = ContainerUtil.find(parameters.getProgramParametersList().getArray(), + value -> StringUtil.startsWithChar(value, '@') && !StringUtil.startsWith(value, "@w@")).substring(1); + List lines = FileUtilRt.loadLines(new File(filePath)); + lines.remove(0); + Assertion.compareUnordered( + //category, filters, classNames... + new Object[]{"", "", "abstractPattern.TestB,test1", "abstractPattern.TestC,test1"}, + lines); + } + public void testRunAllInPackageWhenPackageIsEmptyInModule() throws ExecutionException { assignJdk(getModule2()); JUnitConfiguration configuration = new JUnitConfiguration("", myProject); diff --git a/plugins/junit/src/com/intellij/execution/junit/TestDirectory.java b/plugins/junit/src/com/intellij/execution/junit/TestDirectory.java index fe5a96aca70d..d00dd1b23f31 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestDirectory.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestDirectory.java @@ -3,6 +3,7 @@ package com.intellij.execution.junit; import com.intellij.execution.CantRunException; import com.intellij.execution.ExecutionBundle; +import com.intellij.execution.Location; import com.intellij.execution.configurations.RuntimeConfigurationError; import com.intellij.execution.configurations.RuntimeConfigurationException; import com.intellij.execution.runners.ExecutionEnvironment; @@ -95,7 +96,7 @@ class TestDirectory extends TestPackage { } @Override - protected void searchTests5(Module module, TestClassFilter classFilter, Set classes) throws CantRunException { + protected void searchTests5(Module module, TestClassFilter classFilter, Set> classes) throws CantRunException { if (module != null) { PsiDirectory directory = getDirectory(getConfiguration().getPersistentData()); PsiPackage aPackage = JavaRuntimeConfigurationProducerBase.checkPackage(directory); @@ -110,12 +111,12 @@ class TestDirectory extends TestPackage { } @Override - protected boolean filterOutputByDirectoryForJunit5(Set classNames) { + protected boolean filterOutputByDirectoryForJunit5(Set> classNames) { return true; } @Override - protected String getFilters(Set foundClasses, String packageName) { + protected String getFilters(Set> foundClasses, String packageName) { return foundClasses.isEmpty() ? super.getFilters(foundClasses, packageName) : StringUtil.join(foundClasses, CLASS_NAME_FUNCTION, "||"); @@ -124,14 +125,14 @@ class TestDirectory extends TestPackage { @Override protected void collectClassesRecursively(TestClassFilter classFilter, Condition acceptClassCondition, - Set classes) throws CantRunException { + Set> classes) throws CantRunException { collectClassesRecursively(getDirectory(getConfiguration().getPersistentData()), acceptClassCondition, classes); } private static void collectClassesRecursively(PsiDirectory directory, Condition acceptAsTest, - Set classes) { + Set> classes) { PsiDirectory[] subDirectories = ReadAction.compute(() -> directory.getSubdirectories()); for (PsiDirectory subDirectory : subDirectories) { collectClassesRecursively(subDirectory, acceptAsTest, classes); diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index 6786c4450fe8..9c5bf57a2f2a 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -445,6 +445,9 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState CLASS_NAME_FUNCTION = member -> { - if (member instanceof PsiMethod) { - PsiClass containingClass = member.getContainingClass(); + protected static final Function, String> CLASS_NAME_FUNCTION = location -> { + if (location instanceof MethodLocation) { + PsiClass containingClass = ((MethodLocation)location).getContainingClass(); if (containingClass == null) return null; - return ClassUtil.getJVMClassName(containingClass) + "," + member.getName(); + return ClassUtil.getJVMClassName(containingClass) + "," + ((MethodLocation)location).getPsiElement().getName(); } - return member instanceof PsiClass ? ClassUtil.getJVMClassName((PsiClass)member) : null; + PsiElement psiElement = location.getPsiElement(); + return psiElement instanceof PsiClass ? ClassUtil.getJVMClassName((PsiClass)psiElement) : null; }; public TestPackage(JUnitConfiguration configuration, ExecutionEnvironment environment) { @@ -60,7 +59,7 @@ public class TestPackage extends TestObject { final JUnitConfiguration.Data data = getConfiguration().getPersistentData(); final Module module = getConfiguration().getConfigurationModule().getModule(); return new SearchForTestsTask(getConfiguration().getProject(), myServerSocket) { - private final Set myClasses = new LinkedHashSet<>(); + private final Set> myClasses = new LinkedHashSet<>(); @Override protected void search() { @@ -98,23 +97,25 @@ public class TestPackage extends TestObject { }; } - protected boolean filterOutputByDirectoryForJunit5(final Set classNames) { + protected boolean filterOutputByDirectoryForJunit5(final Set> classNames) { return getConfiguration().getTestSearchScope() == TestSearchScope.SINGLE_MODULE; } - protected String getFilters(Set foundClasses, String packageName) { + protected String getFilters(Set> foundClasses, String packageName) { return foundClasses.isEmpty() ? packageName.isEmpty() ? ".*" : packageName + "\\..*" : ""; } - protected void searchTests5(Module module, TestClassFilter classFilter, Set classes) throws CantRunException { } + protected void searchTests5(Module module, TestClassFilter classFilter, Set> classes) throws CantRunException { } - protected void searchTests(Module module, TestClassFilter classFilter, Set classes) throws CantRunException { + protected void searchTests(Module module, TestClassFilter classFilter, Set> classes) throws CantRunException { if (Registry.is("junit4.search.4.tests.all.in.scope", true)) { Condition acceptClassCondition = aClass -> ReadAction.compute(() -> aClass.isValid() && classFilter.isAccepted(aClass)); collectClassesRecursively(classFilter, acceptClassCondition, classes); } else { - ConfigurationUtil.findAllTestClasses(classFilter, module, classes); + LinkedHashSet psiClasses = new LinkedHashSet<>(); + ConfigurationUtil.findAllTestClasses(classFilter, module, psiClasses); + psiClasses.stream().map(PsiLocation::fromPsiElement).forEach(classes::add); } } @@ -130,7 +131,7 @@ public class TestPackage extends TestObject { protected void collectClassesRecursively(TestClassFilter classFilter, Condition acceptClassCondition, - Set classes) throws CantRunException { + Set> classes) throws CantRunException { PsiPackage aPackage = getPackage(getConfiguration().getPersistentData()); if (aPackage != null) { GlobalSearchScope scope = GlobalSearchScope.projectScope(getConfiguration().getProject()).intersectWith(classFilter.getScope()); @@ -141,7 +142,7 @@ public class TestPackage extends TestObject { private static void collectClassesRecursively(PsiPackage aPackage, GlobalSearchScope scope, Condition acceptAsTest, - Set classes) { + Set> classes) { PsiPackage[] psiPackages = ReadAction.compute(() -> aPackage.getSubPackages(scope)); for (PsiPackage psiPackage : psiPackages) { collectClassesRecursively(psiPackage, scope, acceptAsTest, classes); @@ -152,12 +153,14 @@ public class TestPackage extends TestObject { } } - protected static void collectInnerClasses(PsiClass aClass, Condition acceptAsTest, Set classes) { + protected static void collectInnerClasses(PsiClass aClass, Condition acceptAsTest, Set> classes) { if (Registry.is("junit4.accept.inner.classes", true)) { - classes.addAll(ReadAction.compute(() -> JBTreeTraverser.of(PsiClass::getInnerClasses).withRoot(aClass).filter(acceptAsTest).toList())); + classes.addAll(ReadAction.compute(() -> JBTreeTraverser.of(PsiClass::getInnerClasses) + .withRoot(aClass).filter(acceptAsTest).map(psiClass -> PsiLocation.fromPsiElement(psiClass)) + .toList())); } else if (acceptAsTest.value(aClass)) { - classes.add(aClass); + classes.add(PsiLocation.fromPsiElement(aClass)); } } diff --git a/plugins/junit/src/com/intellij/execution/junit/TestsPattern.java b/plugins/junit/src/com/intellij/execution/junit/TestsPattern.java index ba9c9a853d12..32b8bc8b543e 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestsPattern.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestsPattern.java @@ -1,12 +1,10 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.execution.junit; -import com.intellij.execution.CantRunException; -import com.intellij.execution.ConfigurationUtil; -import com.intellij.execution.ExecutionBundle; -import com.intellij.execution.JavaExecutionUtil; +import com.intellij.execution.*; import com.intellij.execution.configurations.RuntimeConfigurationException; import com.intellij.execution.configurations.RuntimeConfigurationWarning; +import com.intellij.execution.junit2.info.MethodLocation; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.testframework.SourceScope; import com.intellij.execution.util.JavaParametersUtil; @@ -42,21 +40,21 @@ public class TestsPattern extends TestPackage { } @Override - protected boolean filterOutputByDirectoryForJunit5(Set classNames) { + protected boolean filterOutputByDirectoryForJunit5(Set> classNames) { return super.filterOutputByDirectoryForJunit5(classNames) && classNames.isEmpty(); } @Override - protected void searchTests5(Module module, TestClassFilter classFilter, Set classes) { + protected void searchTests5(Module module, TestClassFilter classFilter, Set> classes) { searchTests(module, classFilter, classes, true); } @Override - protected void searchTests(Module module, TestClassFilter classFilter, Set classes) { + protected void searchTests(Module module, TestClassFilter classFilter, Set> classes) { searchTests(module, classFilter, classes, false); } - private void searchTests(Module module, TestClassFilter classFilter, Set classes, boolean junit5) { + private void searchTests(Module module, TestClassFilter classFilter, Set> classes, boolean junit5) { JUnitConfiguration.Data data = getConfiguration().getPersistentData(); Project project = getConfiguration().getProject(); for (String className : data.getPatterns()) { @@ -67,21 +65,23 @@ public class TestsPattern extends TestPackage { String methodName = StringUtil.getShortName(className, ','); PsiMethod[] methods = psiClass.findMethodsByName(methodName, true); if (methods.length > 0) { - classes.add(methods[0]); + classes.add(MethodLocation.elementInClass(methods[0], psiClass)); } else { - classes.add(psiClass); + classes.add(PsiLocation.fromPsiElement(psiClass)); } } else { - classes.add(psiClass); + classes.add(PsiLocation.fromPsiElement(psiClass)); } } } else { classes.clear(); if (!junit5) {//junit 5 process tests automatically - ConfigurationUtil.findAllTestClasses(classFilter, module, classes); + LinkedHashSet psiClasses = new LinkedHashSet<>(); + ConfigurationUtil.findAllTestClasses(classFilter, module, psiClasses); + psiClasses.stream().map(PsiLocation::fromPsiElement).forEach(classes::add); } return; } @@ -89,7 +89,7 @@ public class TestsPattern extends TestPackage { } @Override - protected String getFilters(Set foundClasses, String packageName) { + protected String getFilters(Set> foundClasses, String packageName) { return foundClasses.isEmpty() ? getConfiguration().getPersistentData().getPatternPresentation() : ""; }