New AssertThatInstanceOf inspection that moves instanceof expressions out of assertThat(). Fixes to documentation.
This commit is contained in:
@@ -45,6 +45,10 @@ class MethodNames {
|
||||
const val IS_CLOSE_TO = "isCloseTo"
|
||||
@NonNls
|
||||
const val IS_NOT_CLOSE_TO = "isNotCloseTo"
|
||||
@NonNls
|
||||
const val IS_INSTANCE_OF = "isInstanceOf"
|
||||
@NonNls
|
||||
const val IS_NOT_INSTANCE_OF = "isNotInstanceOf"
|
||||
|
||||
@NonNls
|
||||
const val IS_EMPTY = "isEmpty"
|
||||
|
||||
+2
-4
@@ -5,8 +5,6 @@ import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import de.platon42.intellij.plugins.cajon.MethodNames
|
||||
import de.platon42.intellij.plugins.cajon.MethodNames.Companion.IS_NOT_NULL
|
||||
import de.platon42.intellij.plugins.cajon.MethodNames.Companion.IS_NULL
|
||||
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
|
||||
import de.platon42.intellij.plugins.cajon.firstArg
|
||||
import de.platon42.intellij.plugins.cajon.map
|
||||
@@ -36,7 +34,7 @@ class AssertThatBinaryExpressionInspection : AbstractAssertJInspection() {
|
||||
|
||||
val assertThatArgument = expression.firstArg
|
||||
if (assertThatArgument is PsiMethodCallExpression && OBJECT_EQUALS.test(assertThatArgument)) {
|
||||
val replacementMethod = if (expectedResult) MethodNames.IS_EQUAL_TO else MethodNames.IS_NOT_EQUAL_TO
|
||||
val replacementMethod = expectedResult.map(MethodNames.IS_EQUAL_TO, MethodNames.IS_NOT_EQUAL_TO)
|
||||
registerSplitMethod(holder, expression, "${MethodNames.EQUALS}()", replacementMethod, ::MoveActualOuterExpressionMethodCallQuickFix)
|
||||
return
|
||||
}
|
||||
@@ -51,7 +49,7 @@ class AssertThatBinaryExpressionInspection : AbstractAssertJInspection() {
|
||||
if (isLeftNull && isRightNull) {
|
||||
return
|
||||
} else if (isLeftNull || isRightNull) {
|
||||
val replacementMethod = if (expectedResult) IS_NULL else IS_NOT_NULL
|
||||
val replacementMethod = expectedResult.map(MethodNames.IS_NULL, MethodNames.IS_NOT_NULL)
|
||||
registerSplitMethod(holder, expression, "binary", replacementMethod) { desc, method ->
|
||||
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = isLeftNull, noExpectedExpression = true)
|
||||
}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package de.platon42.intellij.plugins.cajon.inspections
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.JavaElementVisitor
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiInstanceOfExpression
|
||||
import com.intellij.psi.PsiMethodCallExpression
|
||||
import de.platon42.intellij.plugins.cajon.MethodNames
|
||||
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
|
||||
import de.platon42.intellij.plugins.cajon.firstArg
|
||||
import de.platon42.intellij.plugins.cajon.map
|
||||
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveInstanceOfExpressionQuickFix
|
||||
|
||||
class AssertThatInstanceOfInspection : AbstractAssertJInspection() {
|
||||
|
||||
companion object {
|
||||
private const val DISPLAY_NAME = "Asserting a class instance"
|
||||
private const val REPLACE_INSTANCEOF_DESCRIPTION_TEMPLATE = "Replace instanceof expression by assertThat().%s()"
|
||||
private const val MOVE_OUT_INSTANCEOF_MESSAGE = "instanceof expression could be moved out of assertThat()"
|
||||
}
|
||||
|
||||
override fun getDisplayName() = DISPLAY_NAME
|
||||
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
||||
return object : JavaElementVisitor() {
|
||||
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
|
||||
super.visitMethodCallExpression(expression)
|
||||
if (!ASSERT_THAT_BOOLEAN.test(expression)) {
|
||||
return
|
||||
}
|
||||
|
||||
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
|
||||
val expectedResult = getExpectedBooleanResult(expectedCallExpression) ?: return
|
||||
|
||||
if (expression.firstArg is PsiInstanceOfExpression) {
|
||||
val replacementMethod = expectedResult.map(MethodNames.IS_INSTANCE_OF, MethodNames.IS_NOT_INSTANCE_OF)
|
||||
registerRemoveInstanceOfMethod(holder, expression, replacementMethod, ::RemoveInstanceOfExpressionQuickFix)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerRemoveInstanceOfMethod(
|
||||
holder: ProblemsHolder,
|
||||
expression: PsiMethodCallExpression,
|
||||
replacementMethod: String,
|
||||
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||
) {
|
||||
val description = REPLACE_INSTANCEOF_DESCRIPTION_TEMPLATE.format(replacementMethod)
|
||||
val quickfix = quickFixSupplier(description, replacementMethod)
|
||||
holder.registerProblem(expression, MOVE_OUT_INSTANCEOF_MESSAGE, quickfix)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -6,6 +6,7 @@ import com.intellij.psi.*
|
||||
import de.platon42.intellij.plugins.cajon.MethodNames
|
||||
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
|
||||
import de.platon42.intellij.plugins.cajon.firstArg
|
||||
import de.platon42.intellij.plugins.cajon.map
|
||||
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveUnaryExpressionQuickFix
|
||||
|
||||
class AssertThatInvertedBooleanConditionInspection : AbstractAssertJInspection() {
|
||||
@@ -31,7 +32,7 @@ class AssertThatInvertedBooleanConditionInspection : AbstractAssertJInspection()
|
||||
|
||||
val prefixExpression = expression.firstArg as? PsiPrefixExpression ?: return
|
||||
if (prefixExpression.operationTokenType == JavaTokenType.EXCL) {
|
||||
val replacementMethod = if (expectedResult) MethodNames.IS_FALSE else MethodNames.IS_TRUE
|
||||
val replacementMethod = expectedResult.map(MethodNames.IS_FALSE, MethodNames.IS_TRUE)
|
||||
registerInvertMethod(holder, expression, replacementMethod, ::RemoveUnaryExpressionQuickFix)
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package de.platon42.intellij.plugins.cajon.quickfixes
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiInstanceOfExpression
|
||||
import com.intellij.psi.PsiMethodCallExpression
|
||||
import com.intellij.psi.PsiParenthesizedExpression
|
||||
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
|
||||
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
|
||||
import de.platon42.intellij.plugins.cajon.firstArg
|
||||
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
|
||||
|
||||
class RemoveInstanceOfExpressionQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.startElement
|
||||
val methodCallExpression = element as? PsiMethodCallExpression ?: return
|
||||
val assertExpression = methodCallExpression.firstArg as? PsiInstanceOfExpression ?: return
|
||||
val expectedClass = assertExpression.checkType ?: return
|
||||
val factory = JavaPsiFacade.getElementFactory(project)
|
||||
val classObjectAccess = factory.createExpressionFromText("${expectedClass.type.canonicalText}.class", null)
|
||||
|
||||
var operand = assertExpression.operand
|
||||
while (operand is PsiParenthesizedExpression) {
|
||||
operand = operand.expression ?: return
|
||||
}
|
||||
|
||||
assertExpression.replace(operand)
|
||||
|
||||
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
|
||||
val expectedExpression = createExpectedMethodCall(element, replacementMethod, classObjectAccess)
|
||||
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
|
||||
oldExpectedExpression.replace(expectedExpression)
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,9 @@
|
||||
|
||||
<description><![CDATA[
|
||||
Cajon is an IntelliJ IDEA Plugin for shortening and optimizing AssertJ assertions.
|
||||
It adds inspections and quick fixes to fully make use of the AssertJ methods
|
||||
to make the intention clear and concise. It can also convert JUnit 4 assertions to AssertJ.
|
||||
It adds several inspections and quick fixes to fully use the fluent assertion methods
|
||||
and thus makes the intention clear and concise, also generating better messages on test failures.
|
||||
It can also be used to convert JUnit 4 assertions to AssertJ.
|
||||
It supports referencing inside extracting()-methods with strings, adding refactoring safety.
|
||||
]]></description>
|
||||
|
||||
@@ -23,8 +24,12 @@
|
||||
<psi.referenceContributor implementation="de.platon42.intellij.plugins.cajon.references.ExtractorReferenceContributor"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatObjectIsNullOrNotNull" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatObjectIsNullOrNotNullInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatBooleanIsTrueOrFalse" enabledByDefault="true" level="WARNING"
|
||||
<localInspection groupPath="Java" shortName="AssertThatBooleanCondition" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatBooleanConditionInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatInvertedBooleanCondition" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatInvertedBooleanConditionInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatInstanceOf" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatInstanceOfInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatStringIsEmpty" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatStringIsEmptyInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatEnumerableIsEmpty" enabledByDefault="true" level="WARNING"
|
||||
@@ -33,17 +38,15 @@
|
||||
<localInspection groupPath="Java" shortName="AssertThatSize" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatSizeInspection"/>
|
||||
|
||||
<localInspection groupPath="Java" shortName="AssertThatBinaryExpressionIsTrueOrFalse" enabledByDefault="true" level="WARNING"
|
||||
<localInspection groupPath="Java" shortName="AssertThatBinaryExpression" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatBinaryExpressionInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatNotPrefixExpression" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatInvertedBooleanConditionInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatStringExpression" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatStringExpressionInspection"/>
|
||||
|
||||
<localInspection groupPath="Java" shortName="AssertThatJava8Optional" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatJava8OptionalInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatGuavaOptional" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatGuavaOptionalInspection"/>
|
||||
<localInspection groupPath="Java" shortName="AssertThatStringExpression" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatStringExpressionInspection"/>
|
||||
|
||||
<localInspection groupPath="Java" shortName="JUnitAssertToAssertJ" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.JUnitAssertToAssertJInspection"/>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
Turns assertThat(object instanceof classname).isEqualTo(true/false) into assertThat(object).is(Not)InstanceOf(classname.class).
|
||||
<!-- tooltip end -->
|
||||
Also works with constant expressions and Boolean.TRUE/FALSE.
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user