Compare commits

..
16 changed files with 369 additions and 122 deletions
+8 -4
View File
@@ -1,4 +1,4 @@
# Cajon - Concise AssertJ Optimizing Nitpicker [![Build Status](https://travis-ci.org/chrisly42/cajon-plugin.svg?branch=master)](https://travis-ci.org/chrisly42/cajon-plugin) [![Coverage Status](https://coveralls.io/repos/github/chrisly42/cajon-plugin/badge.svg?branch=master)](https://coveralls.io/github/chrisly42/cajon-plugin?branch=master)
# Cajon - Concise AssertJ Optimizing Nitpicker [![Build Status](https://travis-ci.com/chrisly42/cajon-plugin.svg?branch=master)](https://travis-ci.com/chrisly42/cajon-plugin) [![Coverage Status](https://coveralls.io/repos/github/chrisly42/cajon-plugin/badge.svg?branch=master)](https://coveralls.io/github/chrisly42/cajon-plugin?branch=master)
Cajon is an IntelliJ IDEA Plugin for shortening and optimizing [AssertJ](https://assertj.github.io/doc/) assertions.
@@ -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
+16 -16
View File
@@ -1,13 +1,13 @@
plugins {
id 'java'
id 'org.jetbrains.intellij' version '0.7.2'
id 'org.jetbrains.kotlin.jvm' version '1.5.0'
id 'org.jetbrains.intellij' version '1.1.3'
id 'org.jetbrains.kotlin.jvm' version '1.5.21'
id 'jacoco'
id 'com.github.kt3k.coveralls' version '2.11.0'
}
group 'de.platon42'
version '1.12'
version '1.12.1'
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
@@ -22,11 +22,12 @@ repositories {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testImplementation "org.assertj:assertj-core:3.19.0"
testImplementation "org.assertj:assertj-core:3.20.2"
testImplementation "org.assertj:assertj-guava:3.4.0"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.0-M1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.0-M1'
testImplementation "org.jetbrains.kotlin:kotlin-test"
testImplementation "org.jetbrains.kotlin:kotlin-reflect"
// testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
}
@@ -39,21 +40,20 @@ compileTestKotlin {
}
intellij {
version '2021.1.1' // LATEST-EAP-SNAPSHOT
// pluginName 'Concise AssertJ Optimizing Nitpicker (Cajon)'
updateSinceUntilBuild false
plugins = ['java']
setVersion("2021.1.3") // LATEST-EAP-SNAPSHOT
//pluginName.set(provider { 'Concise AssertJ Optimizing Nitpicker (Cajon)' })
setUpdateSinceUntilBuild(false)
setPlugins(["com.intellij.java"])
}
patchPluginXml {
changeNotes """
<h4>V1.12 (06-May-21)</h4>
setChangeNotes("""
<h4>V1.13 (unreleased)</h4>
<ul>
<li>Maintenance. Updated various dependencies (Kotlin 1.50.0) and AssertJ 3.19.0
<li>Fixed issue#3 reported by hankem where usingRecursiveComparison() was not considered a complex transformation.
<li>Added support for converting JUnit 5 tests to AssertJ
</ul>
<p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p>
"""
""")
}
test {
@@ -69,11 +69,11 @@ jacoco {
jacocoTestReport {
reports {
xml.enabled true
csv.enabled false
xml.required.set(true)
csv.required.set(false)
}
}
publishPlugin {
token intellijPublishToken
setToken(intellijPublishToken)
}
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
Vendored
+2 -2
View File
@@ -72,7 +72,7 @@ case "`uname`" in
Darwin* )
darwin=true
;;
MINGW* )
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
@@ -130,7 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
Vendored
+3 -18
View File
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,21 +64,6 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
@@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
@@ -8,10 +8,16 @@ abstract class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTo
companion object {
@NonNls
const val JUNIT_ASSERT_CLASSNAME = "org.junit.Assert"
const val JUNIT4_ASSERT_CLASSNAME = "org.junit.Assert"
@NonNls
const val JUNIT_ASSUME_CLASSNAME = "org.junit.Assume"
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"
@@ -3,6 +3,8 @@ package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.intellij.psi.CommonClassNames.*
import com.intellij.psi.PsiKeyword.*
import com.intellij.psi.search.GlobalSearchScope
import com.siyeh.ig.callMatcher.CallMatcher
import com.siyeh.ig.callMatcher.CallMatcher.anyOf
@@ -20,94 +22,127 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
private const val CONVERT_MESSAGE_TEMPLATE = "%s can be converted to AssertJ style"
private const val CONVERT_DESCRIPTION_TEMPLATE = "Convert %s() to %s().%s()"
private const val DOUBLE_ARR = "$DOUBLE[]"
private const val FLOAT_ARR = "$FLOAT[]"
private val ASSERT_MAPPINGS = listOf(
Mapping(
anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes("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(JUNIT5_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN),
),
MethodNames.IS_TRUE, hasExpected = false
),
Mapping(
anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes("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(JUNIT5_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN),
),
MethodNames.IS_FALSE, hasExpected = false
),
Mapping(
anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.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(JUNIT5_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT),
),
MethodNames.IS_NULL, hasExpected = false
),
Mapping(
anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.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(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT),
),
MethodNames.IS_NOT_NULL, hasExpected = false
),
Mapping(
anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("double", "double", "double"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("float", "float", "float")
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(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2)
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(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("double", "double", "double"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("float", "float", "float")
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(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2)
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(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2)
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(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2)
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(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double[]", "double[]", "double"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("double[]", "double[]", "double"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float[]", "float[]", "float"),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("float[]", "float[]", "float")
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(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3)
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
)
@@ -116,26 +151,35 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
private val ASSUME_MAPPINGS = listOf(
Mapping(
anyOf(
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes("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(JUNIT5_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN),
),
MethodNames.IS_TRUE, hasExpected = false
),
Mapping(
anyOf(
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes("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(JUNIT5_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN),
),
MethodNames.IS_FALSE, hasExpected = false
),
Mapping(
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_NOT_NULL_METHOD).parameterCount(1),
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(JUNIT_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_THROWABLE),
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(CommonClassNames.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(JUNIT5_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE),
),
"doesNotThrowAnyException", hasExpected = false
)
@@ -149,33 +193,41 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
when (expression.resolveMethod()?.containingClass?.qualifiedName) {
JUNIT_ASSERT_CLASSNAME -> {
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, ::ReplaceJUnitDeltaAssertMethodCallQuickFix)
} else {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method ->
ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected)
}
}
}
JUNIT_ASSUME_CLASSNAME -> {
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)
}
}
}
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, 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, junit5)
}
} else {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method ->
ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected, junit5)
}
}
}
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, junit5)
}
}
}
private fun registerConvertMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
@@ -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<PsiExpression>() to message
val hasMessage = if (noExpectedExpression) count == 1 else count == 2;
val actualExpression: PsiExpression
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 {
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)
@@ -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)
@@ -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)
@@ -70,7 +70,7 @@ class ExtractorReferenceContributor : PsiReferenceContributor() {
class ExtractorReference(literal: PsiLiteralExpression, range: TextRange, private val targets: List<PsiElement>) :
PsiPolyVariantReferenceBase<PsiLiteralExpression>(literal, range, true) {
// Do not remove due to compatiblity issue with IDEA <= 2018.2
// Do not remove due to compatibility issue with IDEA <= 2018.2
override fun getVariants(): Array<Any> {
return ArrayUtil.EMPTY_OBJECT_ARRAY
}
@@ -16,7 +16,10 @@ import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.*;
import com.intellij.testFramework.EdtTestUtilKt;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.TestLoggerFactory;
import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy;
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
@@ -140,14 +143,13 @@ public class LightCodeInsightExtension implements ParameterResolver, AfterTestEx
@Override
public void tearDown() throws Exception {
super.tearDown();
Store store = getStore(extensionContext);
Disposable disposable = (Disposable) store.get("disposable");
UsefulTestCase.clearFields(this);
if (myFixture != null && disposable != null) {
Disposer.dispose(disposable);
store.remove("disposable");
}
super.tearDown();
}
@NotNull
@@ -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")
}
}
@@ -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();
}
}
@@ -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!");
}
}