[Java. Tests. JUnit] Support test state refreshing for Retrying test annotation

IDEA-363599

GitOrigin-RevId: 408be1c0c2e7fdc0664b7297508726da3c47a637
This commit is contained in:
Georgii Ustinov
2024-11-21 14:57:55 +00:00
committed by intellij-monorepo-bot
parent 0e2253a62e
commit dfa683d35b
6 changed files with 101 additions and 31 deletions
@@ -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<String> 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);
}
}
@@ -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);
}
}
@@ -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 Main<caret>Test 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 <caret>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<GutterMark> 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<GutterMark> 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);
}
}
}
@@ -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<CachedValue<String>?> = Key.create<CachedValue<String>>("TestFramework:name")
}
}
@@ -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<KtNamedFunction>().takeIf {
RunManager.getInstance(getProject()).selectedConfiguration?.type?.id == "GradleRunConfiguration"
RunConfigurationUtils.isGradleRunConfiguration(this)
} ?: return false
val ktClassOrObject = ktNamedFunction.containingClassOrObject ?: return false
@@ -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"
}
}