mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-02 00:57:59 +07:00
[jvm] IDEA-283602 Migrate JUnit 4 converter to UAST
GitOrigin-RevId: f7bfbf867ecb02a04854bcc266146720ac6a8a6a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0db7d61240
commit
c18db65d64
@@ -52,6 +52,11 @@
|
||||
groupPathKey="jvm.inspections.group.name" groupKey="jvm.inspections.test.frameworks.group.name"
|
||||
key="jvm.inspections.junit3.super.teardown.display.name"
|
||||
implementationClass="com.intellij.codeInspection.test.junit.JUnit3SuperTearDownInspection"/>
|
||||
<localInspection language="UAST" enabledByDefault="true" level="INFORMATION" shortName="Junit4Converter"
|
||||
groupBundle="messages.JvmAnalysisBundle" bundle="messages.JvmAnalysisBundle"
|
||||
groupPathKey="jvm.inspections.group.name" groupKey="jvm.inspections.test.frameworks.group.name"
|
||||
key="jvm.inspections.junit4.converter.display.name"
|
||||
implementationClass="com.intellij.codeInspection.test.junit.JUnit4ConverterInspection"/>
|
||||
<localInspection language="UAST" enabledByDefault="true" level="WARNING" shortName="JUnit5AssertionsConverter"
|
||||
groupBundle="messages.JvmAnalysisBundle" bundle="messages.JvmAnalysisBundle"
|
||||
groupPathKey="jvm.inspections.group.name" groupKey="jvm.inspections.test.frameworks.group.name"
|
||||
|
||||
@@ -96,6 +96,14 @@ jvm.inspections.test.case.with.constructor.problem.descriptor.initializer=Initia
|
||||
jvm.inspections.junit3.super.teardown.display.name=JUnit 3 'super.tearDown()' is not called from 'finally' block
|
||||
jvm.inspections.junit3.super.teardown.problem.descriptor=<code>#ref()</code> is not called from 'finally' block #loc
|
||||
|
||||
jvm.inspections.junit4.converter.display.name=JUnit 3 test can be JUnit 4
|
||||
jvm.inspections.junit4.converter.problem.descriptor=<code>#ref</code> could be converted to JUnit4 test case
|
||||
jvm.inspections.junit4.converter.quickfix.name=Convert to JUnit 4 test case
|
||||
jvm.inspections.junit4.converter.quickfix.conflict.semantics=Method call {0} may change semantics when {1} is converted to JUnit 4
|
||||
jvm.inspections.junit4.converter.quickfix.conflict.suite=Migration of suite method for {0} has side effects which will be deleted
|
||||
jvm.inspections.junit4.converter.quickfix.conflict.name=Method {0} will have a name collision with its super method
|
||||
jvm.inspections.junit4.converter.quickfix.conflict.call.compile=Method call {0} will not compile when {1} is converted to JUnit 4
|
||||
|
||||
jvm.inspections.junit5.converter.display.name=JUnit 4 test can be JUnit 5
|
||||
jvm.inspections.junit5.converter.problem.descriptor=#ref can be JUnit 5 test
|
||||
jvm.inspections.junit5.converter.quickfix=Migrate to JUnit 5
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection.test.junit
|
||||
|
||||
import com.intellij.analysis.JvmAnalysisBundle
|
||||
import com.intellij.codeInspection.AbstractBaseUastLocalInspectionTool
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.codeInspection.registerUProblem
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.util.InheritanceUtil
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import com.intellij.uast.UastHintedVisitorAdapter
|
||||
import com.siyeh.ig.junit.JUnitCommonClassNames.JUNIT_FRAMEWORK_TEST_CASE
|
||||
import com.siyeh.ig.junit.JUnitCommonClassNames.ORG_JUNIT_TEST
|
||||
import org.jetbrains.uast.UClass
|
||||
import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor
|
||||
|
||||
class JUnit4ConverterInspection : AbstractBaseUastLocalInspectionTool() {
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(holder.file)) return PsiElementVisitor.EMPTY_VISITOR
|
||||
if (JavaPsiFacade.getInstance(holder.project).findClass(JUNIT_FRAMEWORK_TEST_CASE, holder.file.resolveScope) == null) { // junit 3
|
||||
return PsiElementVisitor.EMPTY_VISITOR
|
||||
}
|
||||
if (JavaPsiFacade.getInstance(holder.project).findClass(ORG_JUNIT_TEST, holder.file.resolveScope) == null) { // junit 4
|
||||
return PsiElementVisitor.EMPTY_VISITOR
|
||||
}
|
||||
return UastHintedVisitorAdapter.create(
|
||||
holder.file.language,
|
||||
JUnit4ConverterInspectionVisitor(holder),
|
||||
arrayOf(UClass::class.java),
|
||||
directOnly = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class JUnit4ConverterInspectionVisitor(private val holder: ProblemsHolder) : AbstractUastNonRecursiveVisitor() {
|
||||
override fun visitClass(node: UClass): Boolean {
|
||||
val javaClass = node.javaPsi
|
||||
if (!InheritanceUtil.isInheritor(javaClass, JUNIT_FRAMEWORK_TEST_CASE)) return true
|
||||
val message = JvmAnalysisBundle.message("jvm.inspections.junit4.converter.problem.descriptor")
|
||||
holder.registerUProblem(node, message, JUnit4ConverterQuickfix())
|
||||
return true
|
||||
}
|
||||
}
|
||||
+311
@@ -0,0 +1,311 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection.test.junit
|
||||
|
||||
import com.intellij.analysis.JvmAnalysisBundle
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
import com.intellij.codeInspection.isInheritorOf
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.lang.jvm.actions.*
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.CommonClassNames.JAVA_LANG_CLASS
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.SmartPointerManager
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException
|
||||
import com.intellij.refactoring.ui.ConflictsDialog
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||
import com.intellij.refactoring.util.RefactoringUIUtil
|
||||
import com.intellij.util.asSafely
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import com.siyeh.ig.callMatcher.CallMatcher
|
||||
import com.siyeh.ig.junit.JUnitCommonClassNames.*
|
||||
import com.siyeh.ig.psiutils.TypeUtils
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.generate.getUastElementFactory
|
||||
import org.jetbrains.uast.generate.replace
|
||||
import org.jetbrains.uast.util.isInFinallyBlock
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||
|
||||
class JUnit4ConverterQuickfix : LocalQuickFix {
|
||||
override fun getFamilyName(): String = JvmAnalysisBundle.message("jvm.inspections.junit4.converter.quickfix.name")
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val junit3Class = descriptor.psiElement.getUastParentOfType<UClass>() ?: return
|
||||
val conflicts = findConflicts(junit3Class)
|
||||
|
||||
val runnable = Runnable { WriteAction.run<RuntimeException> { performConversion(junit3Class) } }
|
||||
|
||||
if (!conflicts.isEmpty) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode && !ConflictsInTestsException.isTestIgnore()) {
|
||||
throw ConflictsInTestsException(conflicts.values())
|
||||
}
|
||||
else if (!ConflictsDialog(junit3Class.javaPsi.project, conflicts, runnable).showAndGet()) return
|
||||
}
|
||||
runnable.run()
|
||||
}
|
||||
|
||||
private fun performConversion(junit3Class: UClass) {
|
||||
for (method in junit3Class.methods) {
|
||||
val methodPtr = SmartPointerManager.createPointer(method.sourcePsi ?: continue)
|
||||
if (method.name.startsWith("test")) {
|
||||
addAnnotation(method, ORG_JUNIT_TEST)
|
||||
}
|
||||
else if (method.name == SETUP) {
|
||||
addAnnotation(method, ORG_JUNIT_BEFORE)
|
||||
transformSetUpOrTearDownMethod(method)
|
||||
}
|
||||
else if (method.name == TEARDOWN) {
|
||||
addAnnotation(method, ORG_JUNIT_AFTER)
|
||||
transformSetUpOrTearDownMethod(method)
|
||||
} else if (method.name == SUITE) {
|
||||
transformTesSuite(method)
|
||||
}
|
||||
methodPtr.element?.toUElementOfType<UMethod>()?.accept(AssertionsConverter())
|
||||
}
|
||||
junit3Class.javaPsi.extendsList?.referenceElements?.forEach { it.delete() }
|
||||
}
|
||||
|
||||
private fun findConflicts(junit3Class: UClass): MultiMap<PsiElement, String> {
|
||||
val conflicts = MultiMap<PsiElement, String>()
|
||||
findNonMigratableTestSuiteConflicts(junit3Class)?.let { conflicts.putValue(it.first, it.second) }
|
||||
conflicts.putAllValues(findInheritedUsagesConflicts(junit3Class))
|
||||
conflicts.putAllValues(findSetupTeardownNameConflicts(junit3Class))
|
||||
return conflicts
|
||||
}
|
||||
|
||||
private fun findInheritedUsagesConflicts(junit3Class: UClass): MultiMap<PsiElement, String> {
|
||||
val conflicts = MultiMap<PsiElement, String>()
|
||||
junit3Class.accept(object : AbstractUastVisitor() {
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
if (migratableMethodNames.contains(node.methodName)) return false
|
||||
if (node.kind == UastCallKind.CONSTRUCTOR_CALL) return false
|
||||
val method = node.resolveToUElement()?.asSafely<UMethod>() ?: return false
|
||||
if (migratableConstructorNames.contains(method.name)) return false
|
||||
if (method.isStatic) return false // filter out assertions, they will be converted later
|
||||
val containingMethodClass = method.javaPsi.containingClass ?: return false
|
||||
if (isAvailableAfterMigration(containingMethodClass.qualifiedName ?: return false)) return false
|
||||
val sourcePsi = node.sourcePsi ?: return false
|
||||
val expressionText = CommonRefactoringUtil.htmlEmphasize(sourcePsi.text)
|
||||
val classText = RefactoringUIUtil.getDescription(junit3Class.javaPsi, false)
|
||||
val availableSupers = method.javaPsi.findSuperMethods()
|
||||
.mapNotNull { it.containingClass?.qualifiedName }
|
||||
.filter { isAvailableAfterMigration(it) }
|
||||
val problem = if (availableSupers.isNotEmpty()) {
|
||||
JvmAnalysisBundle.message("jvm.inspections.junit4.converter.quickfix.conflict.semantics", expressionText, classText)
|
||||
} else {
|
||||
JvmAnalysisBundle.message("jvm.inspections.junit4.converter.quickfix.conflict.call.compile", expressionText, classText)
|
||||
}
|
||||
conflicts.putValue(node.sourcePsi, problem)
|
||||
return false
|
||||
}
|
||||
})
|
||||
return conflicts
|
||||
}
|
||||
|
||||
private fun isAvailableAfterMigration(fqn: String): Boolean = !fqn.startsWith("junit.framework")
|
||||
|
||||
private fun findNonMigratableTestSuiteConflicts(junit3Class: UClass): Pair<PsiElement, String>? {
|
||||
var conflict: Pair<PsiElement, String>? = null
|
||||
junit3Class.accept(object : AbstractUastVisitor() {
|
||||
override fun visitElement(node: UElement): Boolean = conflict != null
|
||||
|
||||
override fun visitMethod(node: UMethod): Boolean {
|
||||
if (conflict != null) return true
|
||||
if (node.name == SUITE && !isMigratableTestSuite(node)) {
|
||||
val containingClass = node.getContainingUClass() ?: return false
|
||||
val classText = RefactoringUIUtil.getDescription(containingClass.javaPsi, false)
|
||||
conflict = node to JvmAnalysisBundle.message("jvm.inspections.junit4.converter.quickfix.conflict.suite", classText)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isMigratableTestSuite(method: UMethod): Boolean {
|
||||
var migratable = true
|
||||
method.uastBody?.accept(object : AbstractUastVisitor() {
|
||||
override fun visitElement(node: UElement): Boolean = !migratable
|
||||
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
if (!migratable) return true
|
||||
when (node.kind) {
|
||||
UastCallKind.METHOD_CALL -> {
|
||||
when {
|
||||
addTestMatcher.uCallMatches(node) -> {
|
||||
val argumentExpr = node.valueArguments.first().getUCallExpression(searchLimit = 2) ?: return false
|
||||
if (argumentExpr.isSuite()) return true
|
||||
migratable = false
|
||||
}
|
||||
addTestSuiteMatcher.uCallMatches(node) -> { }
|
||||
else -> migratable = false
|
||||
}
|
||||
}
|
||||
UastCallKind.CONSTRUCTOR_CALL -> {
|
||||
if (node.returnType?.isInheritorOf(JUNIT_FRAMEWORK_TEST_SUITE) == false) migratable = false
|
||||
}
|
||||
else -> migratable = false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun visitReturnExpression(node: UReturnExpression): Boolean {
|
||||
if (!migratable) return true
|
||||
if (node.returnExpression?.getExpressionType()?.isInheritorOf(JUNIT_FRAMEWORK_TEST_SUITE) == false) migratable = false
|
||||
return false
|
||||
}
|
||||
})
|
||||
return migratable
|
||||
}
|
||||
})
|
||||
return conflict
|
||||
}
|
||||
|
||||
fun UCallExpression.isSuite() = valueArgumentCount == 0
|
||||
&& methodName == SUITE
|
||||
&& TypeUtils.resolvedClassName(returnType) == JUNIT_FRAMEWORK_TEST
|
||||
|
||||
private fun findSetupTeardownNameConflicts(junit3Class: UClass): MultiMap<PsiElement, String> {
|
||||
val conflicts = MultiMap<PsiElement, String>()
|
||||
junit3Class.accept(object : AbstractUastVisitor() {
|
||||
override fun visitMethod(node: UMethod): Boolean {
|
||||
if (node.name != TEARDOWN && node.name != SETUP) return true
|
||||
val superMethods = node.javaPsi.findSuperMethods().toMutableList()
|
||||
for (method in superMethods) {
|
||||
if (method.containingClass?.qualifiedName == JUNIT_FRAMEWORK_TEST_CASE) {
|
||||
superMethods.remove(method)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (superMethods.isEmpty()) return true
|
||||
conflicts.putValue(node, JvmAnalysisBundle.message(
|
||||
"jvm.inspections.junit4.converter.quickfix.conflict.name", node.uastAnchor?.sourcePsi?.text
|
||||
))
|
||||
return true
|
||||
}
|
||||
})
|
||||
return conflicts
|
||||
}
|
||||
|
||||
private fun addAnnotation(aClass: PsiClass, fqn: String, vararg parameters: AnnotationAttributeRequest) {
|
||||
createAddAnnotationActions(aClass, annotationRequest(fqn, *parameters)).forEach {
|
||||
it.invoke(aClass.project, null, aClass.containingFile)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addAnnotation(method: UMethod, fqn: String, vararg parameters: AnnotationAttributeRequest) {
|
||||
createAddAnnotationActions(method.javaPsi, annotationRequest(fqn, *parameters)).forEach {
|
||||
it.invoke(method.javaPsi.project, null, method.sourcePsi?.containingFile)
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformSetUpOrTearDownMethod(method: UMethod) {
|
||||
val fixModifierOverrideActions = createModifierActions(method, modifierRequest(JvmModifier.PUBLIC, true)) +
|
||||
createChangeOverrideActions(method, shouldBePresent = false)
|
||||
fixModifierOverrideActions.forEach { it.invoke(method.javaPsi.project, null, method.javaPsi.containingFile) }
|
||||
method.accept(SuperCallRemoverVisitor(method.name))
|
||||
}
|
||||
|
||||
private fun transformTesSuite(method: UMethod) {
|
||||
val containingClass = method.javaPsi.containingClass ?: return
|
||||
val classValues = findAddedTestSuites(method).map { AnnotationAttributeValueRequest.ClassValue(it) }
|
||||
addAnnotation(containingClass, ORG_JUNIT_RUNNERS_SUITE_SUITE_CLASSES, arrayAttribute("value", classValues))
|
||||
addAnnotation(containingClass, ORG_JUNIT_RUNNER_RUN_WITH, classAttribute("value", ORG_JUNIT_RUNNERS_SUITE))
|
||||
method.sourcePsi?.delete()
|
||||
}
|
||||
|
||||
private fun findAddedTestSuites(method: UMethod): List<String> {
|
||||
val classLiterals = mutableListOf<String>()
|
||||
method.uastBody?.accept(object : AbstractUastVisitor() {
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
when {
|
||||
addTestMatcher.uCallMatches(node) -> {
|
||||
val qualified = node.valueArguments.first().asSafely<UQualifiedReferenceExpression>()
|
||||
if(qualified?.selector?.asSafely<UCallExpression>()?.isSuite() == false) return false // don't show conflict in preview
|
||||
val receiver = qualified?.receiver.asSafely<UReferenceExpression>() ?: return false
|
||||
classLiterals.add(receiver.getQualifiedName() ?: return false)
|
||||
}
|
||||
addTestSuiteMatcher.uCallMatches(node) -> {
|
||||
val type = node.valueArguments
|
||||
.first().getQualifiedChain()
|
||||
.first().asSafely<UClassLiteralExpression>()
|
||||
?.type ?: return false
|
||||
classLiterals.add(TypeUtils.resolvedClassName(type) ?: return false)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
return classLiterals
|
||||
}
|
||||
|
||||
private class SuperCallRemoverVisitor(private val methodName: String) : AbstractUastVisitor() {
|
||||
override fun visitSuperExpression(node: USuperExpression): Boolean {
|
||||
val qualifiedSuper = node.uastParent.asSafely<UQualifiedReferenceExpression>() ?: return false
|
||||
val selector = qualifiedSuper.selector.asSafely<UCallExpression>() ?: return false
|
||||
if (selector.methodName != methodName) return false
|
||||
if (qualifiedSuper.isInFinallyBlock()) { // tearDown methods are often in finally clauses
|
||||
val tryExpression = qualifiedSuper.getParentOfType(
|
||||
parentClass = UTryExpression::class.java,
|
||||
strict = true,
|
||||
terminators = arrayOf(UMethod::class.java)
|
||||
) ?: return false
|
||||
val finallyClause = tryExpression.finallyClause ?: return false
|
||||
if (finallyClause.asSafely<UBlockExpression>()?.expressions?.size == 1) {
|
||||
val catchClauses = tryExpression.catchClauses
|
||||
if (catchClauses.isEmpty() && !tryExpression.hasResources) {
|
||||
val tryExprSrcPsi = tryExpression.sourcePsi ?: return false
|
||||
val tryClauseSrcPsi = tryExpression.tryClause.sourcePsi ?: return false
|
||||
val first = tryClauseSrcPsi.firstChild?.nextSibling
|
||||
val last = tryClauseSrcPsi.lastChild?.prevSibling
|
||||
tryExprSrcPsi.parent?.addRangeAfter(first, last, tryExpression.sourcePsi)
|
||||
tryExprSrcPsi.delete()
|
||||
} else {
|
||||
finallyClause.sourcePsi?.delete()
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
qualifiedSuper.sourcePsi?.delete()
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private class AssertionsConverter : AbstractUastVisitor() {
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
if (!node.isPsiValid) return true
|
||||
val method = node.resolveToUElement()?.asSafely<UMethod>() ?: return false
|
||||
if (!method.isStatic) return false // assert methods are always static
|
||||
val containingMethodClass = method.javaPsi.containingClass ?: return false
|
||||
val containingClassFqn = containingMethodClass.qualifiedName
|
||||
if (containingClassFqn != JUNIT_FRAMEWORK_ASSERT && containingClassFqn != JUNIT_FRAMEWORK_TEST_CASE) return false
|
||||
val project = node.sourcePsi?.project ?: return true
|
||||
val elementFactory = node.getUastElementFactory(project) ?: return false
|
||||
val newCall = elementFactory.createCallExpression(
|
||||
elementFactory.createQualifiedReference(ORG_JUNIT_ASSERT, node.sourcePsi),
|
||||
method.name, node.valueArguments, node.returnType, UastCallKind.METHOD_CALL
|
||||
) ?: return false
|
||||
node.replace(newCall)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SETUP = "setUp"
|
||||
private const val TEARDOWN = "tearDown"
|
||||
private const val SUITE = "suite"
|
||||
private const val ADD_TEST = "addTest"
|
||||
private const val ADD_TEST_SUITE = "addTestSuite"
|
||||
|
||||
|
||||
private val migratableMethodNames = listOf(SETUP, TEARDOWN, SUITE, ADD_TEST, ADD_TEST_SUITE)
|
||||
|
||||
private val migratableConstructorNames = listOf("TestSuite")
|
||||
|
||||
private val addTestMatcher = CallMatcher.instanceCall(JUNIT_FRAMEWORK_TEST_SUITE, ADD_TEST)
|
||||
.parameterTypes(JUNIT_FRAMEWORK_TEST)
|
||||
|
||||
private val addTestSuiteMatcher = CallMatcher.instanceCall(JUNIT_FRAMEWORK_TEST_SUITE, ADD_TEST_SUITE)
|
||||
.parameterTypes(JAVA_LANG_CLASS)
|
||||
}
|
||||
}
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
package com.intellij.codeInspection.tests.java.test.junit
|
||||
|
||||
import com.intellij.codeInspection.tests.ULanguage
|
||||
import com.intellij.codeInspection.tests.test.junit.JUnit4ConverterInspectionTestBase
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||
|
||||
class JavaJUnit4ConverterInspectionTest : JUnit4ConverterInspectionTestBase() {
|
||||
fun `test highlighting`() {
|
||||
myFixture.testHighlighting(ULanguage.JAVA, """
|
||||
import junit.framework.TestCase;
|
||||
|
||||
class <warning descr="'JUnit3Test' could be converted to JUnit4 test case">JUnit3Test</warning> extends TestCase {
|
||||
public void testAddition() {
|
||||
assertEquals(2, 1 + 1);
|
||||
}
|
||||
}""".trimIndent())
|
||||
}
|
||||
|
||||
fun `test quickfix lifecycle method name conflict`() {
|
||||
myFixture.addFileToProject("AbstractJUnit3Test.java", """
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public abstract class AbstractJUnit3Test extends TestCase {
|
||||
@Override
|
||||
public void setUp() {
|
||||
System.out.println("setup 2");
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
void tearDown() {
|
||||
try {
|
||||
System.out.println("tearDown 2");
|
||||
} finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
myFixture.configureByText("JUnit3Test.java", """
|
||||
import junit.framework.TestCase;
|
||||
|
||||
class JUnit3<caret>Test extends AbstractJUnit3Test {
|
||||
@Override
|
||||
public void setUp() {
|
||||
System.out.println("setup 1");
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testAddition() {
|
||||
assertEquals(2, 1 + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
void tearDown() {
|
||||
try {
|
||||
System.out.println("tearDown 1");
|
||||
} finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
try {
|
||||
myFixture.runQuickFix("Convert to JUnit 4 test case")
|
||||
fail("Expected ConflictsInTestsException exception te be thrown.")
|
||||
} catch(e: BaseRefactoringProcessor.ConflictsInTestsException) {
|
||||
assertEquals(e.messages.size, 2)
|
||||
assertContainsElements(
|
||||
e.messages,
|
||||
"Method setUp will have a name collision with its super method",
|
||||
"Method tearDown will have a name collision with its super method"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test quickfix semantic change`() {
|
||||
myFixture.testQuickFixException<BaseRefactoringProcessor.ConflictsInTestsException>(ULanguage.JAVA, """
|
||||
import junit.framework.TestCase;
|
||||
|
||||
class JUnit3<caret>Test extends TestCase {
|
||||
public void testAddition() {
|
||||
System.out.println(toString());
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case") { e ->
|
||||
assertEquals(e.messages.size, 1)
|
||||
assertContainsElements(
|
||||
e.messages,
|
||||
"Method call toString() may change semantics when class JUnit3Test is converted to JUnit 4"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test quickfix removed method`() {
|
||||
myFixture.testQuickFixException<BaseRefactoringProcessor.ConflictsInTestsException>(ULanguage.JAVA, """
|
||||
import junit.framework.TestCase;
|
||||
|
||||
class JUnit3<caret>Test extends TestCase {
|
||||
public void testAddition() {
|
||||
System.out.println(countTestCases());
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case") { e ->
|
||||
assertEquals(e.messages.size, 1)
|
||||
assertContainsElements(
|
||||
e.messages,
|
||||
"Method call countTestCases() will not compile when class JUnit3Test is converted to JUnit 4"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test quickfix non convertable suite`() {
|
||||
myFixture.testQuickFixException<BaseRefactoringProcessor.ConflictsInTestsException>(ULanguage.JAVA, """
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.Test;
|
||||
|
||||
class JUnit3<caret>Test extends TestCase {
|
||||
public static Test suite() {
|
||||
System.out.println("Creating test suite");
|
||||
TestSuite suite = new TestSuite();
|
||||
suite.addTestSuite(Foo.class);
|
||||
suite.addTestSuite(Bar.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case") { e ->
|
||||
assertEquals(e.messages.size, 1)
|
||||
assertContainsElements(
|
||||
e.messages,
|
||||
"Migration of suite method for class JUnit3Test has side effects which will be deleted"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test quickfix class expression suite converter`() {
|
||||
myFixture.testQuickFix(ULanguage.JAVA, """
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import junit.framework.Test;
|
||||
|
||||
class Foo extends TestCase { }
|
||||
class Bar extends TestCase { }
|
||||
|
||||
class JUnit3<caret>Test extends TestCase {
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite();
|
||||
suite.addTestSuite(Foo.class);
|
||||
suite.addTestSuite(Bar.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
""".trimIndent(), """
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import junit.framework.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
class Foo extends TestCase { }
|
||||
class Bar extends TestCase { }
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({Foo.class, Bar.class})
|
||||
class JUnit3Test {
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case")
|
||||
}
|
||||
|
||||
fun `test quickfix nested suite converter`() {
|
||||
myFixture.testQuickFix(ULanguage.JAVA, """
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import junit.framework.Test;
|
||||
|
||||
class Foo extends TestCase {
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite();
|
||||
suite.addTestSuite(Bar.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends TestCase { }
|
||||
|
||||
class JUnit3<caret>Test extends TestCase {
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite();
|
||||
suite.addTest(Foo.suite());
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
""".trimIndent(), """
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import junit.framework.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
class Foo extends TestCase {
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite();
|
||||
suite.addTestSuite(Bar.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends TestCase { }
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({Foo.class})
|
||||
class JUnit3Test {
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case")
|
||||
}
|
||||
|
||||
fun `test quickfix assertion converter`() {
|
||||
myFixture.testQuickFix(ULanguage.JAVA, """
|
||||
import junit.framework.TestCase;
|
||||
|
||||
class JUnit3<caret>Test extends TestCase {
|
||||
public void testAddition() {
|
||||
assertEquals(2, 1 + 1);
|
||||
}
|
||||
}
|
||||
""".trimIndent(), """
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
class JUnit3Test {
|
||||
@Test
|
||||
public void testAddition() {
|
||||
Assert.assertEquals(2, 1 + 1);
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case")
|
||||
}
|
||||
|
||||
fun `test quickfix setup and teardown converter`() {
|
||||
myFixture.testQuickFix(ULanguage.JAVA, """
|
||||
import junit.framework.TestCase;
|
||||
|
||||
class JUnit3<caret>Test extends TestCase {
|
||||
@Override
|
||||
public void setUp() {
|
||||
System.out.println("setup");
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testAddition() {
|
||||
assertEquals(2, 1 + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
void tearDown() {
|
||||
try {
|
||||
System.out.println("tearDown");
|
||||
} finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent(), """
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
class JUnit3Test {
|
||||
@Before
|
||||
public void setUp() {
|
||||
System.out.println("setup");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddition() {
|
||||
Assert.assertEquals(2, 1 + 1);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
System.out.println("tearDown");
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case")
|
||||
}
|
||||
}
|
||||
+319
@@ -0,0 +1,319 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection.tests.kotlin.test.junit
|
||||
|
||||
import com.intellij.codeInspection.tests.ULanguage
|
||||
import com.intellij.codeInspection.tests.test.junit.JUnit4ConverterInspectionTestBase
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ContentEntry
|
||||
import com.intellij.openapi.roots.ModifiableRootModel
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import com.intellij.util.PathUtil
|
||||
import java.io.File
|
||||
|
||||
class KotlinJUnit4ConverterInspectionTest : JUnit4ConverterInspectionTestBase() {
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = object : JUnitProjectDescriptor(sdkLevel) {
|
||||
override fun configureModule(module: Module, model: ModifiableRootModel, contentEntry: ContentEntry) {
|
||||
super.configureModule(module, model, contentEntry)
|
||||
val jar = File(PathUtil.getJarPathForClass(JvmStatic::class.java))
|
||||
PsiTestUtil.addLibrary(model, "kotlin-stdlib", jar.parent, jar.name)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test highlighting`() {
|
||||
myFixture.testHighlighting(ULanguage.KOTLIN, """
|
||||
import junit.framework.TestCase
|
||||
|
||||
class <warning descr="'JUnit3Test' could be converted to JUnit4 test case">JUnit3Test</warning> : TestCase() {
|
||||
fun testAddition() {
|
||||
assertEquals(2, 1 + 1)
|
||||
}
|
||||
}""".trimIndent())
|
||||
}
|
||||
|
||||
fun `test quickfix lifecycle method name conflict`() {
|
||||
myFixture.addFileToProject("AbstractJUnit3Test.kt", """
|
||||
import junit.framework.TestCase
|
||||
|
||||
public abstract class AbstractJUnit3Test : TestCase() {
|
||||
override fun setUp() {
|
||||
println("setup 2")
|
||||
super.setUp()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
try {
|
||||
println("tearDown 2")
|
||||
} finally {
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
myFixture.configureByText("JUnit3Test.kt", """
|
||||
import junit.framework.TestCase
|
||||
|
||||
class JUnit3<caret>Test : AbstractJUnit3Test() {
|
||||
override fun setUp() {
|
||||
println("setup 1")
|
||||
super.setUp()
|
||||
}
|
||||
|
||||
fun testAddition() {
|
||||
assertEquals(2, 1 + 1)
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
try {
|
||||
println("tearDown 1")
|
||||
} finally {
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
try {
|
||||
myFixture.runQuickFix("Convert to JUnit 4 test case")
|
||||
fail("Expected ConflictsInTestsException exception te be thrown.")
|
||||
} catch(e: BaseRefactoringProcessor.ConflictsInTestsException) {
|
||||
assertEquals(e.messages.size, 2)
|
||||
assertContainsElements(
|
||||
e.messages,
|
||||
"Method setUp will have a name collision with its super method",
|
||||
"Method tearDown will have a name collision with its super method"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test quickfix semantic change`() {
|
||||
myFixture.testQuickFixException<BaseRefactoringProcessor.ConflictsInTestsException>(ULanguage.KOTLIN, """
|
||||
import junit.framework.TestCase
|
||||
|
||||
class JUnit3<caret>Test : TestCase() {
|
||||
fun testAddition() {
|
||||
println(toString())
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case") { e ->
|
||||
assertEquals(e.messages.size, 1)
|
||||
assertContainsElements(
|
||||
e.messages,
|
||||
"Method call toString() may change semantics when class JUnit3Test is converted to JUnit 4"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test quickfix removed method`() {
|
||||
myFixture.testQuickFixException<BaseRefactoringProcessor.ConflictsInTestsException>(ULanguage.KOTLIN, """
|
||||
import junit.framework.TestCase
|
||||
|
||||
class JUnit3<caret>Test : TestCase() {
|
||||
fun testAddition() {
|
||||
println(countTestCases())
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case") { e ->
|
||||
assertEquals(e.messages.size, 1)
|
||||
assertContainsElements(
|
||||
e.messages,
|
||||
"Method call countTestCases() will not compile when class JUnit3Test is converted to JUnit 4"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test quickfix non convertable suite`() {
|
||||
myFixture.testQuickFixException<BaseRefactoringProcessor.ConflictsInTestsException>(ULanguage.KOTLIN, """
|
||||
import junit.framework.TestCase
|
||||
import junit.framework.Test
|
||||
|
||||
class JUnit3<caret>Test : TestCase() {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun suite(): Test {
|
||||
println("Creating test suite")
|
||||
val suite = TestSuite()
|
||||
suite.addTestSuite(Foo::class.java)
|
||||
suite.addTestSuite(Bar::class.java)
|
||||
return suite
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case") { e ->
|
||||
assertEquals(e.messages.size, 1)
|
||||
assertContainsElements(
|
||||
e.messages,
|
||||
"Migration of suite method for class JUnit3Test has side effects which will be deleted"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test quickfix class expression suite converter`() {
|
||||
myFixture.testQuickFix(ULanguage.KOTLIN, """
|
||||
import junit.framework.TestCase
|
||||
import junit.framework.TestSuite
|
||||
import junit.framework.Test
|
||||
|
||||
class Foo : TestCase() { }
|
||||
class Bar : TestCase() { }
|
||||
|
||||
class JUnit3<caret>Test : TestCase() {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun suite(): Test {
|
||||
val suite = TestSuite()
|
||||
suite.addTestSuite(Foo::class.java)
|
||||
suite.addTestSuite(Bar::class.java)
|
||||
return suite
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent(), """
|
||||
import junit.framework.TestCase
|
||||
import junit.framework.TestSuite
|
||||
import junit.framework.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Suite
|
||||
|
||||
class Foo : TestCase() { }
|
||||
class Bar : TestCase() { }
|
||||
|
||||
@RunWith(Suite::class)
|
||||
@Suite.SuiteClasses(Foo::class, Bar::class)
|
||||
class JUnit3Test {
|
||||
companion object {
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case")
|
||||
}
|
||||
|
||||
fun `test quickfix nested suite converter`() {
|
||||
myFixture.testQuickFix(ULanguage.KOTLIN, """
|
||||
import junit.framework.TestCase
|
||||
import junit.framework.TestSuite
|
||||
import junit.framework.Test
|
||||
|
||||
class Foo : TestCase() {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun suite(): Test {
|
||||
val suite = TestSuite()
|
||||
suite.addTestSuite(Bar::class.java)
|
||||
return suite
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Bar : TestCase() { }
|
||||
|
||||
class JUnit3<caret>Test : TestCase() {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun suite(): Test {
|
||||
val suite = TestSuite()
|
||||
suite.addTest(Foo.suite())
|
||||
return suite
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent(), """
|
||||
import junit.framework.TestCase
|
||||
import junit.framework.TestSuite
|
||||
import junit.framework.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Suite
|
||||
|
||||
class Foo : TestCase() {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun suite(): Test {
|
||||
val suite = TestSuite()
|
||||
suite.addTestSuite(Bar::class.java)
|
||||
return suite
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Bar : TestCase() { }
|
||||
|
||||
@RunWith(Suite::class)
|
||||
@Suite.SuiteClasses(Foo.Companion::class)
|
||||
class JUnit3Test {
|
||||
companion object {
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case")
|
||||
}
|
||||
|
||||
fun `test quickfix assertion converter`() {
|
||||
myFixture.testQuickFix(ULanguage.KOTLIN, """
|
||||
import junit.framework.TestCase
|
||||
|
||||
class JUnit3<caret>Test : TestCase {
|
||||
fun testAddition() {
|
||||
assertEquals(2, 1 + 1)
|
||||
}
|
||||
}
|
||||
""".trimIndent(), """
|
||||
import junit.framework.TestCase
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class JUnit3Test {
|
||||
@Test
|
||||
fun testAddition() {
|
||||
Assert.assertEquals(2, 1 + 1)
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case")
|
||||
}
|
||||
|
||||
fun `test quickfix setup and teardown converter`() {
|
||||
myFixture.testQuickFix(ULanguage.KOTLIN, """
|
||||
import junit.framework.TestCase
|
||||
|
||||
class JUnit3<caret>Test : TestCase {
|
||||
override fun setUp() {
|
||||
println("setup")
|
||||
super.setUp()
|
||||
}
|
||||
|
||||
fun testAddition() {
|
||||
assertEquals(2, 1 + 1)
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
try {
|
||||
println("tearDown")
|
||||
} finally {
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent(), """
|
||||
import junit.framework.TestCase
|
||||
import org.junit.After
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class JUnit3Test {
|
||||
@Before
|
||||
fun setUp() {
|
||||
println("setup")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAddition() {
|
||||
Assert.assertEquals(2, 1 + 1)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
println("tearDown")
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "Convert to JUnit 4 test case")
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection.tests.test.junit
|
||||
|
||||
import com.intellij.codeInspection.test.junit.JUnit4ConverterInspection
|
||||
import com.intellij.codeInspection.tests.UastInspectionTestBase
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ContentEntry
|
||||
import com.intellij.openapi.roots.ModifiableRootModel
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
|
||||
abstract class JUnit4ConverterInspectionTestBase : UastInspectionTestBase() {
|
||||
override val inspection = JUnit4ConverterInspection()
|
||||
|
||||
protected open class JUnitProjectDescriptor(languageLevel: LanguageLevel) : ProjectDescriptor(languageLevel) {
|
||||
override fun configureModule(module: Module, model: ModifiableRootModel, contentEntry: ContentEntry) {
|
||||
super.configureModule(module, model, contentEntry)
|
||||
model.addJUnit3Library()
|
||||
model.addJUnit4Library()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = JUnitProjectDescriptor(sdkLevel)
|
||||
}
|
||||
-3
@@ -1662,9 +1662,6 @@ inspection.simplifiable.compare.java.time.problem.descriptor=Expression with 'ja
|
||||
redundant.string.format.call.quickfix=Remove redundant call to 'String.format()'
|
||||
redundant.string.formatted.call.quickfix=Remove redundant call to 'String.formatted()'
|
||||
junit4.test.method.in.class.extending.junit3.testcase.display.name=JUnit 4 test method in class extending JUnit 3 TestCase
|
||||
convert.junit3.test.case.error.string=<code>#ref</code> could be converted to JUnit4 test case
|
||||
convert.junit3.test.case.family.name=Convert to JUnit 4 test case
|
||||
convert.junit3.test.case.display.name=JUnit 3 test can be JUnit 4
|
||||
junit4.test.method.in.class.extending.junit3.testcase.problem.descriptor=Method <code>#ref()</code> annotated with '@Test' inside class extending JUnit 3 TestCase #loc
|
||||
ignore.test.method.in.class.extending.junit3.testcase.problem.descriptor=JUnit 3 test method <code>#ref()</code> annotated with '@Ignore' won't be ignored #loc
|
||||
ignore.test.method.in.class.extending.junit3.testcase.quickfix=Remove ''@Ignore'' and rename method to ''{0}''
|
||||
|
||||
+4
@@ -13,6 +13,7 @@ public final class JUnitCommonClassNames {
|
||||
public static final String JUNIT_FRAMEWORK_ASSERT = "junit.framework.Assert";
|
||||
public static final String ORG_JUNIT_JUPITER_API_ASSERTIONS = "org.junit.jupiter.api.Assertions";
|
||||
public static final String ORG_JUNIT_JUPITER_API_ASSUMPTIONS = "org.junit.jupiter.api.Assumptions";
|
||||
public static final String JUNIT_FRAMEWORK_TEST = "junit.framework.Test";
|
||||
public static final String JUNIT_FRAMEWORK_TEST_CASE = "junit.framework.TestCase";
|
||||
public static final String JUNIT_FRAMEWORK_TEST_SUITE = "junit.framework.TestSuite";
|
||||
public static final String ORG_JUNIT_TEST = "org.junit.Test";
|
||||
@@ -25,6 +26,9 @@ public final class JUnitCommonClassNames {
|
||||
public static final String ORG_JUNIT_AFTER = "org.junit.After";
|
||||
public static final String ORG_JUNIT_BEFORE_CLASS = "org.junit.BeforeClass";
|
||||
public static final String ORG_JUNIT_AFTER_CLASS = "org.junit.AfterClass";
|
||||
public static final String ORG_JUNIT_RUNNER_RUN_WITH = "org.junit.runner.RunWith";
|
||||
public static final String ORG_JUNIT_RUNNERS_SUITE = "org.junit.runners.Suite";
|
||||
public static final String ORG_JUNIT_RUNNERS_SUITE_SUITE_CLASSES = "org.junit.runners.Suite.SuiteClasses";
|
||||
public static final String ORG_JUNIT_JUPITER_PARAMS_PARAMETERIZED_TEST = "org.junit.jupiter.params.ParameterizedTest";
|
||||
public static final String ORG_JUNIT_JUPITER_PARAMS_PROVIDER_METHOD_SOURCE = "org.junit.jupiter.params.provider.MethodSource";
|
||||
public static final String ORG_JUNIT_JUPITER_CONDITION_PROVIDER_ENABLED_IF = "org.junit.jupiter.api.condition.EnabledIf";
|
||||
|
||||
@@ -1371,10 +1371,6 @@
|
||||
key="junit4.test.method.in.class.extending.junit3.testcase.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.junit.issues" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.siyeh.ig.junit.JUnit4AnnotatedMethodInJUnit3TestCaseInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="Junit4Converter" bundle="messages.InspectionGadgetsBundle"
|
||||
key="convert.junit3.test.case.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.junit.issues" enabledByDefault="true" level="INFORMATION"
|
||||
implementationClass="com.siyeh.ig.junit.Junit4ConverterInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="MisorderedAssertEqualsArguments"
|
||||
bundle="messages.InspectionGadgetsBundle" key="misordered.assert.equals.arguments.display.name"
|
||||
groupBundle="messages.InspectionsBundle" groupKey="group.names.test.frameworks.issues" enabledByDefault="false" level="WARNING"
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
// Copyright 2000-2020 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.siyeh.ig.junit;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Junit4ConverterInspection extends BaseInspection {
|
||||
|
||||
@Override
|
||||
public boolean shouldInspect(@NotNull PsiFile file) {
|
||||
if (PsiUtil.isLanguageLevel5OrHigher(file)) return true;
|
||||
return super.shouldInspect(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull String buildErrorString(Object... infos) {
|
||||
return InspectionGadgetsBundle.message("convert.junit3.test.case.error.string");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor() {
|
||||
return new BaseInspectionVisitor() {
|
||||
@Override
|
||||
public void visitClass(@NotNull PsiClass aClass) {
|
||||
super.visitClass(aClass);
|
||||
if (possibleToConvert(aClass)) {
|
||||
registerClassError(aClass);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean possibleToConvert(PsiClass aClass) {
|
||||
final PsiReferenceList extendsList = aClass.getExtendsList();
|
||||
if (extendsList == null) return false;
|
||||
|
||||
final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements();
|
||||
if (referenceElements.length != 1) return false;
|
||||
|
||||
final PsiJavaCodeReferenceElement referenceElement = referenceElements[0];
|
||||
final PsiElement target = referenceElement.resolve();
|
||||
if (!(target instanceof PsiClass)) return false;
|
||||
|
||||
final PsiClass targetClass = (PsiClass)target;
|
||||
final String name = targetClass.getQualifiedName();
|
||||
if (!"junit.framework.TestCase".equals(name)) return false;
|
||||
|
||||
final Project project = aClass.getProject();
|
||||
final GlobalSearchScope scope = aClass.getResolveScope();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
final PsiClass testAnnotation = psiFacade.findClass("org.junit.Test", scope);
|
||||
return testAnnotation != null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable InspectionGadgetsFix buildFix(Object... infos) {
|
||||
return new InspectionGadgetsFix() {
|
||||
@Override
|
||||
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiClass pClass = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiClass.class);
|
||||
JUnit4AnnotatedMethodInJUnit3TestCaseInspection.convertJUnit3ClassToJUnit4(pClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return InspectionGadgetsBundle.message("convert.junit3.test.case.family.name");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
// Copyright 2000-2020 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.siyeh.ig.junit;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightJavaInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Junit4ConverterInspectionTest extends LightJavaInspectionTestCase {
|
||||
|
||||
@Override
|
||||
protected String[] getEnvironmentClasses() {
|
||||
return new String[]{
|
||||
"package junit.framework;" +
|
||||
"public abstract class TestCase extends Assert {\n" +
|
||||
"}",
|
||||
|
||||
"""
|
||||
package junit.framework;public class Assert { static public void assertEquals(int expected, int actual) {
|
||||
}
|
||||
}""",
|
||||
|
||||
"package org.junit;" +
|
||||
"public class Assert {" +
|
||||
"static public void assertEquals(long expected, long actual) {" +
|
||||
"}\n" +
|
||||
"}",
|
||||
|
||||
"""
|
||||
package org.junit;@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface Test {}"""
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("JUnitTestCaseWithNoTests")
|
||||
public void testSimple() {
|
||||
doTest("""
|
||||
import junit.framework.TestCase;
|
||||
class /*'JUnit3Test' could be converted to JUnit4 test case*//*_*/JUnit3Test/**/ extends TestCase {
|
||||
public void testAddition() {
|
||||
assertEquals(2, 1 + 1);
|
||||
}
|
||||
}""");
|
||||
checkQuickFix("Convert to JUnit 4 test case", """
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
class JUnit3Test {
|
||||
@Test
|
||||
public void testAddition() {
|
||||
Assert.assertEquals(2, 1 + 1);
|
||||
}
|
||||
}""");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable InspectionProfileEntry getInspection() {
|
||||
return new Junit4ConverterInspection();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user