diff --git a/README.md b/README.md index 688e3d9..9f0cfbe 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Then AssertJ would tell you the _actual contents_ of the collection on failure. ## Conversion of JUnit assertions to AssertJ -The plugin also supports the conversion of the most common JUnit 4 assertions to AssertJ. +The plugin also supports the conversion of the most common JUnit 4 and JUnit 5 assertions to AssertJ. ## Wrong use of AssertJ @@ -694,7 +694,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the However, this suggests that the test has actually been run and passed instead of showing the test as being skipped. - Return statements in ```if``` statements in main test methods (must be annotated with JUnit 4 or + Return statements in ```if``` statements in main test methods (must be annotated with JUnit 4 or JUnit 5 or Jupiter ```@Test``` annotations) will be verified to have at least one ```assertThat()``` statement in the code flow. Method calls within the same class will be examined for ```assertThat()``` statements, too. However, at most 50 statements and down to five recursions will be tolerated before giving up. @@ -731,7 +731,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the - JUnitAssertToAssertJ - Tries to convert most of the JUnit 4 assertions and assumptions to AssertJ format. + Tries to convert most of the JUnit 4 and JUnit 5 assertions and assumptions to AssertJ format. Sometimes the expected and actual expressions are specified in wrong order -- Cajon tries to swap these when it detects the supposed actual expression to be a constant while the expected one is not. @@ -817,6 +817,10 @@ Feel free to use the code (in package ```de.platon42.intellij.jupiter```) for yo ## Changelog +#### V1.13 (unreleased) + +- Added support for converting JUnit 5 tests to AssertJ + ### V1.12 (06-May-21) - Maintenance. Updated various dependencies (Kotlin 1.50.0) and AssertJ 3.19.0 diff --git a/build.gradle b/build.gradle index 15d3dee..353db0b 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { } group 'de.platon42' -version '1.12' +version '1.12.1' sourceCompatibility = "1.8" targetCompatibility = "1.8" @@ -48,10 +48,9 @@ intellij { patchPluginXml { setChangeNotes(""" -

V1.12 (06-May-21)

+

V1.13 (unreleased)

Full changelog available at Github project site.

""") diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractJUnitAssertInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractJUnitAssertInspection.kt index dfe8a42..b93899f 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractJUnitAssertInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractJUnitAssertInspection.kt @@ -10,9 +10,15 @@ abstract class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTo @NonNls const val JUNIT4_ASSERT_CLASSNAME = "org.junit.Assert" + @NonNls + const val JUNIT5_ASSERT_CLASSNAME = "org.junit.jupiter.api.Assertions" + @NonNls const val JUNIT4_ASSUME_CLASSNAME = "org.junit.Assume" + @NonNls + const val JUNIT5_ASSUME_CLASSNAME = "org.junit.jupiter.api.Assumptions" + @NonNls const val ASSERT_TRUE_METHOD = "assertTrue" diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt index 5f8bfe3..a7121a5 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt @@ -29,90 +29,120 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN), ), MethodNames.IS_TRUE, hasExpected = false ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN), ), MethodNames.IS_FALSE, hasExpected = false ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_OBJECT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT), ), MethodNames.IS_NULL, hasExpected = false ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_OBJECT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT), ), MethodNames.IS_NOT_NULL, hasExpected = false ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE, DOUBLE, DOUBLE), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, FLOAT, FLOAT, FLOAT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT), ), MethodNames.IS_CLOSE_TO, hasDelta = true ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2), ), MethodNames.IS_EQUAL_TO ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE, DOUBLE, DOUBLE), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, FLOAT, FLOAT, FLOAT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT), ), MethodNames.IS_NOT_CLOSE_TO, hasDelta = true ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2), ), MethodNames.IS_NOT_EQUAL_TO ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2), ), MethodNames.IS_SAME_AS ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2), ), MethodNames.IS_NOT_SAME_AS ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE_ARR, DOUBLE_ARR, DOUBLE), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(DOUBLE_ARR, DOUBLE_ARR, DOUBLE, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(DOUBLE_ARR, DOUBLE_ARR, DOUBLE), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(DOUBLE_ARR, DOUBLE_ARR, DOUBLE), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, FLOAT_ARR, FLOAT_ARR, FLOAT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(FLOAT_ARR, FLOAT_ARR, FLOAT, JAVA_LANG_STRING), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(FLOAT_ARR, FLOAT_ARR, FLOAT), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(FLOAT_ARR, FLOAT_ARR, FLOAT), ), MethodNames.CONTAINS_EXACTLY, hasDelta = true ), Mapping( anyOf( staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3), + staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3), ), MethodNames.CONTAINS_EXACTLY ) @@ -122,27 +152,34 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { Mapping( anyOf( staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN), + staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN, JAVA_LANG_STRING), staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN), + staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN), ), MethodNames.IS_TRUE, hasExpected = false ), Mapping( anyOf( staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN), + staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN, JAVA_LANG_STRING), staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN), + staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN), ), MethodNames.IS_FALSE, hasExpected = false ), Mapping( anyOf( staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_NOT_NULL_METHOD).parameterCount(1), + staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_NOT_NULL_METHOD).parameterCount(1), ), MethodNames.IS_NOT_NULL, hasExpected = false, singleArgument = true ), Mapping( anyOf( staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_THROWABLE), + staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE, JAVA_LANG_STRING), staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE), + staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE), ), "doesNotThrowAnyException", hasExpected = false ) @@ -156,35 +193,37 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { super.visitMethodCallExpression(expression) when (expression.resolveMethod()?.containingClass?.qualifiedName) { - JUNIT4_ASSERT_CLASSNAME -> visitMethodCallExpressionAssert(holder, expression) - JUNIT4_ASSUME_CLASSNAME -> visitMethodCallExpressionAssume(holder, expression) + JUNIT4_ASSERT_CLASSNAME -> visitMethodCallExpressionAssert(holder, expression, false) + JUNIT5_ASSERT_CLASSNAME -> visitMethodCallExpressionAssert(holder, expression, true) + JUNIT4_ASSUME_CLASSNAME -> visitMethodCallExpressionAssume(holder, expression, false) + JUNIT5_ASSUME_CLASSNAME -> visitMethodCallExpressionAssume(holder, expression, true) } } } } - private fun visitMethodCallExpressionAssert(holder: ProblemsHolder, expression: PsiMethodCallExpression) { + private fun visitMethodCallExpressionAssert(holder: ProblemsHolder, expression: PsiMethodCallExpression, junit5: Boolean) { JavaPsiFacade.getInstance(expression.project) .findClass(AssertJClassNames.ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return val mapping = ASSERT_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return if (mapping.hasDelta) { registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method -> - ReplaceJUnitDeltaAssertMethodCallQuickFix(desc, method) + ReplaceJUnitDeltaAssertMethodCallQuickFix(desc, method, junit5) } } else { registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method -> - ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected) + ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected, junit5) } } } - private fun visitMethodCallExpressionAssume(holder: ProblemsHolder, expression: PsiMethodCallExpression) { + private fun visitMethodCallExpressionAssume(holder: ProblemsHolder, expression: PsiMethodCallExpression, junit5: Boolean) { JavaPsiFacade.getInstance(expression.project) .findClass(AssertJClassNames.ASSUMPTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return val mapping = ASSUME_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return if (!mapping.singleArgument || expression.argumentList.expressions.size == 1) { registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSUME_THAT) { desc, method -> - ReplaceJUnitAssumeMethodCallQuickFix(desc, method) + ReplaceJUnitAssumeMethodCallQuickFix(desc, method, junit5) } } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssertMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssertMethodCallQuickFix.kt index d9b99b8..17be884 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssertMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssertMethodCallQuickFix.kt @@ -7,7 +7,7 @@ import com.intellij.psi.PsiMethodCallExpression import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME -class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val noExpectedExpression: Boolean) : +class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val noExpectedExpression: Boolean, private val junit5: Boolean) : AbstractCommonQuickFix(description) { companion object { @@ -23,14 +23,20 @@ class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val repl val methodCallExpression = element as? PsiMethodCallExpression ?: return val args = methodCallExpression.argumentList val count = args.expressions.size - val actualExpression = args.expressions[count - 1] ?: return - val (expectedExpressions, messageExpression) = if (noExpectedExpression) { - val message = args.expressions.getOrNull(count - 2) - emptyArray() to message + val hasMessage = if (noExpectedExpression) count == 1 else count == 2; + + val actualExpression: PsiExpression + val expectedExpressions: Array + val messageExpression: PsiExpression? + + if (junit5) { + actualExpression = args.expressions[if (noExpectedExpression) 0 else 1] ?: return + messageExpression = if (hasMessage) null else args.expressions[count - 1] + expectedExpressions = if (noExpectedExpression) emptyArray() else arrayOf(args.expressions[0]) } else { - val expected = args.expressions[count - 2] ?: return - val message = args.expressions.getOrNull(count - 3) - arrayOf(expected) to message + actualExpression = args.expressions[count - 1] ?: return + messageExpression = if (hasMessage) null else args.expressions[0] + expectedExpressions = if (noExpectedExpression) emptyArray() else arrayOf(args.expressions[count - 2]) } val swapActualAndExpected = ((expectedExpressions.getOrNull(0)?.calculateConstantValue() == null) diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssumeMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssumeMethodCallQuickFix.kt index 4da023c..5023fa2 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssumeMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssumeMethodCallQuickFix.kt @@ -5,7 +5,7 @@ import com.intellij.openapi.project.Project import com.intellij.psi.PsiMethodCallExpression import de.platon42.intellij.plugins.cajon.* -class ReplaceJUnitAssumeMethodCallQuickFix(description: String, private val replacementMethod: String) : +class ReplaceJUnitAssumeMethodCallQuickFix(description: String, private val replacementMethod: String, private val junit5: Boolean) : AbstractCommonQuickFix(description) { companion object { @@ -21,8 +21,8 @@ class ReplaceJUnitAssumeMethodCallQuickFix(description: String, private val repl val methodCallExpression = element as? PsiMethodCallExpression ?: return val args = methodCallExpression.argumentList val count = args.expressions.size - val actualExpression = args.expressions[count - 1] ?: return - val messageExpression = args.expressions.getOrNull(count - 2) + val actualExpression = args.expressions[if (junit5) 0 else count - 1] ?: return + val messageExpression = args.expressions.getOrNull(if (junit5) 1 else count - 2) val expectedMethodCall = createExpectedMethodCall(element, replacementMethod) val newMethodCall = createAssumeThat(element, actualExpression) diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitDeltaAssertMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitDeltaAssertMethodCallQuickFix.kt index af65319..c8043e7 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitDeltaAssertMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitDeltaAssertMethodCallQuickFix.kt @@ -6,7 +6,7 @@ import com.intellij.psi.PsiMethodCallExpression import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME -class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) { +class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val junit5: Boolean) : AbstractCommonQuickFix(description) { companion object { private const val CONVERT_DESCRIPTION = "Convert JUnit assertions with delta to assertJ" @@ -21,10 +21,10 @@ class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val val methodCallExpression = element as? PsiMethodCallExpression ?: return val args = methodCallExpression.argumentList val count = args.expressions.size - val messageExpression = args.expressions.getOrNull(count - 4) - val expectedExpression = args.expressions[count - 3] ?: return - val actualExpression = args.expressions[count - 2] ?: return - val deltaExpression = args.expressions[count - 1] ?: return + val messageExpression = args.expressions.getOrNull(if (junit5) 3 else count - 4) + val expectedExpression = args.expressions[if (junit5) 0 else count - 3] ?: return + val actualExpression = args.expressions[if (junit5) 1 else count - 2] ?: return + val deltaExpression = args.expressions[if (junit5) 2 else count - 1] ?: return val offsetMethodCall = createMethodCall(element, "org.assertj.core.data.Offset.offset", deltaExpression) diff --git a/src/test/java/de/platon42/intellij/plugins/cajon/inspections/JUnit5AssertToAssertJInspectionTest.kt b/src/test/java/de/platon42/intellij/plugins/cajon/inspections/JUnit5AssertToAssertJInspectionTest.kt new file mode 100644 index 0000000..f3a7abc --- /dev/null +++ b/src/test/java/de/platon42/intellij/plugins/cajon/inspections/JUnit5AssertToAssertJInspectionTest.kt @@ -0,0 +1,23 @@ +package de.platon42.intellij.plugins.cajon.inspections + +import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture +import de.platon42.intellij.jupiter.AddLocalJarToModule +import de.platon42.intellij.jupiter.MyFixture +import de.platon42.intellij.jupiter.TestDataSubPath +import de.platon42.intellij.plugins.cajon.AbstractCajonTest +import org.assertj.core.api.Assertions +import org.junit.jupiter.api.Test + +@AddLocalJarToModule(org.junit.jupiter.api.Assertions::class, Assertions::class) +internal class JUnit5AssertToAssertJInspectionTest : AbstractCajonTest() { + + @Test + @TestDataSubPath("inspections/JUnit5AssertToAssertJ") + internal fun junit5_Assertions_can_be_converted_into_AssertJ(@MyFixture myFixture: JavaCodeInsightTestFixture) { + myFixture.enableInspections(JUnitAssertToAssertJInspection::class.java) + myFixture.configureByFile("JUnit5AssertToAssertJInspectionBefore.java") + executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Convert assert.*\\(\\) to assertThat\\(\\).*"), 48) + executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Convert assume.*\\(\\) to assumeThat\\(\\).*"), 4) + myFixture.checkResultByFile("JUnit5AssertToAssertJInspectionAfter.java") + } +} \ No newline at end of file diff --git a/src/test/resources/inspections/JUnit5AssertToAssertJ/JUnit5AssertToAssertJInspectionAfter.java b/src/test/resources/inspections/JUnit5AssertToAssertJ/JUnit5AssertToAssertJInspectionAfter.java new file mode 100644 index 0000000..6797bd4 --- /dev/null +++ b/src/test/resources/inspections/JUnit5AssertToAssertJ/JUnit5AssertToAssertJInspectionAfter.java @@ -0,0 +1,86 @@ +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assumptions.assumeThat; +import static org.assertj.core.data.Offset.offset; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +public class JUnit5AssertToAssertJ { + + private void jUnit5AssertToAssertJ() { + String foo = "foo"; + String bar = "bar"; + int someInt = 1; + double someDouble = 1.0; + float someFloat = 1.0f; + + assertThat(foo == "foo").isTrue(); + assertThat(foo == "foo").as("oh no!").isTrue(); + assertThat(foo == "bar").isFalse(); + assertThat(foo == "bar").as("boom!").isFalse(); + + assertThat(foo).isNull(); + assertThat(foo).as("oh no!").isNull(); + assertThat(foo).isNotNull(); + assertThat(foo).as("oh no!").isNotNull(); + + assertThat(foo).isEqualTo(bar); + assertThat(foo).as("equals").isEqualTo(bar); + assertThat(foo).isNotEqualTo(bar); + assertThat(foo).as("equals").isNotEqualTo(bar); + + assertThat(foo).isSameAs(bar); + assertThat(foo).as("same").isSameAs(bar); + assertThat(foo).isNotSameAs(bar); + assertThat(foo).as("same").isNotSameAs(bar); + + assertThat(2.0).isEqualTo(1.0); + assertThat(2.0).isCloseTo(1.0, offset(0.1)); + assertThat(2.0).as("equals").isEqualTo(1.0); + assertThat(2.0).as("equals").isCloseTo(1.0, offset(0.1)); + assertThat(2.0f).isEqualTo(1.0f); + assertThat(2.0f).isCloseTo(1.0f, offset(0.1f)); + assertThat(2.0f).as("equals").isEqualTo(1.0f); + assertThat(2.0f).as("equals").isCloseTo(1.0f, offset(0.1f)); + + assertThat(2.0).isNotEqualTo(1.0); + assertThat(2.0).isNotCloseTo(1.0, offset(0.1)); + assertThat(2.0).as("equals").isNotEqualTo(1.0); + assertThat(2.0).as("equals").isNotCloseTo(1.0, offset(0.1)); + assertThat(2.0f).isNotEqualTo(1.0f); + assertThat(2.0f).isNotCloseTo(1.0f, offset(0.1f)); + assertThat(2.0f).as("equals").isNotEqualTo(1.0f); + assertThat(2.0f).as("equals").isNotCloseTo(1.0f, offset(0.1f)); + + assertThat(new int[1]).containsExactly(new int[2]); + assertThat(new int[1]).as("array equals").containsExactly(new int[2]); + + assertThat(new double[1]).containsExactly(new double[2], offset(1.0)); + assertThat(new double[1]).as("array equals").containsExactly(new double[2], offset(1.0)); + assertThat(new float[1]).containsExactly(new float[2], offset(1.0f)); + assertThat(new float[1]).as("array equals").containsExactly(new float[2], offset(1.0f)); + + assertThat(foo).isEqualTo("bar"); + assertThat(bar).as("equals").isEqualTo("foo"); + assertThat(bar).isNotEqualTo("foo"); + assertThat(foo).as("equals").isNotEqualTo("bar"); + + assertThat(someInt).isEqualTo(2); + assertThat(someDouble).isCloseTo(2.0, offset(0.1)); + assertThat(someDouble).as("equals").isEqualTo(1.0); + assertThat(someDouble).as("equals").isCloseTo(1.0, offset(0.1)); + assertThat(someFloat).isEqualTo(1.0f); + assertThat(someFloat).isCloseTo(2.0f, offset(0.1f)); + + fail(); + fail("oh no!") + } + + private void jUnit5AssumeToAssertJ() { + String foo = "foo"; + String bar = "bar"; + assumeThat(foo == "foo").isTrue(); + assumeThat(foo == "foo").as("oh no!").isTrue(); + assumeThat(foo == "bar").isFalse(); + assumeThat(foo == "bar").as("boom!").isFalse(); + } +} diff --git a/src/test/resources/inspections/JUnit5AssertToAssertJ/JUnit5AssertToAssertJInspectionBefore.java b/src/test/resources/inspections/JUnit5AssertToAssertJ/JUnit5AssertToAssertJInspectionBefore.java new file mode 100644 index 0000000..a766561 --- /dev/null +++ b/src/test/resources/inspections/JUnit5AssertToAssertJ/JUnit5AssertToAssertJInspectionBefore.java @@ -0,0 +1,83 @@ +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +public class JUnit5AssertToAssertJ { + + private void jUnit5AssertToAssertJ() { + String foo = "foo"; + String bar = "bar"; + int someInt = 1; + double someDouble = 1.0; + float someFloat = 1.0f; + + assertTrue(foo == "foo"); + assertTrue(foo == "foo", "oh no!"); + assertFalse(foo == "bar"); + assertFalse(foo == "bar", "boom!"); + + assertNull(foo); + assertNull(foo, "oh no!"); + assertNotNull(foo); + assertNotNull(foo, "oh no!"); + + assertEquals(bar, foo); + assertEquals(bar, foo, "equals"); + assertNotEquals(bar, foo); + assertNotEquals(bar, foo, "equals"); + + assertSame(bar, foo); + assertSame(bar, foo, "same"); + assertNotSame(bar, foo); + assertNotSame(bar, foo, "same"); + + assertEquals(1.0, 2.0); + assertEquals(1.0, 2.0, 0.1); + assertEquals(1.0, 2.0, "equals"); + assertEquals(1.0, 2.0, 0.1, "equals"); + assertEquals(1.0f, 2.0f); + assertEquals(1.0f, 2.0f, 0.1f); + assertEquals(1.0f, 2.0f, "equals"); + assertEquals(1.0f, 2.0f, 0.1f, "equals"); + + assertNotEquals(1.0, 2.0); + assertNotEquals(1.0, 2.0, 0.1); + assertNotEquals(1.0, 2.0, "equals"); + assertNotEquals(1.0, 2.0, 0.1, "equals"); + assertNotEquals(1.0f, 2.0f); + assertNotEquals(1.0f, 2.0f, 0.1f); + assertNotEquals(1.0f, 2.0f, "equals"); + assertNotEquals(1.0f, 2.0f, 0.1f, "equals"); + + assertArrayEquals(new int[2], new int[1]); + assertArrayEquals(new int[2], new int[1], "array equals"); + + assertArrayEquals(new double[2], new double[1], 1.0); + assertArrayEquals(new double[2], new double[1], 1.0, "array equals"); + assertArrayEquals(new float[2], new float[1], 1.0f); + assertArrayEquals(new float[2], new float[1], 1.0f, "array equals"); + + assertEquals("bar", foo); + assertEquals(bar, "foo", "equals"); + assertNotEquals(bar, "foo"); + assertNotEquals("bar", foo, "equals"); + + assertEquals(someInt, 2); + assertEquals(someDouble, 2.0, 0.1); + assertEquals(1.0, someDouble, "equals"); + assertEquals(1.0, someDouble, 0.1, "equals"); + assertEquals(1.0f, someFloat); + assertEquals(someFloat, 2.0f, 0.1f); + + fail(); + fail("oh no!") + } + + private void jUnit5AssumeToAssertJ() { + String foo = "foo"; + String bar = "bar"; + assumeTrue(foo == "foo"); + assumeTrue(foo == "foo", "oh no!"); + assumeFalse(foo == "bar"); + assumeFalse(foo == "bar", "boom!"); + } +}