From dfa683d35b59941989c5cb19eea621364c71ddcf Mon Sep 17 00:00:00 2001 From: Georgii Ustinov Date: Thu, 21 Nov 2024 14:30:25 +0200 Subject: [PATCH] [Java. Tests. JUnit] Support test state refreshing for Retrying test annotation IDEA-363599 GitOrigin-RevId: 408be1c0c2e7fdc0664b7297508726da3c47a637 --- .../TestRunLineMarkerProvider.java | 23 ++++++-- .../navigation/LineMarkerTestCase.java | 12 ++++ .../navigation/TestRunLineMarkerTest.java | 59 ++++++++++++------- .../AbstractJvmIdePlatformKindTooling.kt | 20 +++++-- .../KotlinTestRunLineMarkerContributor.kt | 4 +- .../kotlin/idea/util/RunConfigurationUtils.kt | 14 +++++ 6 files changed, 101 insertions(+), 31 deletions(-) create mode 100644 plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/util/RunConfigurationUtils.kt diff --git a/java/java-impl/src/com/intellij/testIntegration/TestRunLineMarkerProvider.java b/java/java-impl/src/com/intellij/testIntegration/TestRunLineMarkerProvider.java index 11e4ccb7064a..f9bcedce567a 100644 --- a/java/java-impl/src/com/intellij/testIntegration/TestRunLineMarkerProvider.java +++ b/java/java-impl/src/com/intellij/testIntegration/TestRunLineMarkerProvider.java @@ -24,11 +24,15 @@ import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + /** * @author Dmitry Avdeev */ public class TestRunLineMarkerProvider extends RunLineMarkerContributor implements DumbAware { - + private static final String URL_TEST_PREFIX = "java:test://"; + private static final String URL_SUITE_PREFIX = "java:suite://"; private static final Logger LOG = Logger.getInstance(TestRunLineMarkerProvider.class); @@ -38,7 +42,7 @@ public class TestRunLineMarkerProvider extends RunLineMarkerContributor implemen PsiElement element = e.getParent(); if (element instanceof PsiClass psiClass) { if (!isTestClass(psiClass)) return null; - String url = "java:suite://" + ClassUtil.getJVMClassName(psiClass); + String url = URL_SUITE_PREFIX + ClassUtil.getJVMClassName(psiClass); TestStateStorage.Record state = TestStateStorage.getInstance(e.getProject()).getState(url); return getInfo(state, true, PsiMethodUtil.hasMainInClass(psiClass) ? 1 : 0); } @@ -46,8 +50,19 @@ public class TestRunLineMarkerProvider extends RunLineMarkerContributor implemen PsiClass containingClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class); if (!isTestMethod(containingClass, psiMethod)) return null; if (isIgnoredForGradleConfiguration(containingClass, psiMethod)) return null; - String url = "java:test://" + ClassUtil.getJVMClassName(containingClass) + "/" + psiMethod.getName(); - TestStateStorage.Record state = TestStateStorage.getInstance(e.getProject()).getState(url); + String urlSuffix = ClassUtil.getJVMClassName(containingClass) + "/" + psiMethod.getName(); + + List urlList = new ArrayList<>(); + urlList.add(URL_TEST_PREFIX + urlSuffix); + if (isGradleConfiguration(containingClass)) { + urlList.add(URL_SUITE_PREFIX + urlSuffix); + } + + TestStateStorage.Record state = null; + for (String url : urlList) { + state = TestStateStorage.getInstance(e.getProject()).getState(url); + if (state != null) break; + } return getInfo(state, false, 0); } } diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/navigation/LineMarkerTestCase.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/navigation/LineMarkerTestCase.java index 1351052253c8..ced84a3319e9 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/navigation/LineMarkerTestCase.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/navigation/LineMarkerTestCase.java @@ -3,6 +3,9 @@ package com.intellij.java.codeInsight.navigation; import com.intellij.execution.RunManager; import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.impl.RunManagerImpl; +import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl; import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; import java.util.HashSet; @@ -25,4 +28,13 @@ abstract public class LineMarkerTestCase extends LightJavaCodeInsightFixtureTest super.tearDown(); } } + + protected void setupRunConfiguration(RunConfiguration configuration) { + RunManager manager = RunManager.getInstance(myFixture.getProject()); + RunnerAndConfigurationSettings runnerAndConfigurationSettings = + new RunnerAndConfigurationSettingsImpl((RunManagerImpl)manager, configuration); + manager.addConfiguration(runnerAndConfigurationSettings); + myTempSettings.add(runnerAndConfigurationSettings); + manager.setSelectedConfiguration(runnerAndConfigurationSettings); + } } diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/navigation/TestRunLineMarkerTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/navigation/TestRunLineMarkerTest.java index bfa653b0d905..66ca5c006775 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/navigation/TestRunLineMarkerTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/navigation/TestRunLineMarkerTest.java @@ -27,7 +27,9 @@ import com.intellij.testFramework.DumbModeTestUtils; import com.intellij.testFramework.TestActionEvent; import com.intellij.testIntegration.TestRunLineMarkerProvider; import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import javax.swing.*; import java.util.Date; import java.util.List; @@ -44,26 +46,15 @@ public class TestRunLineMarkerTest extends LineMarkerTestCase { } public void testNestedTestClass() { - TestStateStorage stateStorage = TestStateStorage.getInstance(getProject()); String testUrl = "java:suite://Main$MainTest"; - try { - stateStorage.writeState(testUrl, new TestStateStorage.Record(TestStateInfo.Magnitude.FAILED_INDEX.getValue(), new Date(), 0, 0, "", - "", "")); - myFixture.addClass("package junit.framework; public class TestCase {}"); - PsiFile file = myFixture.configureByText("MainTest.java", """ + myFixture.addClass("package junit.framework; public class TestCase {}"); + myFixture.configureByText("MainTest.java", """ public class Main { public static class MainTest extends junit.framework.TestCase { public void testFoo() { } }}"""); - - RunLineMarkerContributor.Info info = new TestRunLineMarkerProvider().getInfo(file.findElementAt(myFixture.getCaretOffset())); - assertNotNull(info); - assertEquals(AllIcons.RunConfigurations.TestState.Red2, info.icon); - } - finally { - stateStorage.removeState(testUrl); - } + doTestState(testUrl, TestStateInfo.Magnitude.FAILED_INDEX.getValue(), AllIcons.RunConfigurations.TestState.Red2); } public void testTestAnnotationInSuperMethodOnly() { @@ -227,6 +218,23 @@ public class TestRunLineMarkerTest extends LineMarkerTestCase { doTest(); } + public void testRetryingTestAnnotationSupportGradle() { + JUnit5TestFrameworkSetupUtil.setupJunit5WithExtensionLibrary(myFixture); + + myFixture.configureByText("ClassWithRetryingTest.java", """ + import org.junitpioneer.jupiter.RetryingTest; + + public class ClassWithRetryingTest { + @RetryingTest(value = 2) + void retryingTest() { + } + } + """); + setupRunConfiguration(new MockGradleRunConfiguration(myFixture.getProject(), "ClassWithRetryingTest")); + doTestState("java:suite://ClassWithRetryingTest/retryingTest", TestStateInfo.Magnitude.PASSED_INDEX.getValue(), AllIcons.RunConfigurations.TestState.Green2); + + } + private void doTest() { List markList = myFixture.findGuttersAtCaret(); assertSize(1, markList); @@ -273,15 +281,26 @@ public class TestRunLineMarkerTest extends LineMarkerTestCase { JUnit5TestFrameworkSetupUtil.setupJUnit5Library(myFixture); myFixture.addClass("package org.junit.jupiter.api; public @interface Disabled {}"); - RunManager manager = RunManager.getInstance(myFixture.getProject()); - RunnerAndConfigurationSettings runnerAndConfigurationSettings = - new RunnerAndConfigurationSettingsImpl((RunManagerImpl)manager,configuration); - manager.addConfiguration(runnerAndConfigurationSettings); - myTempSettings.add(runnerAndConfigurationSettings); - manager.setSelectedConfiguration(runnerAndConfigurationSettings); + setupRunConfiguration(configuration); myFixture.configureByText("DisabledMethodTest.java", testClass); List marks = myFixture.findGuttersAtCaret(); assertEquals(marksCount, marks.size()); } + + private void doTestState(String testUrl, int indexValue, @NotNull Icon expectedIcon) { + TestStateStorage stateStorage = TestStateStorage.getInstance(getProject()); + try { + stateStorage.writeState(testUrl, new TestStateStorage.Record(indexValue, new Date(), 0, 0, "", + "", "")); + + + RunLineMarkerContributor.Info info = new TestRunLineMarkerProvider().getInfo(myFixture.getFile().findElementAt(myFixture.getCaretOffset())); + assertNotNull(info); + assertEquals(expectedIcon, info.icon); + } + finally { + stateStorage.removeState(testUrl); + } + } } diff --git a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/tooling/AbstractJvmIdePlatformKindTooling.kt b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/tooling/AbstractJvmIdePlatformKindTooling.kt index c04f034bc335..7055a47e56c8 100644 --- a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/tooling/AbstractJvmIdePlatformKindTooling.kt +++ b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/tooling/AbstractJvmIdePlatformKindTooling.kt @@ -12,6 +12,7 @@ import com.intellij.testIntegration.TestFramework import org.jetbrains.kotlin.idea.highlighter.KotlinTestRunLineMarkerContributor import org.jetbrains.kotlin.idea.projectModel.KotlinPlatform import org.jetbrains.kotlin.idea.testIntegration.framework.KotlinPsiBasedTestFramework +import org.jetbrains.kotlin.idea.util.RunConfigurationUtils import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFunction @@ -74,16 +75,25 @@ abstract class AbstractJvmIdePlatformKindTooling : IdePlatformKindTooling() { } ?: return null return when (declaration) { - is KtClassOrObject -> listOf("java:suite://$qualifiedName") - is KtNamedFunction -> listOf( - "java:test://$qualifiedName/${declaration.name}", - "java:test://$qualifiedName.${declaration.name}" - ) + is KtClassOrObject -> listOf("$URL_SUITE_PREFIX$qualifiedName") + is KtNamedFunction -> { + val urlList = listOf( + "$URL_TEST_PREFIX$qualifiedName/${declaration.name}", + "$URL_TEST_PREFIX$qualifiedName.${declaration.name}" + ) + if (RunConfigurationUtils.isGradleRunConfiguration(declaration)) { + urlList + "$URL_SUITE_PREFIX$qualifiedName/${declaration.name}" + } else { + urlList + } + } else -> null } } private companion object { + private const val URL_TEST_PREFIX = "java:test://" + private const val URL_SUITE_PREFIX = "java:suite://" val TEST_FRAMEWORK_NAME_KEY: Key?> = Key.create>("TestFramework:name") } } \ No newline at end of file diff --git a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/highlighter/KotlinTestRunLineMarkerContributor.kt b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/highlighter/KotlinTestRunLineMarkerContributor.kt index 85195d4a5126..41ec6425baea 100644 --- a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/highlighter/KotlinTestRunLineMarkerContributor.kt +++ b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/highlighter/KotlinTestRunLineMarkerContributor.kt @@ -1,7 +1,6 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.highlighter -import com.intellij.execution.RunManager import com.intellij.execution.TestStateStorage import com.intellij.execution.lineMarker.ExecutorAction import com.intellij.execution.lineMarker.RunLineMarkerContributor @@ -18,6 +17,7 @@ import org.jetbrains.kotlin.idea.base.facet.platform.platform import org.jetbrains.kotlin.idea.base.util.isUnderKotlinSourceRootTypes import org.jetbrains.kotlin.idea.base.util.module import org.jetbrains.kotlin.idea.testIntegration.framework.KotlinPsiBasedTestFramework +import org.jetbrains.kotlin.idea.util.RunConfigurationUtils import org.jetbrains.kotlin.konan.target.Architecture import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget @@ -44,7 +44,7 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() { */ private fun KtNamedDeclaration.isIgnoredForGradleConfiguration(includeSlowProviders: Boolean): Boolean { val ktNamedFunction = this.safeAs().takeIf { - RunManager.getInstance(getProject()).selectedConfiguration?.type?.id == "GradleRunConfiguration" + RunConfigurationUtils.isGradleRunConfiguration(this) } ?: return false val ktClassOrObject = ktNamedFunction.containingClassOrObject ?: return false diff --git a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/util/RunConfigurationUtils.kt b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/util/RunConfigurationUtils.kt new file mode 100644 index 000000000000..4a597ff4c6ea --- /dev/null +++ b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/util/RunConfigurationUtils.kt @@ -0,0 +1,14 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.util + +import com.intellij.execution.RunManager +import com.intellij.psi.PsiElement + +internal object RunConfigurationUtils { + /** + * Checks if the current run configuration is a Gradle run configuration. + */ + fun isGradleRunConfiguration(element: PsiElement): Boolean { + return RunManager.getInstance(element.project).selectedConfiguration?.type?.id == "GradleRunConfiguration" + } +} \ No newline at end of file