Add support for converting JUnit 5 tests to AssertJ

This commit is contained in:
Niels Ulrik Andersen 2022-02-23 18:03:46 +01:00
parent f8b86ac78f
commit 49a3b1aada
10 changed files with 276 additions and 30 deletions

View File

@ -32,7 +32,7 @@ Then AssertJ would tell you the _actual contents_ of the collection on failure.
## Conversion of JUnit assertions to AssertJ ## 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 ## 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 However, this suggests that the test has actually been run and passed instead of showing the test
as being skipped. 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. 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. 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. 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 - 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 -- 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 Cajon tries to swap these when it detects the supposed actual expression to be a
constant while the expected one is not. 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 ## Changelog
#### V1.13 (unreleased)
- Added support for converting JUnit 5 tests to AssertJ
### V1.12 (06-May-21) ### V1.12 (06-May-21)
- Maintenance. Updated various dependencies (Kotlin 1.50.0) and AssertJ 3.19.0 - Maintenance. Updated various dependencies (Kotlin 1.50.0) and AssertJ 3.19.0

View File

@ -7,7 +7,7 @@ plugins {
} }
group 'de.platon42' group 'de.platon42'
version '1.12' version '1.12.1'
sourceCompatibility = "1.8" sourceCompatibility = "1.8"
targetCompatibility = "1.8" targetCompatibility = "1.8"
@ -48,10 +48,9 @@ intellij {
patchPluginXml { patchPluginXml {
setChangeNotes(""" setChangeNotes("""
<h4>V1.12 (06-May-21)</h4> <h4>V1.13 (unreleased)</h4>
<ul> <ul>
<li>Maintenance. Updated various dependencies (Kotlin 1.50.0) and AssertJ 3.19.0 <li>Added support for converting JUnit 5 tests to AssertJ
<li>Fixed issue#3 reported by hankem where usingRecursiveComparison() was not considered a complex transformation.
</ul> </ul>
<p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p> <p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p>
""") """)

View File

@ -10,9 +10,15 @@ abstract class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTo
@NonNls @NonNls
const val JUNIT4_ASSERT_CLASSNAME = "org.junit.Assert" const val JUNIT4_ASSERT_CLASSNAME = "org.junit.Assert"
@NonNls
const val JUNIT5_ASSERT_CLASSNAME = "org.junit.jupiter.api.Assertions"
@NonNls @NonNls
const val JUNIT4_ASSUME_CLASSNAME = "org.junit.Assume" const val JUNIT4_ASSUME_CLASSNAME = "org.junit.Assume"
@NonNls
const val JUNIT5_ASSUME_CLASSNAME = "org.junit.jupiter.api.Assumptions"
@NonNls @NonNls
const val ASSERT_TRUE_METHOD = "assertTrue" const val ASSERT_TRUE_METHOD = "assertTrue"

View File

@ -29,90 +29,120 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN), 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(JUNIT4_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN),
), ),
MethodNames.IS_TRUE, hasExpected = false MethodNames.IS_TRUE, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN), 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(JUNIT4_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN),
), ),
MethodNames.IS_FALSE, hasExpected = false MethodNames.IS_FALSE, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_OBJECT), 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(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 MethodNames.IS_NULL, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_OBJECT), 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(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 MethodNames.IS_NOT_NULL, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE, DOUBLE, DOUBLE), 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(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(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(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 MethodNames.IS_CLOSE_TO, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3), 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(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2),
), ),
MethodNames.IS_EQUAL_TO MethodNames.IS_EQUAL_TO
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE, DOUBLE, DOUBLE), 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(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(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(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 MethodNames.IS_NOT_CLOSE_TO, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3), 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(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2),
), ),
MethodNames.IS_NOT_EQUAL_TO MethodNames.IS_NOT_EQUAL_TO
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3), 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(JUNIT4_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2),
), ),
MethodNames.IS_SAME_AS MethodNames.IS_SAME_AS
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3), 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(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2),
), ),
MethodNames.IS_NOT_SAME_AS MethodNames.IS_NOT_SAME_AS
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE_ARR, DOUBLE_ARR, DOUBLE), 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(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(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(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 MethodNames.CONTAINS_EXACTLY, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2), 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(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3),
), ),
MethodNames.CONTAINS_EXACTLY MethodNames.CONTAINS_EXACTLY
) )
@ -122,27 +152,34 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN), 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(JUNIT4_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN),
staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN),
), ),
MethodNames.IS_TRUE, hasExpected = false MethodNames.IS_TRUE, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN), 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(JUNIT4_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN),
staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN),
), ),
MethodNames.IS_FALSE, hasExpected = false MethodNames.IS_FALSE, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_NOT_NULL_METHOD).parameterCount(1), 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 MethodNames.IS_NOT_NULL, hasExpected = false, singleArgument = true
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_THROWABLE), 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(JUNIT4_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE),
staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE),
), ),
"doesNotThrowAnyException", hasExpected = false "doesNotThrowAnyException", hasExpected = false
) )
@ -156,35 +193,37 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
when (expression.resolveMethod()?.containingClass?.qualifiedName) { when (expression.resolveMethod()?.containingClass?.qualifiedName) {
JUNIT4_ASSERT_CLASSNAME -> visitMethodCallExpressionAssert(holder, expression) JUNIT4_ASSERT_CLASSNAME -> visitMethodCallExpressionAssert(holder, expression, false)
JUNIT4_ASSUME_CLASSNAME -> visitMethodCallExpressionAssume(holder, expression) 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) JavaPsiFacade.getInstance(expression.project)
.findClass(AssertJClassNames.ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return .findClass(AssertJClassNames.ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
val mapping = ASSERT_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return val mapping = ASSERT_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return
if (mapping.hasDelta) { if (mapping.hasDelta) {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method -> registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method ->
ReplaceJUnitDeltaAssertMethodCallQuickFix(desc, method) ReplaceJUnitDeltaAssertMethodCallQuickFix(desc, method, junit5)
} }
} else { } else {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method -> 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) JavaPsiFacade.getInstance(expression.project)
.findClass(AssertJClassNames.ASSUMPTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return .findClass(AssertJClassNames.ASSUMPTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
val mapping = ASSUME_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return val mapping = ASSUME_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return
if (!mapping.singleArgument || expression.argumentList.expressions.size == 1) { if (!mapping.singleArgument || expression.argumentList.expressions.size == 1) {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSUME_THAT) { desc, method -> registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSUME_THAT) { desc, method ->
ReplaceJUnitAssumeMethodCallQuickFix(desc, method) ReplaceJUnitAssumeMethodCallQuickFix(desc, method, junit5)
} }
} }
} }

View File

@ -7,7 +7,7 @@ import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME 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) { AbstractCommonQuickFix(description) {
companion object { companion object {
@ -23,14 +23,20 @@ class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val repl
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList val args = methodCallExpression.argumentList
val count = args.expressions.size val count = args.expressions.size
val actualExpression = args.expressions[count - 1] ?: return val hasMessage = if (noExpectedExpression) count == 1 else count == 2;
val (expectedExpressions, messageExpression) = if (noExpectedExpression) {
val message = args.expressions.getOrNull(count - 2) val actualExpression: PsiExpression
emptyArray<PsiExpression>() to message val expectedExpressions: Array<PsiExpression>
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 { } else {
val expected = args.expressions[count - 2] ?: return actualExpression = args.expressions[count - 1] ?: return
val message = args.expressions.getOrNull(count - 3) messageExpression = if (hasMessage) null else args.expressions[0]
arrayOf(expected) to message expectedExpressions = if (noExpectedExpression) emptyArray() else arrayOf(args.expressions[count - 2])
} }
val swapActualAndExpected = ((expectedExpressions.getOrNull(0)?.calculateConstantValue() == null) val swapActualAndExpected = ((expectedExpressions.getOrNull(0)?.calculateConstantValue() == null)

View File

@ -5,7 +5,7 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.* 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) { AbstractCommonQuickFix(description) {
companion object { companion object {
@ -21,8 +21,8 @@ class ReplaceJUnitAssumeMethodCallQuickFix(description: String, private val repl
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList val args = methodCallExpression.argumentList
val count = args.expressions.size val count = args.expressions.size
val actualExpression = args.expressions[count - 1] ?: return val actualExpression = args.expressions[if (junit5) 0 else count - 1] ?: return
val messageExpression = args.expressions.getOrNull(count - 2) val messageExpression = args.expressions.getOrNull(if (junit5) 1 else count - 2)
val expectedMethodCall = createExpectedMethodCall(element, replacementMethod) val expectedMethodCall = createExpectedMethodCall(element, replacementMethod)
val newMethodCall = createAssumeThat(element, actualExpression) val newMethodCall = createAssumeThat(element, actualExpression)

View File

@ -6,7 +6,7 @@ import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME 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 { companion object {
private const val CONVERT_DESCRIPTION = "Convert JUnit assertions with delta to assertJ" 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 methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList val args = methodCallExpression.argumentList
val count = args.expressions.size val count = args.expressions.size
val messageExpression = args.expressions.getOrNull(count - 4) val messageExpression = args.expressions.getOrNull(if (junit5) 3 else count - 4)
val expectedExpression = args.expressions[count - 3] ?: return val expectedExpression = args.expressions[if (junit5) 0 else count - 3] ?: return
val actualExpression = args.expressions[count - 2] ?: return val actualExpression = args.expressions[if (junit5) 1 else count - 2] ?: return
val deltaExpression = args.expressions[count - 1] ?: return val deltaExpression = args.expressions[if (junit5) 2 else count - 1] ?: return
val offsetMethodCall = createMethodCall(element, "org.assertj.core.data.Offset.offset", deltaExpression) val offsetMethodCall = createMethodCall(element, "org.assertj.core.data.Offset.offset", deltaExpression)

View File

@ -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")
}
}

View File

@ -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();
}
}

View File

@ -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!");
}
}