Fix for incompatible method call regarding IDEA <2018.2.

Heavy refactoring regarding quick fixes (using more extensions).
Even more refactoring.
Fixed/extended AssertThatGuavaOptionalInspection regarding static.
imports and wrong reference to core assertThat() where Guava assertThat() actually was necessary.
This commit is contained in:
Chris Hodges 2019-04-13 18:35:49 +02:00
parent 4e6d53b3dc
commit b58d8cfd2f
27 changed files with 425 additions and 290 deletions

View File

@ -228,6 +228,10 @@ Feel free to use the code (in package de.platon42.intellij.jupiter) for your pro
## Changelog ## Changelog
#### V0.5 (13-Apr-19)
- Fixed incompatibility with IDEA versions < 2018.2 (affected AssertThatSizeInspection).
- Fixed missing Guava imports (if not already present) for AssertThatGuavaInspection. This was a major PITA to get right.
#### V0.4 (11-Apr-19) #### V0.4 (11-Apr-19)
- Reduced minimal supported IDEA version from 2018.2 to 2017.2. - Reduced minimal supported IDEA version from 2018.2 to 2017.2.
- New inspection AssertThatJava8Optional that operates on Java 8 Optional objects and tries to use contains(), containsSame(), isPresent(), and isNotPresent() instead. - New inspection AssertThatJava8Optional that operates on Java 8 Optional objects and tries to use contains(), containsSame(), isPresent(), and isNotPresent() instead.

View File

@ -5,7 +5,7 @@ plugins {
} }
group 'de.platon42' group 'de.platon42'
version '0.4' version '0.5'
repositories { repositories {
mavenCentral() mavenCentral()
@ -41,6 +41,11 @@ intellij {
patchPluginXml { patchPluginXml {
changeNotes """ changeNotes """
<h4>V0.5 (13-Apr-19)</h4>
<ul>
<li>Fixed incompatibility with IDEA versions < 2018.2 (affected AssertThatSizeInspection).
<li>Fixed missing Guava imports (if not already present) for AssertThatGuavaInspection. This was a major PITA to get right.
</ul>
<h4>V0.4 (11-Apr-19)</h4> <h4>V0.4 (11-Apr-19)</h4>
<ul> <ul>
<li>Reduced minimal supported IDEA version from 2018.2 to 2017.2. <li>Reduced minimal supported IDEA version from 2018.2 to 2017.2.

View File

@ -10,6 +10,8 @@ class AssertJClassNames {
@NonNls @NonNls
const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert" const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert"
@NonNls @NonNls
const val ABSTRACT_OBJECT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractObjectAssert"
@NonNls
const val ABSTRACT_BOOLEAN_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractBooleanAssert" const val ABSTRACT_BOOLEAN_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractBooleanAssert"
@NonNls @NonNls
const val ABSTRACT_INTEGER_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIntegerAssert" const val ABSTRACT_INTEGER_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIntegerAssert"

View File

@ -1,12 +1,14 @@
package de.platon42.intellij.plugins.cajon package de.platon42.intellij.plugins.cajon
import com.intellij.psi.PsiExpression import com.intellij.psi.*
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.util.PsiTreeUtil
val PsiMethodCallExpression.qualifierExpression: PsiExpression get() = this.methodExpression.qualifierExpression!! val PsiMethodCallExpression.qualifierExpression: PsiExpression get() = this.methodExpression.qualifierExpression!!
val PsiMethodCallExpression.firstArg: PsiExpression get() = this.argumentList.expressions[0]!! val PsiMethodCallExpression.firstArg: PsiExpression get() = this.argumentList.expressions[0]!!
fun PsiMethodCallExpression.replaceQualifier(qualifier: PsiExpression) { fun PsiMethodCallExpression.replaceQualifier(qualifier: PsiElement) {
this.qualifierExpression.replace(qualifier) this.qualifierExpression.replace(qualifier)
} }
@ -14,6 +16,32 @@ fun PsiMethodCallExpression.replaceQualifierFromMethodCall(oldMethodCall: PsiMet
this.qualifierExpression.replace(oldMethodCall.qualifierExpression) this.qualifierExpression.replace(oldMethodCall.qualifierExpression)
} }
fun PsiElement.findOutmostMethodCall(): PsiMethodCallExpression? {
val statement = PsiTreeUtil.getParentOfType(this, PsiStatement::class.java) ?: return null
return PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java)
}
fun PsiMethodCallExpression.getArg(n: Int): PsiExpression = this.argumentList.expressions[n] fun PsiMethodCallExpression.getArg(n: Int): PsiExpression = this.argumentList.expressions[n]
fun <T> Boolean.map(forTrue: T, forFalse: T) = if (this) forTrue else forFalse fun <T> Boolean.map(forTrue: T, forFalse: T) = if (this) forTrue else forFalse
fun PsiMethod.addAsStaticImport(context: PsiElement, vararg allowedClashes: String) {
val factory = JavaPsiFacade.getElementFactory(context.project)
val methodName = this.name
val containingClass = this.containingClass ?: return
val importList = (context.containingFile as PsiJavaFile).importList ?: return
val notImportedStatically = importList.importStaticStatements.none {
val targetClass = it.resolveTargetClass() ?: return@none false
((it.referenceName == methodName) && !allowedClashes.contains(targetClass.qualifiedName))
|| (it.isOnDemand && (targetClass == this.containingClass))
}
if (notImportedStatically) {
importList.add(factory.createImportStaticStatement(containingClass, methodName))
}
}
fun PsiElement.shortenAndReformat() {
val codeStyleManager = JavaCodeStyleManager.getInstance(project)
codeStyleManager.shortenClassReferences(this)
CodeStyleManager.getInstance(project).reformat(this)
}

View File

@ -0,0 +1,33 @@
package de.platon42.intellij.plugins.cajon
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethodCallExpression
fun createAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
return createAssertThat(context, AssertJClassNames.ASSERTIONS_CLASSNAME, actualExpression)
}
fun createGuavaAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
return createAssertThat(context, AssertJClassNames.GUAVA_ASSERTIONS_CLASSNAME, actualExpression)
}
fun createAssertThat(context: PsiElement, baseclass: String, actualExpression: PsiExpression): PsiMethodCallExpression {
return createMethodCall(context, "$baseclass.${MethodNames.ASSERT_THAT}", actualExpression)
}
fun createExpectedMethodCall(context: PsiElement, methodName: String, vararg arguments: PsiElement): PsiMethodCallExpression {
return createMethodCall(context, "a.$methodName", *arguments)
}
fun createMethodCall(context: PsiElement, fullQualifiedMethodName: String, vararg arguments: PsiElement): PsiMethodCallExpression {
val factory = JavaPsiFacade.getElementFactory(context.project)
val argString = generateSequence('b') { it + 1 }.take(arguments.size).joinToString(", ")
val expectedExpression = factory.createExpressionFromText(
"$fullQualifiedMethodName($argString)", context
) as PsiMethodCallExpression
arguments.forEachIndexed { index, newArg -> expectedExpression.getArg(index).replace(newArg) }
return expectedExpression
}

View File

@ -1,6 +1,7 @@
package de.platon42.intellij.plugins.cajon.inspections package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
@ -18,8 +19,6 @@ import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_OPTI
import de.platon42.intellij.plugins.cajon.MethodNames import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.getArg import de.platon42.intellij.plugins.cajon.getArg
import de.platon42.intellij.plugins.cajon.qualifierExpression import de.platon42.intellij.plugins.cajon.qualifierExpression
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveActualOutmostMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveExpectedOutmostMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSimpleMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSimpleMethodCallQuickFix
open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
@ -174,30 +173,17 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
holder.registerProblem(expression, message, quickFix) holder.registerProblem(expression, message, quickFix)
} }
protected fun registerRemoveActualOutmostMethod( protected fun registerReplaceMethod(
holder: ProblemsHolder, holder: ProblemsHolder,
expression: PsiMethodCallExpression, expression: PsiMethodCallExpression,
expectedCallExpression: PsiMethodCallExpression, oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String, replacementMethod: String,
noExpectedExpression: Boolean = false quickFixSupplier: (String, String) -> LocalQuickFix
) { ) {
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return val originalMethod = getOriginalMethodName(oldExpectedCallExpression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod) val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod) val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
val quickfix = RemoveActualOutmostMethodCallQuickFix(description, replacementMethod, noExpectedExpression) val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickfix)
}
protected fun registerRemoveExpectedOutmostMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
expectedCallExpression: PsiMethodCallExpression,
replacementMethod: String
) {
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
val quickfix = RemoveExpectedOutmostMethodCallQuickFix(description, replacementMethod)
holder.registerProblem(expression, message, quickfix) holder.registerProblem(expression, message, quickfix)
} }
@ -239,6 +225,6 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
val findClass = val findClass =
JavaPsiFacade.getInstance(element.project).findClass(classname, GlobalSearchScope.allScope(element.project)) JavaPsiFacade.getInstance(element.project).findClass(classname, GlobalSearchScope.allScope(element.project))
?: return false ?: return false
return findClass.findMethodsByName(methodname).isNotEmpty() return findClass.allMethods.any { it.name == methodname }
} }
} }

View File

@ -1,12 +1,13 @@
package de.platon42.intellij.plugins.cajon.inspections package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.TypeConversionUtil import com.intellij.psi.util.TypeConversionUtil
import de.platon42.intellij.plugins.cajon.MethodNames 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_NOT_NULL
import de.platon42.intellij.plugins.cajon.MethodNames.Companion.IS_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.firstArg
import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.SplitBinaryExpressionMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.SplitBinaryExpressionMethodCallQuickFix
@ -30,18 +31,13 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect
return return
} }
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val expectedResult = getExpectedBooleanResult(expectedCallExpression) ?: return val expectedResult = getExpectedBooleanResult(expectedCallExpression) ?: return
val assertThatArgument = expression.firstArg val assertThatArgument = expression.firstArg
if (assertThatArgument is PsiMethodCallExpression && OBJECT_EQUALS.test(assertThatArgument)) { if (assertThatArgument is PsiMethodCallExpression && OBJECT_EQUALS.test(assertThatArgument)) {
val replacementMethod = if (expectedResult) MethodNames.IS_EQUAL_TO else MethodNames.IS_NOT_EQUAL_TO val replacementMethod = if (expectedResult) MethodNames.IS_EQUAL_TO else MethodNames.IS_NOT_EQUAL_TO
val type = "${MethodNames.EQUALS}()" registerSplitMethod(holder, expression, "${MethodNames.EQUALS}()", replacementMethod, ::SplitEqualsExpressionMethodCallQuickFix)
val description = SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE.format(type)
val message = MORE_MEANINGFUL_MESSAGE_TEMPLATE.format(type)
val quickFix = SplitEqualsExpressionMethodCallQuickFix(description, replacementMethod)
holder.registerProblem(expression, message, quickFix)
return return
} }
@ -56,7 +52,9 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect
return return
} else if (isLeftNull || isRightNull) { } else if (isLeftNull || isRightNull) {
val replacementMethod = if (expectedResult) IS_NULL else IS_NOT_NULL val replacementMethod = if (expectedResult) IS_NULL else IS_NOT_NULL
registerSplitBinaryExpressionMethod(holder, expression, replacementMethod, pickRightOperand = isLeftNull, noExpectedExpression = true) registerSplitMethod(holder, expression, "binary", replacementMethod) { desc, method ->
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = isLeftNull, noExpectedExpression = true)
}
return return
} }
@ -76,21 +74,22 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect
(isPrimitive || isNumericType).map(TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP, TOKEN_TO_ASSERTJ_FOR_OBJECT_MAPPINGS) (isPrimitive || isNumericType).map(TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP, TOKEN_TO_ASSERTJ_FOR_OBJECT_MAPPINGS)
val replacementMethod = mappingToUse[tokenType] ?: return val replacementMethod = mappingToUse[tokenType] ?: return
registerSplitBinaryExpressionMethod(holder, expression, replacementMethod, pickRightOperand = swapExpectedAndActual) registerSplitMethod(holder, expression, "binary", replacementMethod) { desc, method ->
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = swapExpectedAndActual)
}
} }
private fun registerSplitBinaryExpressionMethod( private fun registerSplitMethod(
holder: ProblemsHolder, holder: ProblemsHolder,
expression: PsiMethodCallExpression, expression: PsiMethodCallExpression,
type: String,
replacementMethod: String, replacementMethod: String,
pickRightOperand: Boolean = false, quickFixSupplier: (String, String) -> LocalQuickFix
noExpectedExpression: Boolean = false
) { ) {
val type = "binary"
val description = SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE.format(type) val description = SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE.format(type)
val message = MORE_MEANINGFUL_MESSAGE_TEMPLATE.format(type) val message = MORE_MEANINGFUL_MESSAGE_TEMPLATE.format(type)
val quickFix = SplitBinaryExpressionMethodCallQuickFix(description, replacementMethod, pickRightOperand, noExpectedExpression) val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickFix) holder.registerProblem(expression, message, quickfix)
} }
} }
} }

View File

@ -1,13 +1,13 @@
package de.platon42.intellij.plugins.cajon.inspections package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.* import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.AssertJClassNames import de.platon42.intellij.plugins.cajon.quickfixes.*
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() { class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
@ -27,35 +27,87 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
if (!(ASSERT_THAT_ANY.test(expression) || assertThatGuava)) { if (!(ASSERT_THAT_ANY.test(expression) || assertThatGuava)) {
return return
} }
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val isEqualTo = IS_EQUAL_TO_OBJECT.test(expectedCallExpression)
val isNotEqualTo = IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)
if (assertThatGuava) { if (assertThatGuava) {
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) { if (isEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (GUAVA_OPTIONAL_OF.test(innerExpectedCall) || GUAVA_OPTIONAL_FROM_NULLABLE.test(innerExpectedCall)) { if (GUAVA_OPTIONAL_OF.test(innerExpectedCall) || GUAVA_OPTIONAL_FROM_NULLABLE.test(innerExpectedCall)) {
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix)
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) { } else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT) registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
} }
} else if (IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)) { } else if (isNotEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) { if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT) registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT)
} }
} }
} else { } else {
val actualExpression = expression.firstArg as? PsiMethodCallExpression ?: return // we're not calling an assertThat() from Guava, but a core-AssertJ one!
// We need to replace that by the Guava one, if we want to apply a formally correct fix.
if (GUAVA_OPTIONAL_GET.test(actualExpression) && IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) { val actualExpression = expression.firstArg as? PsiMethodCallExpression
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) if (actualExpression != null) {
} else if (GUAVA_OPTIONAL_IS_PRESENT.test(actualExpression)) { if (GUAVA_OPTIONAL_GET.test(actualExpression) && isEqualTo) {
val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return registerRemoveActualOutmostForGuavaMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_ABSENT) } else if (GUAVA_OPTIONAL_IS_PRESENT.test(actualExpression)) {
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true) val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_ABSENT)
registerRemoveActualOutmostForGuavaMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true)
}
}
if (isEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (GUAVA_OPTIONAL_OF.test(innerExpectedCall) || GUAVA_OPTIONAL_FROM_NULLABLE.test(innerExpectedCall)) {
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) { desc, method ->
QuickFixWithPostfixDelegate(
RemoveExpectedOutmostMethodCallQuickFix(desc, method),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
}
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyForGuavaMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
}
} else if (isNotEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyForGuavaMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT)
}
} }
} }
} }
} }
} }
private fun registerRemoveActualOutmostForGuavaMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
noExpectedExpression: Boolean = false
) {
registerReplaceMethod(holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method ->
QuickFixWithPostfixDelegate(
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
}
}
private fun registerSimplifyForGuavaMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
replacementMethod: String
) {
val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = SIMPLIFY_MESSAGE_TEMPLATE.format(originalMethod, replacementMethod)
val quickFix = QuickFixWithPostfixDelegate(
ReplaceSimpleMethodCallQuickFix(description, replacementMethod),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
holder.registerProblem(expression, message, quickFix)
}
} }

View File

@ -4,11 +4,12 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.MethodNames 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.firstArg
import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveActualOutmostMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveExpectedOutmostMethodCallQuickFix
class AssertThatJava8OptionalInspection : AbstractAssertJInspection() { class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
@ -25,14 +26,13 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
if (!ASSERT_THAT_ANY.test(expression)) { if (!ASSERT_THAT_ANY.test(expression)) {
return return
} }
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
if (ASSERT_THAT_JAVA8_OPTIONAL.test(expression)) { if (ASSERT_THAT_JAVA8_OPTIONAL.test(expression)) {
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) { if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (OPTIONAL_OF.test(innerExpectedCall) || OPTIONAL_OF_NULLABLE.test(innerExpectedCall)) { if (OPTIONAL_OF.test(innerExpectedCall) || OPTIONAL_OF_NULLABLE.test(innerExpectedCall)) {
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix)
} else if (OPTIONAL_EMPTY.test(innerExpectedCall)) { } else if (OPTIONAL_EMPTY.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_NOT_PRESENT) registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_NOT_PRESENT)
} }
@ -47,14 +47,20 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
if (OPTIONAL_GET.test(actualExpression)) { if (OPTIONAL_GET.test(actualExpression)) {
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) { if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method)
}
} else if (IS_SAME_AS_OBJECT.test(expectedCallExpression)) { } else if (IS_SAME_AS_OBJECT.test(expectedCallExpression)) {
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS_SAME) registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS_SAME) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method)
}
} }
} else if (OPTIONAL_IS_PRESENT.test(actualExpression)) { } else if (OPTIONAL_IS_PRESENT.test(actualExpression)) {
val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_NOT_PRESENT) val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_NOT_PRESENT)
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true) registerReplaceMethod(holder, expression, expectedCallExpression, replacementMethod) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
} }
} }
} }

View File

@ -2,9 +2,9 @@ package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ITERABLE_ASSERT_CLASSNAME import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ITERABLE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.MethodNames 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.firstArg
import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix
@ -34,18 +34,23 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
val actualExpression = expression.firstArg val actualExpression = expression.firstArg
if (isArrayLength(actualExpression) || isCollectionSize(actualExpression)) { if (isArrayLength(actualExpression) || isCollectionSize(actualExpression)) {
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val constValue = calculateConstantParameterValue(expectedCallExpression, 0) val constValue = calculateConstantParameterValue(expectedCallExpression, 0)
if (IS_EQUAL_TO_INT.test(expectedCallExpression)) { if (IS_EQUAL_TO_INT.test(expectedCallExpression)) {
if (constValue == 0) { if (constValue == 0) {
registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.IS_EMPTY, noExpectedExpression = true) registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.IS_EMPTY) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
} else { } else {
val equalToExpression = expectedCallExpression.firstArg val equalToExpression = expectedCallExpression.firstArg
if (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression)) { if (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression)) {
registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SAME_SIZE_AS, expectedIsCollection = true) registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SAME_SIZE_AS) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, expectedIsCollection = true)
}
} else { } else {
registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SIZE) registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SIZE) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method)
}
} }
} }
} else { } else {
@ -57,11 +62,15 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
|| IS_NOT_ZERO.test(expectedCallExpression)) || IS_NOT_ZERO.test(expectedCallExpression))
if (isTestForEmpty || isTestForNotEmpty) { if (isTestForEmpty || isTestForNotEmpty) {
val replacementMethod = isTestForEmpty.map(MethodNames.IS_EMPTY, MethodNames.IS_NOT_EMPTY) val replacementMethod = isTestForEmpty.map(MethodNames.IS_EMPTY, MethodNames.IS_NOT_EMPTY)
registerReplaceSizeMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true) registerReplaceMethod(holder, expression, expectedCallExpression, replacementMethod) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
} else if (hasAssertJMethod(expression, ABSTRACT_ITERABLE_ASSERT_CLASSNAME, MethodNames.HAS_SIZE_LESS_THAN)) { } else if (hasAssertJMethod(expression, ABSTRACT_ITERABLE_ASSERT_CLASSNAME, MethodNames.HAS_SIZE_LESS_THAN)) {
// new stuff in AssertJ 13.2.0 // new stuff in AssertJ 13.2.0
val matchedMethod = BONUS_EXPRESSIONS_CALL_MATCHER_MAP.find { it.first.test(expectedCallExpression) }?.second ?: return val matchedMethod = BONUS_EXPRESSIONS_CALL_MATCHER_MAP.find { it.first.test(expectedCallExpression) }?.second ?: return
registerReplaceSizeMethod(holder, expression, expectedCallExpression, matchedMethod) registerReplaceMethod(holder, expression, expectedCallExpression, matchedMethod) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method)
}
} }
} }
} }
@ -74,21 +83,6 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
return ((psiReferenceExpression.qualifierExpression?.type is PsiArrayType) return ((psiReferenceExpression.qualifierExpression?.type is PsiArrayType)
&& ((psiReferenceExpression.resolve() as? PsiField)?.name == "length")) && ((psiReferenceExpression.resolve() as? PsiField)?.name == "length"))
} }
private fun registerReplaceSizeMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
expectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
noExpectedExpression: Boolean = false,
expectedIsCollection: Boolean = false
) {
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
val quickfix = ReplaceSizeMethodCallQuickFix(description, replacementMethod, noExpectedExpression, expectedIsCollection)
holder.registerProblem(expression, message, quickfix)
}
} }
} }
} }

View File

@ -1,5 +1,6 @@
package de.platon42.intellij.plugins.cajon.inspections package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
@ -121,43 +122,29 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
} }
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
for (mapping in MAPPINGS) { val mapping = MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return
if (mapping.callMatcher.test(expression)) { if (mapping.hasDelta) {
if (mapping.hasDelta) { registerConvertMethod(holder, expression, mapping.replacement, ::ReplaceJUnitDeltaAssertMethodCallQuickFix)
registerDeltaReplacementMethod(holder, expression, mapping.replacement) } else {
} else { registerConvertMethod(holder, expression, mapping.replacement) { desc, method ->
registerSimpleReplacementMethod(holder, expression, mapping.hasExpected, mapping.replacement) ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected)
}
return
} }
} }
} }
} }
} }
private fun registerSimpleReplacementMethod( private fun registerConvertMethod(
holder: ProblemsHolder, holder: ProblemsHolder,
expression: PsiMethodCallExpression, expression: PsiMethodCallExpression,
hasExpected: Boolean, replacementMethod: String,
replacementMethod: String quickFixSupplier: (String, String) -> LocalQuickFix
) { ) {
val originalMethod = getOriginalMethodName(expression) ?: return val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod) val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = CONVERT_MESSAGE_TEMPLATE.format(originalMethod) val message = CONVERT_MESSAGE_TEMPLATE.format(originalMethod)
val quickFix = ReplaceJUnitAssertMethodCallQuickFix(description, !hasExpected, replacementMethod) val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickFix) holder.registerProblem(expression, message, quickfix)
}
private fun registerDeltaReplacementMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
replacementMethod: String
) {
val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = CONVERT_MESSAGE_TEMPLATE.format(originalMethod)
val quickFix = ReplaceJUnitDeltaAssertMethodCallQuickFix(description, replacementMethod)
holder.registerProblem(expression, message, quickFix)
} }
private class Mapping( private class Mapping(

View File

@ -1,35 +1,9 @@
package de.platon42.intellij.plugins.cajon.quickfixes package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.LocalQuickFix
import com.intellij.psi.*
import de.platon42.intellij.plugins.cajon.AssertJClassNames
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.firstArg
abstract class AbstractCommonQuickFix(private val description: String) : LocalQuickFix { abstract class AbstractCommonQuickFix(private val description: String) : LocalQuickFix {
override fun getFamilyName() = description override fun getFamilyName() = description
protected fun addStaticImport(method: PsiMethod, element: PsiMethodCallExpression, factory: PsiElementFactory, vararg allowedClashes: String) {
val methodName = method.name
val containingClass = method.containingClass ?: return
val importList = (element.containingFile as PsiJavaFile).importList ?: return
val notImportedStatically = importList.importStaticStatements.none {
val targetClass = it.resolveTargetClass() ?: return@none false
((it.referenceName == methodName) && !allowedClashes.contains(targetClass.qualifiedName))
|| (it.isOnDemand && (targetClass == method.containingClass))
}
if (notImportedStatically) {
importList.add(factory.createImportStaticStatement(containingClass, methodName))
}
}
protected fun createAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
val factory = JavaPsiFacade.getElementFactory(context.project)
val newMethodCall = factory.createExpressionFromText(
"${AssertJClassNames.ASSERTIONS_CLASSNAME}.${MethodNames.ASSERT_THAT}(a)", context
) as PsiMethodCallExpression
newMethodCall.firstArg.replace(actualExpression)
return newMethodCall
}
} }

View File

@ -0,0 +1,27 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement
import com.intellij.psi.util.PsiTreeUtil
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.*
class ForGuavaPostFix {
companion object {
private val CORE_MATCHER = CallMatcher.staticCall(AssertJClassNames.ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
val REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT: (Project, ProblemDescriptor) -> Unit = exit@
{ _, descriptor ->
val element = descriptor.startElement
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return@exit
val methodCallExpression = PsiTreeUtil.findChildrenOfType(statement, PsiMethodCallExpression::class.java).find { CORE_MATCHER.test(it) } ?: return@exit
val newMethodCall = createGuavaAssertThat(element, methodCallExpression.firstArg)
newMethodCall.resolveMethod()?.addAsStaticImport(element, AssertJClassNames.ASSERTIONS_CLASSNAME)
val parentCall = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return@exit
parentCall.replaceQualifier(newMethodCall)
parentCall.shortenAndReformat()
}
}
}

View File

@ -0,0 +1,16 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
class QuickFixWithPostfixDelegate(
private val mainFix: LocalQuickFix,
private val postfix: (Project, ProblemDescriptor) -> Unit
) : LocalQuickFix by mainFix {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
mainFix.applyFix(project, descriptor)
postfix(project, descriptor)
}
}

View File

@ -2,19 +2,13 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement import de.platon42.intellij.plugins.cajon.*
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.qualifierExpression
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class RemoveActualOutmostMethodCallQuickFix( class RemoveActualOutmostMethodCallQuickFix(
description: String, description: String,
private val replacementMethod: String, private val replacementMethod: String,
private val noExpectedExpression: Boolean private val noExpectedExpression: Boolean = false
) : AbstractCommonQuickFix(description) { ) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@ -22,16 +16,10 @@ class RemoveActualOutmostMethodCallQuickFix(
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.firstArg as? PsiMethodCallExpression ?: return val assertExpression = methodCallExpression.firstArg as? PsiMethodCallExpression ?: return
assertExpression.replace(assertExpression.qualifierExpression) assertExpression.replace(assertExpression.qualifierExpression)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val factory = JavaPsiFacade.getElementFactory(element.project) val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val expectedExpression = factory.createExpressionFromText( val args = if (noExpectedExpression) emptyArray() else oldExpectedExpression.argumentList.expressions
"a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
) as PsiMethodCallExpression
if (!noExpectedExpression) {
expectedExpression.firstArg.replace(oldExpectedExpression.firstArg)
}
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression) expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression) oldExpectedExpression.replace(expectedExpression)
} }

View File

@ -2,10 +2,9 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import com.intellij.psi.util.PsiTreeUtil import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
@ -13,14 +12,9 @@ class RemoveExpectedOutmostMethodCallQuickFix(description: String, private val r
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement val element = descriptor.startElement
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression =
factory.createExpressionFromText("a.$replacementMethod(e)", element) as PsiMethodCallExpression
val expectedMethodCallExpression = oldExpectedExpression.firstArg as? PsiMethodCallExpression ?: return val expectedMethodCallExpression = oldExpectedExpression.firstArg as? PsiMethodCallExpression ?: return
expectedExpression.firstArg.replace(expectedMethodCallExpression.firstArg) val expectedExpression = createExpectedMethodCall(element, replacementMethod, expectedMethodCallExpression.firstArg)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression) expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression) oldExpectedExpression.replace(expectedExpression)
} }

View File

@ -2,17 +2,12 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.codeStyle.CodeStyleManager import de.platon42.intellij.plugins.cajon.*
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.replaceQualifier
class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val noExpectedExpression: Boolean, private val replacementMethod: String) : class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val noExpectedExpression: Boolean) :
AbstractCommonQuickFix(description) { AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@ -22,39 +17,26 @@ class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val noEx
val count = args.expressions.size val count = args.expressions.size
val actualExpression = args.expressions[count - 1] ?: return val actualExpression = args.expressions[count - 1] ?: return
val (expectedExpression, messageExpression) = if (noExpectedExpression) { val (expectedExpression, messageExpression) = if (noExpectedExpression) {
val message = if (count > 1) args.expressions[0] else null val message = args.expressions.getOrNull(count - 2)
null to message emptyArray<PsiExpression>() to message
} else { } else {
val expected = args.expressions[count - 2] ?: return val expected = args.expressions[count - 2] ?: return
val message = if (count > 2) args.expressions[0] else null val message = args.expressions.getOrNull(count - 3)
expected to message arrayOf(expected) to message
}
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedMethodCall = factory.createExpressionFromText(
"a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element
) as PsiMethodCallExpression
if (!noExpectedExpression) {
expectedMethodCall.firstArg.replace(expectedExpression!!)
} }
val expectedMethodCall = createExpectedMethodCall(element, replacementMethod, *expectedExpression)
val newMethodCall = createAssertThat(element, actualExpression) val newMethodCall = createAssertThat(element, actualExpression)
if (messageExpression != null) { if (messageExpression != null) {
val asExpression = factory.createExpressionFromText("a.${MethodNames.AS}(desc)", element) as PsiMethodCallExpression val asExpression = createExpectedMethodCall(element, MethodNames.AS, messageExpression)
asExpression.firstArg.replace(messageExpression)
asExpression.replaceQualifier(newMethodCall) asExpression.replaceQualifier(newMethodCall)
expectedMethodCall.replaceQualifier(asExpression) expectedMethodCall.replaceQualifier(asExpression)
} else { } else {
expectedMethodCall.replaceQualifier(newMethodCall) expectedMethodCall.replaceQualifier(newMethodCall)
} }
val assertThatMethod = newMethodCall.resolveMethod() ?: return newMethodCall.resolveMethod()?.addAsStaticImport(element, GUAVA_ASSERTIONS_CLASSNAME)
addStaticImport(assertThatMethod, element, factory, GUAVA_ASSERTIONS_CLASSNAME) element.replace(expectedMethodCall).shortenAndReformat()
val codeStyleManager = JavaCodeStyleManager.getInstance(element.project)
val newElement = element.replace(expectedMethodCall)
val shortened = codeStyleManager.shortenClassReferences(newElement)
CodeStyleManager.getInstance(element.project).reformat(shortened)
} }
} }

View File

@ -2,14 +2,9 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.codeStyle.CodeStyleManager import de.platon42.intellij.plugins.cajon.*
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.getArg
import de.platon42.intellij.plugins.cajon.replaceQualifier
class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) { class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
@ -18,44 +13,25 @@ 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 actualExpression = args.expressions[count - 2] ?: return val messageExpression = args.expressions.getOrNull(count - 4)
val messageExpression = if (count > 3) args.expressions[0] else null
val expectedExpression = args.expressions[count - 3] ?: return val expectedExpression = args.expressions[count - 3] ?: return
val actualExpression = args.expressions[count - 2] ?: return
val deltaExpression = args.expressions[count - 1] ?: return val deltaExpression = args.expressions[count - 1] ?: return
val factory = JavaPsiFacade.getElementFactory(element.project) val offsetMethodCall = createMethodCall(element, "org.assertj.core.data.Offset.offset", deltaExpression)
val offsetMethodCall = factory.createExpressionFromText( val expectedMethodCall = createExpectedMethodCall(element, replacementMethod, expectedExpression, offsetMethodCall)
"org.assertj.core.data.Offset.offset(c)", element
) as PsiMethodCallExpression
offsetMethodCall.firstArg.replace(deltaExpression)
val expectedMethodCall = factory.createExpressionFromText(
"a.$replacementMethod(e, offs)", element
) as PsiMethodCallExpression
expectedMethodCall.firstArg.replace(expectedExpression)
expectedMethodCall.getArg(1).replace(offsetMethodCall)
val newMethodCall = createAssertThat(element, actualExpression) val newMethodCall = createAssertThat(element, actualExpression)
if (messageExpression != null) { if (messageExpression != null) {
val asExpression = factory.createExpressionFromText("a.as(desc)", element) as PsiMethodCallExpression val asExpression = createExpectedMethodCall(element, MethodNames.AS, messageExpression)
asExpression.firstArg.replace(messageExpression)
asExpression.replaceQualifier(newMethodCall) asExpression.replaceQualifier(newMethodCall)
expectedMethodCall.replaceQualifier(asExpression) expectedMethodCall.replaceQualifier(asExpression)
} else { } else {
expectedMethodCall.replaceQualifier(newMethodCall) expectedMethodCall.replaceQualifier(newMethodCall)
} }
val assertThatMethod = newMethodCall.resolveMethod() ?: return newMethodCall.resolveMethod()?.addAsStaticImport(element, GUAVA_ASSERTIONS_CLASSNAME)
addStaticImport(assertThatMethod, element, factory, GUAVA_ASSERTIONS_CLASSNAME) offsetMethodCall.resolveMethod()?.addAsStaticImport(element)
val offsetMethod = offsetMethodCall.resolveMethod() ?: return element.replace(expectedMethodCall).shortenAndReformat()
addStaticImport(offsetMethod, element, factory)
val codeStyleManager = JavaCodeStyleManager.getInstance(element.project)
val newElement = element.replace(expectedMethodCall)
val shortened = codeStyleManager.shortenClassReferences(newElement)
CodeStyleManager.getInstance(element.project).reformat(shortened)
} }
} }

View File

@ -2,19 +2,19 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class ReplaceSimpleMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) { class ReplaceSimpleMethodCallQuickFix(
description: String,
private val replacementMethod: String
) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement val element = descriptor.startElement
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val expectedExpression = createExpectedMethodCall(element, replacementMethod)
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression =
factory.createExpressionFromText("a.$replacementMethod()", element) as PsiMethodCallExpression
expectedExpression.replaceQualifierFromMethodCall(methodCallExpression) expectedExpression.replaceQualifierFromMethodCall(methodCallExpression)
element.replace(expectedExpression) element.replace(expectedExpression)
} }

View File

@ -2,18 +2,16 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.* import com.intellij.psi.PsiExpression
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.firstArg import com.intellij.psi.PsiReferenceExpression
import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.qualifierExpression
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class ReplaceSizeMethodCallQuickFix( class ReplaceSizeMethodCallQuickFix(
description: String, description: String,
private val replacementMethod: String, private val replacementMethod: String,
private val noExpectedExpression: Boolean, private val noExpectedExpression: Boolean = false,
private val expectedIsCollection: Boolean private val expectedIsCollection: Boolean = false
) : AbstractCommonQuickFix(description) { ) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@ -21,19 +19,15 @@ class ReplaceSizeMethodCallQuickFix(
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.firstArg val assertExpression = methodCallExpression.firstArg
replaceCollectionSizeOrArrayLength(assertExpression) replaceCollectionSizeOrArrayLength(assertExpression)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val factory = JavaPsiFacade.getElementFactory(element.project) if (expectedIsCollection) {
val expectedExpression = factory.createExpressionFromText( replaceCollectionSizeOrArrayLength(oldExpectedExpression.firstArg)
"a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element
) as PsiMethodCallExpression
if (!noExpectedExpression) {
if (expectedIsCollection) {
replaceCollectionSizeOrArrayLength(oldExpectedExpression.firstArg)
}
expectedExpression.firstArg.replace(oldExpectedExpression.firstArg)
} }
val args = if (noExpectedExpression) emptyArray() else arrayOf(oldExpectedExpression.firstArg)
val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression) expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression) oldExpectedExpression.replace(expectedExpression)
} }

View File

@ -2,20 +2,18 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiBinaryExpression import com.intellij.psi.PsiBinaryExpression
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import com.intellij.psi.util.PsiTreeUtil import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class SplitBinaryExpressionMethodCallQuickFix( class SplitBinaryExpressionMethodCallQuickFix(
description: String, description: String,
private val replacementMethod: String, private val replacementMethod: String,
private val pickRightOperand: Boolean, private val pickRightOperand: Boolean = false,
private val noExpectedExpression: Boolean private val noExpectedExpression: Boolean = false
) : AbstractCommonQuickFix(description) { ) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@ -25,16 +23,9 @@ class SplitBinaryExpressionMethodCallQuickFix(
val expectedArgument = (if (pickRightOperand) binaryExpression.lOperand else binaryExpression.rOperand)?.copy() ?: return val expectedArgument = (if (pickRightOperand) binaryExpression.lOperand else binaryExpression.rOperand)?.copy() ?: return
binaryExpression.replace(if (pickRightOperand) binaryExpression.rOperand!! else binaryExpression.lOperand) binaryExpression.replace(if (pickRightOperand) binaryExpression.rOperand!! else binaryExpression.lOperand)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return val args = if (noExpectedExpression) emptyArray() else arrayOf(expectedArgument)
val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression = factory.createExpressionFromText(
"a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element
) as PsiMethodCallExpression
if (!noExpectedExpression) {
expectedExpression.firstArg.replace(expectedArgument)
}
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression) expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression) oldExpectedExpression.replace(expectedExpression)
} }

View File

@ -2,13 +2,8 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement import de.platon42.intellij.plugins.cajon.*
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.qualifierExpression
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class SplitEqualsExpressionMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) { class SplitEqualsExpressionMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
@ -19,14 +14,8 @@ class SplitEqualsExpressionMethodCallQuickFix(description: String, private val r
val expectedArgument = equalsMethodCall.firstArg.copy() val expectedArgument = equalsMethodCall.firstArg.copy()
equalsMethodCall.replace(equalsMethodCall.qualifierExpression) equalsMethodCall.replace(equalsMethodCall.qualifierExpression)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return val expectedExpression = createExpectedMethodCall(element, replacementMethod, expectedArgument)
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression = factory.createExpressionFromText(
"a.$replacementMethod(e)", element
) as PsiMethodCallExpression
expectedExpression.firstArg.replace(expectedArgument)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression) expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression) oldExpectedExpression.replace(expectedExpression)
} }

View File

@ -18,13 +18,36 @@ internal class AssertThatGuavaOptionalInspectionTest : AbstractCajonTest() {
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java) myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
myFixture.configureByFile("AssertThatGuavaOptionalBefore.java") myFixture.configureByFile("AssertThatGuavaOptionalBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isPresent()"), 2) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isPresent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 3) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 5)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 3) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 5)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isAbsent()"), 2) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isAbsent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isTrue() with isPresent()"), 1) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isTrue() with isPresent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isFalse() with isAbsent()"), 1) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isFalse() with isAbsent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with contains()"), 3) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with contains()"), 7)
myFixture.checkResultByFile("AssertThatGuavaOptionalAfter.java") myFixture.checkResultByFile("AssertThatGuavaOptionalAfter.java")
} }
} }
@Test
@TestDataSubPath("inspections/AssertThatGuavaOptional")
internal fun adds_missing_Guava_import_any_order(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
myFixture.configureByFile("WithoutPriorGuavaImportBefore.java")
executeQuickFixes(myFixture, Regex("Replace .* with .*"), 7)
myFixture.checkResultByFile("WithoutPriorGuavaImportAfter.java")
}
}
@Test
@TestDataSubPath("inspections/AssertThatGuavaOptional")
internal fun adds_missing_Guava_import_isAbsent_first(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
myFixture.configureByFile("WithoutPriorGuavaImportBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 1)
executeQuickFixes(myFixture, Regex("Replace .* with .*"), 6)
myFixture.checkResultByFile("WithoutPriorGuavaImportAfter.java")
}
}
} }

View File

@ -32,5 +32,21 @@ public class AssertThatGuavaOptional {
assertThat(opt).isAbsent(); assertThat(opt).isAbsent();
assertThat(opt).isPresent(); assertThat(opt).isPresent();
org.assertj.guava.api.Assertions.assertThat(opt).contains("foo");
org.assertj.guava.api.Assertions.assertThat(opt).contains("foo");
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.of("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isAbsent();
org.assertj.guava.api.Assertions.assertThat(opt).isPresent();
assertThat(opt).contains("foo");
assertThat(opt).contains("foo");
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.of("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isAbsent();
assertThat(opt).isPresent();
} }
} }

View File

@ -32,5 +32,21 @@ public class AssertThatGuavaOptional {
assertThat(opt).isEqualTo(Optional.absent()); assertThat(opt).isEqualTo(Optional.absent());
assertThat(opt).isNotEqualTo(Optional.absent()); assertThat(opt).isNotEqualTo(Optional.absent());
org.assertj.guava.api.Assertions.assertThat(opt).isEqualTo(Optional.of("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.of("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isEqualTo(Optional.absent());
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.absent());
org.assertj.core.api.Assertions.assertThat(opt).isEqualTo(Optional.of("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.of("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isEqualTo(Optional.absent());
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.absent());
} }
} }

View File

@ -0,0 +1,27 @@
import com.google.common.base.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;
public class AssertThatGuavaOptional {
private void assertThatGuavaOptional() {
Optional<String> opt = Optional.absent();
assertThat(opt).contains("foo");
assertThat(opt).contains("foo");
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isPresent();
assertThat(opt).isAbsent();
assertThat(opt).contains("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).isAbsent();
assertThat(opt).isPresent();
}
}

View File

@ -0,0 +1,26 @@
import com.google.common.base.Optional;
import static org.assertj.core.api.Assertions.assertThat;
public class AssertThatGuavaOptional {
private void assertThatGuavaOptional() {
Optional<String> opt = Optional.absent();
assertThat(opt).isEqualTo(Optional.of("foo"));
assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
assertThat(opt.isPresent()).isTrue();
assertThat(opt.isPresent()).isFalse();
assertThat(opt.get()).isEqualTo("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).isEqualTo(Optional.absent());
assertThat(opt).isNotEqualTo(Optional.absent());
}
}