Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
941ddfdb5e | ||
|
|
666e373405 | ||
|
|
8b0da63f86 |
@@ -70,7 +70,20 @@ assertThat(array).hasSameSizeAs(collection);
|
|||||||
|
|
||||||
You can toggle the various inspections in the Settings/Editor/Inspections in the AssertJ group.
|
You can toggle the various inspections in the Settings/Editor/Inspections in the AssertJ group.
|
||||||
|
|
||||||
## Implemented inspections
|
## Implemented inspections and quickfixes
|
||||||
|
|
||||||
|
- JoinAssertThatStatements
|
||||||
|
```
|
||||||
|
from: assertThat(expected).someCondition();
|
||||||
|
assertThat(expected).anotherCondition();
|
||||||
|
to: assertThat(expected).someCondition().anotherCondition();
|
||||||
|
```
|
||||||
|
Joining will work on actual expressions inside assertThat() that are
|
||||||
|
- the same variable reference
|
||||||
|
- textually equal binary expressions
|
||||||
|
- the same method calls (except for known side-effect methods such as ```Iterator.next()``` -- please notify me about others)
|
||||||
|
|
||||||
|
The comments of the statements will be preserved. When using ```.extracting()``` or similar, the statements will not be merged.
|
||||||
|
|
||||||
- AssertThatObjectIsNullOrNotNull
|
- AssertThatObjectIsNullOrNotNull
|
||||||
```
|
```
|
||||||
@@ -156,6 +169,9 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
|
|||||||
|
|
||||||
from: assertThat(array.length).isEqualTo(anotherArray.length);
|
from: assertThat(array.length).isEqualTo(anotherArray.length);
|
||||||
to: assertThat(array).hasSameSizeAs(anotherArray);
|
to: assertThat(array).hasSameSizeAs(anotherArray);
|
||||||
|
|
||||||
|
from: assertThat(array).hasSize(anotherArray.length);
|
||||||
|
to: assertThat(array).hasSameSizeAs(anotherArray);
|
||||||
```
|
```
|
||||||
|
|
||||||
and additionally with AssertJ 13.2.0 or later
|
and additionally with AssertJ 13.2.0 or later
|
||||||
@@ -181,6 +197,9 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
|
|||||||
|
|
||||||
from: assertThat("string".length()).isEqualTo(collection.size())
|
from: assertThat("string".length()).isEqualTo(collection.size())
|
||||||
to: assertThat("string").hasSameSizeAs(collection);
|
to: assertThat("string").hasSameSizeAs(collection);
|
||||||
|
|
||||||
|
from: assertThat("string".length()).hasSize("strong".length())
|
||||||
|
to: assertThat("string").hasSameSizeAs("strong");
|
||||||
```
|
```
|
||||||
|
|
||||||
- AssertThatBinaryExpression
|
- AssertThatBinaryExpression
|
||||||
@@ -314,9 +333,8 @@ Cajon is probably the only plugin that uses JUnit 5 Jupiter for unit testing so
|
|||||||
The IntelliJ framework actually uses the JUnit 3 TestCase for plugin testing and it took me quite a while to make it work with JUnit 5.
|
The IntelliJ framework actually uses the JUnit 3 TestCase for plugin testing and it took me quite a while to make it work with JUnit 5.
|
||||||
Feel free to use the code (in package de.platon42.intellij.jupiter) for your projects (with attribution).
|
Feel free to use the code (in package de.platon42.intellij.jupiter) for your projects (with attribution).
|
||||||
|
|
||||||
## TODO
|
## Planned features
|
||||||
- AssumeThatInsteadOfReturn
|
- AssumeThatInsteadOfReturn
|
||||||
- Join consecutive assertThats
|
|
||||||
- Extraction with property names to lambda with Java 8
|
- Extraction with property names to lambda with Java 8
|
||||||
```
|
```
|
||||||
from: assertThat(object).extracting("propOne", "propNoGetter", "propTwo.innerProp")...
|
from: assertThat(object).extracting("propOne", "propNoGetter", "propTwo.innerProp")...
|
||||||
@@ -327,6 +345,13 @@ Feel free to use the code (in package de.platon42.intellij.jupiter) for your pro
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
#### V0.7 (28-Apr-19)
|
||||||
|
- Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions
|
||||||
|
(really, Jetbrains, this sucks for no reason).
|
||||||
|
- Extended AssertThatSize inspection to transform ```hasSize()``` into ```hasSameSizeAs()```, if possible.
|
||||||
|
- Implemented first version of JoinAssertThatStatements inspection that will try to merge ```assertThat()``` statements with the same
|
||||||
|
actual object together, preserving comments.
|
||||||
|
|
||||||
#### V0.6 (22-Apr-19)
|
#### V0.6 (22-Apr-19)
|
||||||
- New AssertThatStringExpression inspection that will move ```isEmpty()```, ```equals()```, ```equalsIgnoreCase()```, ```contains()```,
|
- New AssertThatStringExpression inspection that will move ```isEmpty()```, ```equals()```, ```equalsIgnoreCase()```, ```contains()```,
|
||||||
```startsWith()```, and ```endsWith()``` out of actual expression.
|
```startsWith()```, and ```endsWith()``` out of actual expression.
|
||||||
|
|||||||
+10
-11
@@ -1,11 +1,11 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'org.jetbrains.intellij' version '0.4.8'
|
id 'org.jetbrains.intellij' version '0.4.8'
|
||||||
id 'org.jetbrains.kotlin.jvm' version '1.3.30'
|
id 'org.jetbrains.kotlin.jvm' version '1.3.31'
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'de.platon42'
|
group 'de.platon42'
|
||||||
version '0.6'
|
version '0.7'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -40,6 +40,14 @@ intellij {
|
|||||||
|
|
||||||
patchPluginXml {
|
patchPluginXml {
|
||||||
changeNotes """
|
changeNotes """
|
||||||
|
<h4>V0.7 (28-Apr-19)</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions
|
||||||
|
(really, Jetbrains, this sucks for no reason).
|
||||||
|
<li>Extended AssertThatSize inspection to transform hasSize() into hasSameSizeAs(), if possible.
|
||||||
|
<li>Implemented first version of JoinAssertThatStatements inspection that will try to merge assertThat() statements with the same
|
||||||
|
actual object together, preserving comments.
|
||||||
|
</ul>
|
||||||
<h4>V0.6 (22-Apr-19)</h4>
|
<h4>V0.6 (22-Apr-19)</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>New AssertThatStringExpression inspection that will move isEmpty(), equals(), equalsIgnoreCase(), contains(),
|
<li>New AssertThatStringExpression inspection that will move isEmpty(), equals(), equalsIgnoreCase(), contains(),
|
||||||
@@ -49,15 +57,6 @@ patchPluginXml {
|
|||||||
<li>Renamed a few inspections to better/shorter names.
|
<li>Renamed a few inspections to better/shorter names.
|
||||||
<li>New AssertThatInstanceOf inspection that moves instanceof expressions out of assertThat().
|
<li>New AssertThatInstanceOf inspection that moves instanceof expressions out of assertThat().
|
||||||
</ul>
|
</ul>
|
||||||
<h4>V0.5 (18-Apr-19)</h4>
|
|
||||||
<ul>
|
|
||||||
<li>Fixed incompatibility with IDEA versions < 2018.2 (affected AssertThatSizeInspection). Minimal version is now 2017.3.
|
|
||||||
<li>Fixed missing Guava imports (if not already present) for AssertThatGuavaInspection. This was a major PITA to get right.
|
|
||||||
<li>Added support for referencing and refactoring inside .extracting() methods with fields, properties and methods (though
|
|
||||||
getter renaming does not work that perfect, but I'm giving up for now as the IntelliJ SDK docs are seriously lacking).
|
|
||||||
<li>Fixed an exception in batch mode if the description string was the same but for different fixes.
|
|
||||||
Now descriptions are different for quick fixes triggered by AssertThatJava8OptionalInspection and AssertThatGuavaOptionalInspection.
|
|
||||||
</ul>
|
|
||||||
<p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p>
|
<p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p>
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package de.platon42.intellij.plugins.cajon
|
||||||
|
|
||||||
|
import com.intellij.psi.CommonClassNames
|
||||||
|
import com.siyeh.ig.callMatcher.CallMatcher
|
||||||
|
|
||||||
|
val CORE_ASSERT_THAT_MATCHER = CallMatcher.staticCall(AssertJClassNames.ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)!!
|
||||||
|
val GUAVA_ASSERT_THAT_MATCHER = CallMatcher.staticCall(AssertJClassNames.GUAVA_ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)!!
|
||||||
|
val ALL_ASSERT_THAT_MATCHERS = CallMatcher.anyOf(CORE_ASSERT_THAT_MATCHER, GUAVA_ASSERT_THAT_MATCHER)!!
|
||||||
|
val EXTRACTING_FROM_OBJECT = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_OBJECT_ASSERT_CLASSNAME, "extracting")!!
|
||||||
|
val EXTRACTING_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "extracting")!!
|
||||||
|
val FLAT_EXTRACTING_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "flatExtracting")!!
|
||||||
|
val EXTRACTING_RESULT_OF_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "extractingResultOf")!!
|
||||||
|
|
||||||
|
val EXTRACTING_CALL_MATCHERS = CallMatcher.anyOf(
|
||||||
|
EXTRACTING_FROM_OBJECT,
|
||||||
|
EXTRACTING_FROM_ITERABLE,
|
||||||
|
FLAT_EXTRACTING_FROM_ITERABLE,
|
||||||
|
EXTRACTING_RESULT_OF_FROM_ITERABLE
|
||||||
|
)!!
|
||||||
|
|
||||||
|
val KNOWN_METHODS_WITH_SIDE_EFFECTS = CallMatcher.anyOf(
|
||||||
|
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_ITERATOR, "next")
|
||||||
|
)!!
|
||||||
@@ -4,6 +4,7 @@ import com.intellij.psi.*
|
|||||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager
|
import com.intellij.psi.codeStyle.JavaCodeStyleManager
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import com.siyeh.ig.callMatcher.CallMatcher
|
||||||
|
|
||||||
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]!!
|
||||||
@@ -21,6 +22,17 @@ fun PsiElement.findOutmostMethodCall(): PsiMethodCallExpression? {
|
|||||||
return PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java)
|
return PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiMethodCallExpression.findFluentCallTo(matcher: CallMatcher): PsiMethodCallExpression? {
|
||||||
|
var currentMethodCall: PsiMethodCallExpression? = this
|
||||||
|
while (currentMethodCall != null) {
|
||||||
|
if (matcher.test(currentMethodCall)) {
|
||||||
|
return currentMethodCall
|
||||||
|
}
|
||||||
|
currentMethodCall = PsiTreeUtil.getParentOfType(currentMethodCall, PsiMethodCallExpression::class.java, true, PsiStatement::class.java)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ import com.intellij.psi.JavaPsiFacade
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiExpression
|
import com.intellij.psi.PsiExpression
|
||||||
import com.intellij.psi.PsiMethodCallExpression
|
import com.intellij.psi.PsiMethodCallExpression
|
||||||
import com.siyeh.ig.callMatcher.CallMatcher
|
|
||||||
|
|
||||||
val CORE_ASSERT_THAT_MATCHER = CallMatcher.staticCall(AssertJClassNames.ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)!!
|
|
||||||
|
|
||||||
fun createAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
|
fun createAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
|
||||||
return createAssertThat(context, AssertJClassNames.ASSERTIONS_CLASSNAME, actualExpression)
|
return createAssertThat(context, AssertJClassNames.ASSERTIONS_CLASSNAME, actualExpression)
|
||||||
|
|||||||
+8
-8
@@ -29,7 +29,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
|||||||
|
|
||||||
const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with %s()"
|
const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with %s()"
|
||||||
const val REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE = "Remove unwrapping of expected expression and replace %s() with %s()"
|
const val REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE = "Remove unwrapping of expected expression and replace %s() with %s()"
|
||||||
const val REMOVE_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with %s()"
|
const val UNWRAP_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with %s()"
|
||||||
|
|
||||||
val TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP = mapOf<IElementType, String>(
|
val TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP = mapOf<IElementType, String>(
|
||||||
JavaTokenType.EQEQ to MethodNames.IS_EQUAL_TO,
|
JavaTokenType.EQEQ to MethodNames.IS_EQUAL_TO,
|
||||||
@@ -184,16 +184,16 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
|||||||
replacementMethod: String,
|
replacementMethod: String,
|
||||||
quickFixSupplier: (String, String) -> LocalQuickFix
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
) {
|
) {
|
||||||
registerConciseMethod(REPLACE_DESCRIPTION_TEMPLATE, oldExpectedCallExpression, replacementMethod, quickFixSupplier, holder, expression)
|
registerConciseMethod(REPLACE_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerConciseMethod(
|
protected fun registerConciseMethod(
|
||||||
descriptionTemplate: String,
|
descriptionTemplate: String,
|
||||||
|
holder: ProblemsHolder,
|
||||||
|
expression: PsiMethodCallExpression,
|
||||||
oldExpectedCallExpression: PsiMethodCallExpression,
|
oldExpectedCallExpression: PsiMethodCallExpression,
|
||||||
replacementMethod: String,
|
replacementMethod: String,
|
||||||
quickFixSupplier: (String, String) -> LocalQuickFix,
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
holder: ProblemsHolder,
|
|
||||||
expression: PsiMethodCallExpression
|
|
||||||
) {
|
) {
|
||||||
val originalMethod = getOriginalMethodName(oldExpectedCallExpression) ?: return
|
val originalMethod = getOriginalMethodName(oldExpectedCallExpression) ?: return
|
||||||
val description = descriptionTemplate.format(originalMethod, replacementMethod)
|
val description = descriptionTemplate.format(originalMethod, replacementMethod)
|
||||||
@@ -209,7 +209,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
|||||||
replacementMethod: String,
|
replacementMethod: String,
|
||||||
quickFixSupplier: (String, String) -> LocalQuickFix
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
) {
|
) {
|
||||||
registerConciseMethod(REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE, oldExpectedCallExpression, replacementMethod, quickFixSupplier, holder, expression)
|
registerConciseMethod(REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun registerRemoveActualOutmostMethod(
|
protected fun registerRemoveActualOutmostMethod(
|
||||||
@@ -219,7 +219,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
|||||||
replacementMethod: String,
|
replacementMethod: String,
|
||||||
quickFixSupplier: (String, String) -> LocalQuickFix
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
) {
|
) {
|
||||||
registerConciseMethod(REMOVE_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE, oldExpectedCallExpression, replacementMethod, quickFixSupplier, holder, expression)
|
registerConciseMethod(UNWRAP_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? {
|
protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? {
|
||||||
|
|||||||
+13
-13
@@ -76,19 +76,19 @@ class AssertThatBinaryExpressionInspection : AbstractAssertJInspection() {
|
|||||||
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = swapExpectedAndActual)
|
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = swapExpectedAndActual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerSplitMethod(
|
|
||||||
holder: ProblemsHolder,
|
|
||||||
expression: PsiMethodCallExpression,
|
|
||||||
type: String,
|
|
||||||
replacementMethod: String,
|
|
||||||
quickFixSupplier: (String, String) -> LocalQuickFix
|
|
||||||
) {
|
|
||||||
val description = SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE.format(type)
|
|
||||||
val message = MORE_MEANINGFUL_MESSAGE_TEMPLATE.format(type)
|
|
||||||
val quickfix = quickFixSupplier(description, replacementMethod)
|
|
||||||
holder.registerProblem(expression, message, quickfix)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun registerSplitMethod(
|
||||||
|
holder: ProblemsHolder,
|
||||||
|
expression: PsiMethodCallExpression,
|
||||||
|
type: String,
|
||||||
|
replacementMethod: String,
|
||||||
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
|
) {
|
||||||
|
val description = SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE.format(type)
|
||||||
|
val message = MORE_MEANINGFUL_MESSAGE_TEMPLATE.format(type)
|
||||||
|
val quickfix = quickFixSupplier(description, replacementMethod)
|
||||||
|
holder.registerProblem(expression, message, quickfix)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+21
-9
@@ -14,6 +14,9 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DISPLAY_NAME = "Asserting an Optional (Guava)"
|
private const val DISPLAY_NAME = "Asserting an Optional (Guava)"
|
||||||
|
private const val REPLACE_GUAVA_DESCRIPTION_TEMPLATE = "Replace %s() with Guava assertThat().%s()"
|
||||||
|
private const val REMOVE_EXPECTED_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE = "Remove unwrapping of expected expression and replace %s() with Guava assertThat().%s()"
|
||||||
|
private const val REMOVE_ACTUAL_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with Guava assertThat().%s()"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDisplayName() = DISPLAY_NAME
|
override fun getDisplayName() = DISPLAY_NAME
|
||||||
@@ -36,7 +39,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
|||||||
if (isEqualTo) {
|
if (isEqualTo) {
|
||||||
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
|
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
|
||||||
if (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
|
if (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
|
||||||
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix)
|
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix)
|
||||||
} 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)
|
||||||
}
|
}
|
||||||
@@ -62,12 +65,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
|||||||
if (isEqualTo) {
|
if (isEqualTo) {
|
||||||
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
|
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
|
||||||
if (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
|
if (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
|
||||||
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) { desc, method ->
|
registerRemoveExpectedOutmostGuavaMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
|
||||||
QuickFixWithPostfixDelegate(
|
|
||||||
RemoveExpectedOutmostMethodCallQuickFix(desc, method),
|
|
||||||
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
|
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
|
||||||
registerSimplifyForGuavaMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
|
registerSimplifyForGuavaMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
|
||||||
}
|
}
|
||||||
@@ -82,6 +80,20 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun registerRemoveExpectedOutmostGuavaMethod(
|
||||||
|
holder: ProblemsHolder,
|
||||||
|
expression: PsiMethodCallExpression,
|
||||||
|
oldExpectedCallExpression: PsiMethodCallExpression,
|
||||||
|
replacementMethod: String
|
||||||
|
) {
|
||||||
|
registerConciseMethod(REMOVE_EXPECTED_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method ->
|
||||||
|
QuickFixWithPostfixDelegate(
|
||||||
|
UnwrapExpectedStaticMethodCallQuickFix(desc, method),
|
||||||
|
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun registerRemoveActualOutmostForGuavaMethod(
|
private fun registerRemoveActualOutmostForGuavaMethod(
|
||||||
holder: ProblemsHolder,
|
holder: ProblemsHolder,
|
||||||
expression: PsiMethodCallExpression,
|
expression: PsiMethodCallExpression,
|
||||||
@@ -89,7 +101,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
|||||||
replacementMethod: String,
|
replacementMethod: String,
|
||||||
noExpectedExpression: Boolean = false
|
noExpectedExpression: Boolean = false
|
||||||
) {
|
) {
|
||||||
registerRemoveActualOutmostMethod(holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method ->
|
registerConciseMethod(REMOVE_ACTUAL_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method ->
|
||||||
QuickFixWithPostfixDelegate(
|
QuickFixWithPostfixDelegate(
|
||||||
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression),
|
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression),
|
||||||
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
|
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
|
||||||
@@ -99,7 +111,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
|||||||
|
|
||||||
private fun registerSimplifyForGuavaMethod(holder: ProblemsHolder, expression: PsiMethodCallExpression, replacementMethod: String) {
|
private fun registerSimplifyForGuavaMethod(holder: ProblemsHolder, expression: PsiMethodCallExpression, replacementMethod: String) {
|
||||||
val originalMethod = getOriginalMethodName(expression) ?: return
|
val originalMethod = getOriginalMethodName(expression) ?: return
|
||||||
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
|
val description = REPLACE_GUAVA_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
|
||||||
val message = SIMPLIFY_MESSAGE_TEMPLATE.format(originalMethod, replacementMethod)
|
val message = SIMPLIFY_MESSAGE_TEMPLATE.format(originalMethod, replacementMethod)
|
||||||
val quickFix = QuickFixWithPostfixDelegate(
|
val quickFix = QuickFixWithPostfixDelegate(
|
||||||
ReplaceSimpleMethodCallQuickFix(description, replacementMethod),
|
ReplaceSimpleMethodCallQuickFix(description, replacementMethod),
|
||||||
|
|||||||
+11
-11
@@ -38,17 +38,17 @@ class AssertThatInstanceOfInspection : AbstractAssertJInspection() {
|
|||||||
registerRemoveInstanceOfMethod(holder, expression, replacementMethod, ::RemoveInstanceOfExpressionQuickFix)
|
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+10
-10
@@ -36,16 +36,16 @@ class AssertThatInvertedBooleanConditionInspection : AbstractAssertJInspection()
|
|||||||
registerInvertMethod(holder, expression, replacementMethod, ::RemoveUnaryExpressionQuickFix)
|
registerInvertMethod(holder, expression, replacementMethod, ::RemoveUnaryExpressionQuickFix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerInvertMethod(
|
|
||||||
holder: ProblemsHolder,
|
|
||||||
expression: PsiMethodCallExpression,
|
|
||||||
replacementMethod: String,
|
|
||||||
quickFixSupplier: (String, String) -> LocalQuickFix
|
|
||||||
) {
|
|
||||||
val quickfix = quickFixSupplier(INVERT_CONDITION_DESCRIPTION, replacementMethod)
|
|
||||||
holder.registerProblem(expression, INVERT_CONDITION_MESSAGE, quickfix)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun registerInvertMethod(
|
||||||
|
holder: ProblemsHolder,
|
||||||
|
expression: PsiMethodCallExpression,
|
||||||
|
replacementMethod: String,
|
||||||
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
|
) {
|
||||||
|
val quickfix = quickFixSupplier(INVERT_CONDITION_DESCRIPTION, replacementMethod)
|
||||||
|
holder.registerProblem(expression, INVERT_CONDITION_MESSAGE, quickfix)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -10,7 +10,7 @@ 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.RemoveActualOutmostMethodCallQuickFix
|
||||||
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveExpectedOutmostMethodCallQuickFix
|
import de.platon42.intellij.plugins.cajon.quickfixes.UnwrapExpectedStaticMethodCallQuickFix
|
||||||
|
|
||||||
class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
|
class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
|
|||||||
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 (CallMatcher.anyOf(OPTIONAL_OF, OPTIONAL_OF_NULLABLE).test(innerExpectedCall)) {
|
if (CallMatcher.anyOf(OPTIONAL_OF, OPTIONAL_OF_NULLABLE).test(innerExpectedCall)) {
|
||||||
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix)
|
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix)
|
||||||
} 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)
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-6
@@ -2,17 +2,17 @@ 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.*
|
||||||
|
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME
|
||||||
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.findOutmostMethodCall
|
|
||||||
import de.platon42.intellij.plugins.cajon.firstArg
|
|
||||||
import de.platon42.intellij.plugins.cajon.map
|
|
||||||
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix
|
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix
|
||||||
|
|
||||||
class AssertThatSizeInspection : AbstractAssertJInspection() {
|
class AssertThatSizeInspection : AbstractAssertJInspection() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DISPLAY_NAME = "Asserting the size of an collection, array or string"
|
private const val DISPLAY_NAME = "Asserting the size of an collection, array or string"
|
||||||
|
private const val REMOVE_SIZE_DESCRIPTION_TEMPLATE = "Remove size determination of expected expression and replace %s() with %s()"
|
||||||
|
|
||||||
private val BONUS_EXPRESSIONS_CALL_MATCHER_MAP = listOf(
|
private val BONUS_EXPRESSIONS_CALL_MATCHER_MAP = listOf(
|
||||||
IS_LESS_THAN_INT to MethodNames.HAS_SIZE_LESS_THAN,
|
IS_LESS_THAN_INT to MethodNames.HAS_SIZE_LESS_THAN,
|
||||||
@@ -28,14 +28,29 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
|
|||||||
return object : JavaElementVisitor() {
|
return object : JavaElementVisitor() {
|
||||||
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
|
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
|
||||||
super.visitMethodCallExpression(expression)
|
super.visitMethodCallExpression(expression)
|
||||||
if (!ASSERT_THAT_INT.test(expression)) {
|
val isAssertThatWithInt = ASSERT_THAT_INT.test(expression)
|
||||||
|
val isHasSize = HAS_SIZE.test(expression)
|
||||||
|
if (!(isAssertThatWithInt || isHasSize)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val actualExpression = expression.firstArg
|
val actualExpression = expression.firstArg
|
||||||
|
|
||||||
val isForArrayOrCollection = isArrayLength(actualExpression) || isCollectionSize(actualExpression)
|
val isForArrayOrCollection = isArrayLength(actualExpression) || isCollectionSize(actualExpression)
|
||||||
val isForString = isCharSequenceLength(actualExpression)
|
val isForString = isCharSequenceLength(actualExpression)
|
||||||
if (isForArrayOrCollection || isForString) {
|
if (isHasSize && (isForArrayOrCollection
|
||||||
|
|| (isForString && checkAssertedType(expression, ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME)))
|
||||||
|
) {
|
||||||
|
val assertThatCall = PsiTreeUtil.findChildrenOfType(expression, PsiMethodCallExpression::class.java).find { CORE_ASSERT_THAT_MATCHER.test(it) } ?: return
|
||||||
|
registerConciseMethod(
|
||||||
|
REMOVE_SIZE_DESCRIPTION_TEMPLATE,
|
||||||
|
holder,
|
||||||
|
assertThatCall,
|
||||||
|
expression,
|
||||||
|
MethodNames.HAS_SAME_SIZE_AS
|
||||||
|
) { desc, method ->
|
||||||
|
ReplaceSizeMethodCallQuickFix(desc, method, expectedIsCollection = true, keepActualAsIs = true)
|
||||||
|
}
|
||||||
|
} else if (isForArrayOrCollection || isForString) {
|
||||||
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
|
val expectedCallExpression = expression.findOutmostMethodCall() ?: 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)) {
|
||||||
|
|||||||
+14
-14
@@ -76,23 +76,23 @@ class AssertThatStringExpressionInspection : AbstractAssertJInspection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerMoveOutMethod(
|
|
||||||
holder: ProblemsHolder,
|
|
||||||
expression: PsiMethodCallExpression,
|
|
||||||
oldActualExpression: PsiMethodCallExpression,
|
|
||||||
replacementMethod: String,
|
|
||||||
quickFixSupplier: (String, String) -> LocalQuickFix
|
|
||||||
) {
|
|
||||||
val originalMethod = getOriginalMethodName(oldActualExpression) ?: return
|
|
||||||
val description = MOVE_EXPECTED_EXPRESSION_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
|
|
||||||
val message = MOVING_OUT_MESSAGE_TEMPLATE.format(originalMethod)
|
|
||||||
val quickfix = quickFixSupplier(description, replacementMethod)
|
|
||||||
holder.registerProblem(expression, message, quickfix)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun registerMoveOutMethod(
|
||||||
|
holder: ProblemsHolder,
|
||||||
|
expression: PsiMethodCallExpression,
|
||||||
|
oldActualExpression: PsiMethodCallExpression,
|
||||||
|
replacementMethod: String,
|
||||||
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
|
) {
|
||||||
|
val originalMethod = getOriginalMethodName(oldActualExpression) ?: return
|
||||||
|
val description = MOVE_EXPECTED_EXPRESSION_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
|
||||||
|
val message = MOVING_OUT_MESSAGE_TEMPLATE.format(originalMethod)
|
||||||
|
val quickfix = quickFixSupplier(description, replacementMethod)
|
||||||
|
holder.registerProblem(expression, message, quickfix)
|
||||||
|
}
|
||||||
|
|
||||||
private class Mapping(
|
private class Mapping(
|
||||||
val callMatcher: CallMatcher,
|
val callMatcher: CallMatcher,
|
||||||
val replacementForTrue: String,
|
val replacementForTrue: String,
|
||||||
|
|||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
package de.platon42.intellij.plugins.cajon.inspections
|
||||||
|
|
||||||
|
import com.intellij.codeInspection.ProblemHighlightType
|
||||||
|
import com.intellij.codeInspection.ProblemsHolder
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import de.platon42.intellij.plugins.cajon.*
|
||||||
|
import de.platon42.intellij.plugins.cajon.quickfixes.JoinStatementsQuickFix
|
||||||
|
|
||||||
|
class JoinAssertThatStatementsInspection : AbstractAssertJInspection() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DISPLAY_NAME = "Joining multiple assertThat() statements with same actual expression"
|
||||||
|
private const val CAN_BE_JOINED_DESCRIPTION = "Multiple assertThat() statements can be joined together"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDisplayName() = DISPLAY_NAME
|
||||||
|
|
||||||
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
||||||
|
return object : JavaElementVisitor() {
|
||||||
|
override fun visitCodeBlock(block: PsiCodeBlock?) {
|
||||||
|
super.visitCodeBlock(block)
|
||||||
|
val statements = block?.statements ?: return
|
||||||
|
var lastActualExpression: PsiExpression? = null
|
||||||
|
var sameCount = 0
|
||||||
|
var firstStatement: PsiStatement? = null
|
||||||
|
var lastStatement: PsiStatement? = null
|
||||||
|
for (statement in statements) {
|
||||||
|
val assertThatCall = isLegitAssertThatCall(statement)
|
||||||
|
var reset = true
|
||||||
|
var actualExpression: PsiExpression? = null
|
||||||
|
if (assertThatCall != null) {
|
||||||
|
reset = (lastActualExpression == null)
|
||||||
|
actualExpression = assertThatCall.firstArg
|
||||||
|
if (!reset) {
|
||||||
|
val isSame = when (actualExpression) {
|
||||||
|
is PsiReferenceExpression -> (actualExpression.qualifierExpression == (lastActualExpression as? PsiReferenceExpression)?.qualifierExpression)
|
||||||
|
is PsiMethodCallExpression -> (actualExpression.text == (lastActualExpression as? PsiMethodCallExpression)?.text)
|
||||||
|
&& !KNOWN_METHODS_WITH_SIDE_EFFECTS.test(actualExpression)
|
||||||
|
is PsiPolyadicExpression -> (actualExpression.text == (lastActualExpression as? PsiPolyadicExpression)?.text)
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if (isSame) {
|
||||||
|
sameCount++
|
||||||
|
lastStatement = statement
|
||||||
|
} else {
|
||||||
|
reset = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reset) {
|
||||||
|
if (sameCount > 1) {
|
||||||
|
registerProblem(firstStatement, lastStatement)
|
||||||
|
}
|
||||||
|
firstStatement = statement
|
||||||
|
lastStatement = null
|
||||||
|
lastActualExpression = actualExpression
|
||||||
|
sameCount = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sameCount > 1) {
|
||||||
|
registerProblem(firstStatement, lastStatement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerProblem(firstStatement: PsiStatement?, lastStatement: PsiStatement?) {
|
||||||
|
val problemDescriptor = holder.manager.createProblemDescriptor(
|
||||||
|
firstStatement!!,
|
||||||
|
lastStatement!!,
|
||||||
|
CAN_BE_JOINED_DESCRIPTION,
|
||||||
|
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||||
|
isOnTheFly,
|
||||||
|
JoinStatementsQuickFix()
|
||||||
|
)
|
||||||
|
holder.registerProblem(problemDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isLegitAssertThatCall(statement: PsiStatement?): PsiMethodCallExpression? {
|
||||||
|
if ((statement is PsiExpressionStatement) && (statement.expression is PsiMethodCallExpression)) {
|
||||||
|
val assertThatCall = PsiTreeUtil.findChildrenOfType(statement, PsiMethodCallExpression::class.java).find { ALL_ASSERT_THAT_MATCHERS.test(it) }
|
||||||
|
return assertThatCall?.takeIf { it.findFluentCallTo(EXTRACTING_CALL_MATCHERS) == null }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package de.platon42.intellij.plugins.cajon.quickfixes
|
||||||
|
|
||||||
|
import com.intellij.codeInspection.ProblemDescriptor
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import de.platon42.intellij.plugins.cajon.ALL_ASSERT_THAT_MATCHERS
|
||||||
|
|
||||||
|
class JoinStatementsQuickFix : AbstractCommonQuickFix(JOIN_STATEMENTS_MESSAGE) {
|
||||||
|
companion object {
|
||||||
|
private const val JOIN_STATEMENTS_MESSAGE = "Join assertThat() statements"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||||
|
val firstStatement = descriptor.startElement as PsiExpressionStatement
|
||||||
|
val lastStatement = descriptor.endElement as PsiExpressionStatement
|
||||||
|
do {
|
||||||
|
val commentsToKeep = ArrayList<PsiComment>()
|
||||||
|
val stuffToDelete = ArrayList<PsiElement>()
|
||||||
|
var previousStatement = lastStatement.prevSibling ?: throw IllegalStateException("Internal error")
|
||||||
|
while (previousStatement !is PsiExpressionStatement) {
|
||||||
|
if (previousStatement is PsiComment) {
|
||||||
|
commentsToKeep.add(previousStatement.copy() as PsiComment)
|
||||||
|
}
|
||||||
|
stuffToDelete.add(previousStatement)
|
||||||
|
previousStatement = previousStatement.prevSibling ?: throw IllegalStateException("Internal error")
|
||||||
|
}
|
||||||
|
stuffToDelete.forEach { if (it.isValid) it.delete() }
|
||||||
|
|
||||||
|
val statementComments = PsiTreeUtil.getChildrenOfAnyType(previousStatement, PsiComment::class.java)
|
||||||
|
commentsToKeep.addAll(statementComments)
|
||||||
|
|
||||||
|
val assertThatCallOfCursorStatement =
|
||||||
|
PsiTreeUtil.findChildrenOfType(lastStatement, PsiMethodCallExpression::class.java).find { ALL_ASSERT_THAT_MATCHERS.test(it) }
|
||||||
|
?: throw IllegalStateException("Internal error")
|
||||||
|
|
||||||
|
val lastElementBeforeConcat = assertThatCallOfCursorStatement.parent
|
||||||
|
commentsToKeep.forEach {
|
||||||
|
lastElementBeforeConcat.addAfter(it, lastElementBeforeConcat.firstChild)
|
||||||
|
val newLineNode =
|
||||||
|
PsiParserFacade.SERVICE.getInstance(project).createWhiteSpaceFromText("\n\t")
|
||||||
|
|
||||||
|
lastElementBeforeConcat.addAfter(newLineNode, lastElementBeforeConcat.firstChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
val newLeaf = previousStatement.firstChild
|
||||||
|
assertThatCallOfCursorStatement.replace(newLeaf)
|
||||||
|
previousStatement.delete()
|
||||||
|
} while (previousStatement !== firstStatement)
|
||||||
|
val codeBlock = PsiTreeUtil.getParentOfType(lastStatement, PsiCodeBlock::class.java) ?: return
|
||||||
|
CodeStyleManager.getInstance(project).reformat(codeBlock)
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-6
@@ -5,7 +5,7 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.psi.JavaPsiFacade
|
import com.intellij.psi.JavaPsiFacade
|
||||||
import com.intellij.psi.PsiInstanceOfExpression
|
import com.intellij.psi.PsiInstanceOfExpression
|
||||||
import com.intellij.psi.PsiMethodCallExpression
|
import com.intellij.psi.PsiMethodCallExpression
|
||||||
import com.intellij.psi.PsiParenthesizedExpression
|
import com.intellij.psi.util.PsiUtil
|
||||||
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
|
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
|
||||||
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
|
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
|
||||||
import de.platon42.intellij.plugins.cajon.firstArg
|
import de.platon42.intellij.plugins.cajon.firstArg
|
||||||
@@ -21,11 +21,7 @@ class RemoveInstanceOfExpressionQuickFix(description: String, private val replac
|
|||||||
val factory = JavaPsiFacade.getElementFactory(project)
|
val factory = JavaPsiFacade.getElementFactory(project)
|
||||||
val classObjectAccess = factory.createExpressionFromText("${expectedClass.type.canonicalText}.class", null)
|
val classObjectAccess = factory.createExpressionFromText("${expectedClass.type.canonicalText}.class", null)
|
||||||
|
|
||||||
var operand = assertExpression.operand
|
val operand = PsiUtil.deparenthesizeExpression(assertExpression.operand) ?: return
|
||||||
while (operand is PsiParenthesizedExpression) {
|
|
||||||
operand = operand.expression ?: return
|
|
||||||
}
|
|
||||||
|
|
||||||
assertExpression.replace(operand)
|
assertExpression.replace(operand)
|
||||||
|
|
||||||
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
|
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
|
||||||
|
|||||||
+2
-5
@@ -3,8 +3,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.PsiMethodCallExpression
|
import com.intellij.psi.PsiMethodCallExpression
|
||||||
import com.intellij.psi.PsiParenthesizedExpression
|
|
||||||
import com.intellij.psi.PsiUnaryExpression
|
import com.intellij.psi.PsiUnaryExpression
|
||||||
|
import com.intellij.psi.util.PsiUtil
|
||||||
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
|
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
|
||||||
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
|
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
|
||||||
import de.platon42.intellij.plugins.cajon.firstArg
|
import de.platon42.intellij.plugins.cajon.firstArg
|
||||||
@@ -16,10 +16,7 @@ class RemoveUnaryExpressionQuickFix(description: String, private val replacement
|
|||||||
val element = descriptor.startElement
|
val element = descriptor.startElement
|
||||||
val methodCallExpression = element as? PsiMethodCallExpression ?: return
|
val methodCallExpression = element as? PsiMethodCallExpression ?: return
|
||||||
val assertExpression = methodCallExpression.firstArg as? PsiUnaryExpression ?: return
|
val assertExpression = methodCallExpression.firstArg as? PsiUnaryExpression ?: return
|
||||||
var operand = assertExpression.operand ?: return
|
val operand = PsiUtil.skipParenthesizedExprDown(assertExpression.operand) ?: return
|
||||||
while (operand is PsiParenthesizedExpression) {
|
|
||||||
operand = operand.expression ?: return
|
|
||||||
}
|
|
||||||
assertExpression.replace(operand)
|
assertExpression.replace(operand)
|
||||||
|
|
||||||
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
|
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
|
||||||
|
|||||||
+6
-3
@@ -11,14 +11,17 @@ class ReplaceSizeMethodCallQuickFix(
|
|||||||
description: String,
|
description: String,
|
||||||
private val replacementMethod: String,
|
private val replacementMethod: String,
|
||||||
private val noExpectedExpression: Boolean = false,
|
private val noExpectedExpression: Boolean = false,
|
||||||
private val expectedIsCollection: Boolean = false
|
private val expectedIsCollection: Boolean = false,
|
||||||
|
private val keepActualAsIs: Boolean = false
|
||||||
) : AbstractCommonQuickFix(description) {
|
) : 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 assertExpression = methodCallExpression.firstArg
|
if (!keepActualAsIs) {
|
||||||
replaceCollectionSizeOrArrayLength(assertExpression)
|
val assertExpression = methodCallExpression.firstArg
|
||||||
|
replaceCollectionSizeOrArrayLength(assertExpression)
|
||||||
|
}
|
||||||
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
|
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
|
||||||
|
|
||||||
if (expectedIsCollection) {
|
if (expectedIsCollection) {
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ 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
|
||||||
|
|
||||||
class RemoveExpectedOutmostMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
|
class UnwrapExpectedStaticMethodCallQuickFix(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
|
||||||
+1
-9
@@ -10,19 +10,11 @@ import com.intellij.psi.util.PsiTypesUtil
|
|||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import com.intellij.util.ProcessingContext
|
import com.intellij.util.ProcessingContext
|
||||||
import com.siyeh.ig.callMatcher.CallMatcher
|
import com.siyeh.ig.callMatcher.CallMatcher
|
||||||
import de.platon42.intellij.plugins.cajon.AssertJClassNames
|
import de.platon42.intellij.plugins.cajon.*
|
||||||
import de.platon42.intellij.plugins.cajon.CORE_ASSERT_THAT_MATCHER
|
|
||||||
import de.platon42.intellij.plugins.cajon.firstArg
|
|
||||||
|
|
||||||
class ExtractorReferenceContributor : PsiReferenceContributor() {
|
class ExtractorReferenceContributor : PsiReferenceContributor() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val EXTRACTING_FROM_OBJECT = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_OBJECT_ASSERT_CLASSNAME, "extracting")
|
|
||||||
private val EXTRACTING_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "extracting")
|
|
||||||
private val FLAT_EXTRACTING_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "flatExtracting")
|
|
||||||
private val EXTRACTING_RESULT_OF_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "extractingResultOf")
|
|
||||||
|
|
||||||
private val BY_NAME = CallMatcher.staticCall(AssertJClassNames.EXTRACTORS_CLASSNAME, "byName")
|
private val BY_NAME = CallMatcher.staticCall(AssertJClassNames.EXTRACTORS_CLASSNAME, "byName")
|
||||||
private val RESULT_OF = CallMatcher.staticCall(AssertJClassNames.EXTRACTORS_CLASSNAME, "resultOf")
|
private val RESULT_OF = CallMatcher.staticCall(AssertJClassNames.EXTRACTORS_CLASSNAME, "resultOf")
|
||||||
.parameterTypes(CommonClassNames.JAVA_LANG_STRING)!!
|
.parameterTypes(CommonClassNames.JAVA_LANG_STRING)!!
|
||||||
|
|||||||
@@ -43,6 +43,9 @@
|
|||||||
<localInspection groupPath="Java" shortName="AssertThatStringExpression" enabledByDefault="true" level="WARNING"
|
<localInspection groupPath="Java" shortName="AssertThatStringExpression" enabledByDefault="true" level="WARNING"
|
||||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatStringExpressionInspection"/>
|
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatStringExpressionInspection"/>
|
||||||
|
|
||||||
|
<localInspection groupPath="Java" shortName="JoinAssertThatStatements" enabledByDefault="true" level="WARNING"
|
||||||
|
implementationClass="de.platon42.intellij.plugins.cajon.inspections.JoinAssertThatStatementsInspection"/>
|
||||||
|
|
||||||
<localInspection groupPath="Java" shortName="AssertThatJava8Optional" enabledByDefault="true" level="WARNING"
|
<localInspection groupPath="Java" shortName="AssertThatJava8Optional" enabledByDefault="true" level="WARNING"
|
||||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatJava8OptionalInspection"/>
|
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatJava8OptionalInspection"/>
|
||||||
<localInspection groupPath="Java" shortName="AssertThatGuavaOptional" enabledByDefault="true" level="WARNING"
|
<localInspection groupPath="Java" shortName="AssertThatGuavaOptional" enabledByDefault="true" level="WARNING"
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ import org.assertj.core.api.ListAssert;
|
|||||||
import org.assertj.core.data.Offset;
|
import org.assertj.core.data.Offset;
|
||||||
import org.assertj.core.extractor.Extractors;
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.data.Offset.offset;
|
import static org.assertj.core.data.Offset.offset;
|
||||||
@@ -38,6 +35,39 @@ public class Playground {
|
|||||||
assertThat(new Long[1]).as("etc").hasSameSizeAs(new Long[2]);
|
assertThat(new Long[1]).as("etc").hasSameSizeAs(new Long[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void joinStatements() {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
assertThat(list).as("foo").hasSize(2);
|
||||||
|
assertThat(list).as("bar").contains("barbar"); // comment to keep
|
||||||
|
assertThat(list).as("etc").contains("etcetc");
|
||||||
|
|
||||||
|
// moar!
|
||||||
|
assertThat(list).doesNotContain("foobar");
|
||||||
|
|
||||||
|
assertThat("narf").isNotEqualTo("puit");
|
||||||
|
assertThat(list).as("bar").contains("barbar");
|
||||||
|
assertThat(list).as("foo").hasSize(2);
|
||||||
|
assertThat(list).as("evil").extracting(String::length).contains(2);
|
||||||
|
|
||||||
|
assertThat(list).as("bar").contains("barbar");
|
||||||
|
assertThat("narf").isNotEqualTo("puit");
|
||||||
|
assertThat(list).as("foo").hasSize(2);
|
||||||
|
if (true) {
|
||||||
|
assertThat(list).doesNotContain("narf");
|
||||||
|
assertThat(list).as("bar").contains("barbar");
|
||||||
|
}
|
||||||
|
assertThat(list.get(0)).isNotEmpty();
|
||||||
|
assertThat(list.get(0)).hasSize(3);
|
||||||
|
assertThat(list.get(0)).isEqualTo("bar");
|
||||||
|
|
||||||
|
assertThat(list.get(0) + "foo").isEqualTo("bar");
|
||||||
|
assertThat(list.get(0) + "foo").doesNotStartWith("foo");
|
||||||
|
|
||||||
|
Iterator<String> iterator = list.iterator();
|
||||||
|
assertThat(iterator.next()).isEqualTo("foo");
|
||||||
|
assertThat(iterator.next()).isEqualTo("bar");
|
||||||
|
}
|
||||||
|
|
||||||
private void sizeOfArray() {
|
private void sizeOfArray() {
|
||||||
assertThat(new String[1].length).isLessThanOrEqualTo(1);
|
assertThat(new String[1].length).isLessThanOrEqualTo(1);
|
||||||
assertThat(new String[1]).hasSameSizeAs(new Object());
|
assertThat(new String[1]).hasSameSizeAs(new Object());
|
||||||
|
|||||||
+14
-11
@@ -17,16 +17,19 @@ internal class AssertThatGuavaOptionalInspectionTest : AbstractCajonTest() {
|
|||||||
runTest {
|
runTest {
|
||||||
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
|
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
|
||||||
myFixture.configureByFile("GuavaOptionalBefore.java")
|
myFixture.configureByFile("GuavaOptionalBefore.java")
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with isPresent()"), 2)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with Guava assertThat().isPresent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with isPresent()"), 2)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with Guava assertThat().isPresent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 3)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with isAbsent()"), 2)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with Guava assertThat().isPresent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 3)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with Guava assertThat().isAbsent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with isAbsent()"), 2)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isTrue() with isPresent()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with Guava assertThat().isAbsent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isFalse() with isAbsent()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with Guava assertThat().isAbsent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with contains()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isTrue() with Guava assertThat().isPresent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Remove unwrapping of expected expression and replace isEqualTo() with contains()"), 6)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isFalse() with Guava assertThat().isAbsent()"), 1)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with Guava assertThat().contains()"), 1)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Remove unwrapping of expected expression and replace isEqualTo() with contains()"), 4)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Remove unwrapping of expected expression and replace isEqualTo() with Guava assertThat().contains()"), 2)
|
||||||
myFixture.checkResultByFile("GuavaOptionalAfter.java")
|
myFixture.checkResultByFile("GuavaOptionalAfter.java")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +49,7 @@ internal class AssertThatGuavaOptionalInspectionTest : AbstractCajonTest() {
|
|||||||
runTest {
|
runTest {
|
||||||
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
|
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
|
||||||
myFixture.configureByFile("WithoutPriorGuavaImportBefore.java")
|
myFixture.configureByFile("WithoutPriorGuavaImportBefore.java")
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with Guava assertThat().isAbsent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex(".*eplace .* with .*"), 6)
|
executeQuickFixes(myFixture, Regex(".*eplace .* with .*"), 6)
|
||||||
myFixture.checkResultByFile("WithoutPriorGuavaImportAfter.java")
|
myFixture.checkResultByFile("WithoutPriorGuavaImportAfter.java")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -27,6 +27,7 @@ internal class AssertThatSizeInspectionTest : AbstractCajonTest() {
|
|||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isGreaterThanOrEqualTo() with hasSizeGreaterThanOrEqualTo()"), 4)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isGreaterThanOrEqualTo() with hasSizeGreaterThanOrEqualTo()"), 4)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThan() with hasSizeLessThan()"), 4)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThan() with hasSizeLessThan()"), 4)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThanOrEqualTo() with hasSizeLessThanOrEqualTo()"), 4)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThanOrEqualTo() with hasSizeLessThanOrEqualTo()"), 4)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Remove size determination of expected expression and replace hasSize() with hasSameSizeAs()"), 12)
|
||||||
myFixture.checkResultByFile("SizeAfter.java")
|
myFixture.checkResultByFile("SizeAfter.java")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package de.platon42.intellij.plugins.cajon.inspections
|
||||||
|
|
||||||
|
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
||||||
|
import de.platon42.intellij.jupiter.MyFixture
|
||||||
|
import de.platon42.intellij.jupiter.TestDataSubPath
|
||||||
|
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
internal class JoinAssertThatStatementsInspectionTest : AbstractCajonTest() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestDataSubPath("inspections/JoinStatements")
|
||||||
|
internal fun assertThat_size_of_array_or_collection_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.enableInspections(JoinAssertThatStatementsInspection::class.java)
|
||||||
|
myFixture.configureByFile("JoinStatementsBefore.java")
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Join assertThat() statements"), 6)
|
||||||
|
myFixture.checkResultByFile("JoinStatementsAfter.java")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class JoinStatements {
|
||||||
|
|
||||||
|
private void joinStatements() {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
// the future is always born in pain
|
||||||
|
/* tricky */
|
||||||
|
assertThat(list).as("foo").hasSize(2)
|
||||||
|
/* do another */
|
||||||
|
/* do one */.as("bar").contains("barbar")
|
||||||
|
// comment to keep
|
||||||
|
.doesNotContain("barbara") // another comment to keep
|
||||||
|
.doesNotContain("wrzlbrmpft")
|
||||||
|
/* and a multi line comment
|
||||||
|
after the statement */
|
||||||
|
// across two lines
|
||||||
|
.as("etc")/* what a nasty comment */.contains("etcetc")
|
||||||
|
// moar!
|
||||||
|
.doesNotContain("foobar");
|
||||||
|
|
||||||
|
assertThat("narf").isNotEqualTo("puit").as("bar").contains("barbar").as("foo").hasSize(2);
|
||||||
|
assertThat(list).as("evil").extracting(String::length).contains(2);
|
||||||
|
|
||||||
|
assertThat(list).as("bar").contains("barbar");
|
||||||
|
assertThat("narf").isNotEqualTo("puit").as("foo").hasSize(2);
|
||||||
|
if (true) {
|
||||||
|
assertThat(list).doesNotContain("narf").as("bar").contains("barbar");
|
||||||
|
}
|
||||||
|
assertThat(list.get(0)).isNotEmpty().hasSize(3).isEqualTo("bar");
|
||||||
|
|
||||||
|
assertThat(list.get(0) + "foo").isEqualTo("bar").doesNotStartWith("foo");
|
||||||
|
|
||||||
|
Iterator<String> iterator = list.iterator();
|
||||||
|
assertThat(iterator.next()).isEqualTo("foo");
|
||||||
|
assertThat(iterator.next()).isEqualTo("bar");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class JoinStatements {
|
||||||
|
|
||||||
|
private void joinStatements() {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
// the future is always born in pain
|
||||||
|
/* tricky */assertThat(list).as("foo").hasSize(2); /* do one */ /* do another */
|
||||||
|
assertThat(list).as("bar").contains("barbar"); // comment to keep
|
||||||
|
assertThat(list).doesNotContain("barbara") // another comment to keep
|
||||||
|
.doesNotContain("wrzlbrmpft") // across two lines
|
||||||
|
; /* and a multi line comment
|
||||||
|
after the statement */
|
||||||
|
assertThat(list).as("etc")/* what a nasty comment */.contains("etcetc");
|
||||||
|
|
||||||
|
// moar!
|
||||||
|
assertThat(list).doesNotContain("foobar");
|
||||||
|
|
||||||
|
assertThat("narf").isNotEqualTo("puit");
|
||||||
|
assertThat(list).as("bar").contains("barbar");
|
||||||
|
assertThat(list).as("foo").hasSize(2);
|
||||||
|
assertThat(list).as("evil").extracting(String::length).contains(2);
|
||||||
|
|
||||||
|
assertThat(list).as("bar").contains("barbar");
|
||||||
|
assertThat("narf").isNotEqualTo("puit");
|
||||||
|
assertThat(list).as("foo").hasSize(2);
|
||||||
|
if (true) {
|
||||||
|
assertThat(list).doesNotContain("narf");
|
||||||
|
assertThat(list).as("bar").contains("barbar");
|
||||||
|
}
|
||||||
|
assertThat(list.get(0)).isNotEmpty();
|
||||||
|
assertThat(list.get(0)).hasSize(3);
|
||||||
|
assertThat(list.get(0)).isEqualTo("bar");
|
||||||
|
|
||||||
|
assertThat(list.get(0) + "foo").isEqualTo("bar");
|
||||||
|
assertThat(list.get(0) + "foo").doesNotStartWith("foo");
|
||||||
|
|
||||||
|
Iterator<String> iterator = list.iterator();
|
||||||
|
assertThat(iterator.next()).isEqualTo("foo");
|
||||||
|
assertThat(iterator.next()).isEqualTo("bar");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,10 +24,14 @@ public class Size {
|
|||||||
assertThat(list).hasSize(string.length());
|
assertThat(list).hasSize(string.length());
|
||||||
assertThat(list).hasSize(stringBuilder.length());
|
assertThat(list).hasSize(stringBuilder.length());
|
||||||
assertThat(list).hasSize(1);
|
assertThat(list).hasSize(1);
|
||||||
assertThat(list).hasSizeGreaterThan(list.size() * 2);
|
assertThat(list).hasSizeGreaterThan(otherList.size() * 2);
|
||||||
assertThat(list).hasSizeGreaterThanOrEqualTo(list.size() * 2);
|
assertThat(list).hasSizeGreaterThanOrEqualTo(otherList.size() * 2);
|
||||||
assertThat(list).hasSizeLessThan(list.size() * 2);
|
assertThat(list).hasSizeLessThan(otherList.size() * 2);
|
||||||
assertThat(list).hasSizeLessThanOrEqualTo(list.size() * 2);
|
assertThat(list).hasSizeLessThanOrEqualTo(otherList.size() * 2);
|
||||||
|
assertThat(list).hasSameSizeAs(otherList);
|
||||||
|
assertThat(list).hasSameSizeAs(array);
|
||||||
|
assertThat(list).hasSize(string.length());
|
||||||
|
assertThat(list).hasSize(stringBuilder.length());
|
||||||
|
|
||||||
assertThat(array).isEmpty();
|
assertThat(array).isEmpty();
|
||||||
assertThat(array).isEmpty();
|
assertThat(array).isEmpty();
|
||||||
@@ -45,6 +49,10 @@ public class Size {
|
|||||||
assertThat(array).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
|
assertThat(array).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
|
||||||
assertThat(array).hasSizeLessThan(otherArray.length - 3);
|
assertThat(array).hasSizeLessThan(otherArray.length - 3);
|
||||||
assertThat(array).hasSizeLessThanOrEqualTo(1 - otherArray.length);
|
assertThat(array).hasSizeLessThanOrEqualTo(1 - otherArray.length);
|
||||||
|
assertThat(array).hasSameSizeAs(list);
|
||||||
|
assertThat(array).hasSameSizeAs(otherArray);
|
||||||
|
assertThat(array).hasSize(string.length());
|
||||||
|
assertThat(array).hasSize(stringBuilder.length());
|
||||||
|
|
||||||
assertThat(string).isEmpty();
|
assertThat(string).isEmpty();
|
||||||
assertThat(string).isEmpty();
|
assertThat(string).isEmpty();
|
||||||
@@ -62,6 +70,10 @@ public class Size {
|
|||||||
assertThat(string).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
|
assertThat(string).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
|
||||||
assertThat(string).hasSizeLessThan(otherArray.length - 3);
|
assertThat(string).hasSizeLessThan(otherArray.length - 3);
|
||||||
assertThat(string).hasSizeLessThanOrEqualTo(1 - otherArray.length);
|
assertThat(string).hasSizeLessThanOrEqualTo(1 - otherArray.length);
|
||||||
|
assertThat(string).hasSameSizeAs(otherList);
|
||||||
|
assertThat(string).hasSameSizeAs(array);
|
||||||
|
assertThat(string).hasSameSizeAs(string);
|
||||||
|
assertThat(string).hasSameSizeAs(stringBuilder);
|
||||||
|
|
||||||
assertThat(stringBuilder).isEmpty();
|
assertThat(stringBuilder).isEmpty();
|
||||||
assertThat(stringBuilder).isEmpty();
|
assertThat(stringBuilder).isEmpty();
|
||||||
@@ -79,5 +91,9 @@ public class Size {
|
|||||||
assertThat(stringBuilder).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
|
assertThat(stringBuilder).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
|
||||||
assertThat(stringBuilder).hasSizeLessThan(otherArray.length - 3);
|
assertThat(stringBuilder).hasSizeLessThan(otherArray.length - 3);
|
||||||
assertThat(stringBuilder).hasSizeLessThanOrEqualTo(1 - otherArray.length);
|
assertThat(stringBuilder).hasSizeLessThanOrEqualTo(1 - otherArray.length);
|
||||||
|
assertThat(stringBuilder).hasSameSizeAs(otherList);
|
||||||
|
assertThat(stringBuilder).hasSameSizeAs(array);
|
||||||
|
assertThat(stringBuilder).hasSameSizeAs(string);
|
||||||
|
assertThat(stringBuilder).hasSameSizeAs(stringBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,10 +24,14 @@ public class Size {
|
|||||||
assertThat(list.size()).isEqualTo(string.length());
|
assertThat(list.size()).isEqualTo(string.length());
|
||||||
assertThat(list.size()).isEqualTo(stringBuilder.length());
|
assertThat(list.size()).isEqualTo(stringBuilder.length());
|
||||||
assertThat(list.size()).isEqualTo(1);
|
assertThat(list.size()).isEqualTo(1);
|
||||||
assertThat(list.size()).isGreaterThan(list.size() * 2);
|
assertThat(list.size()).isGreaterThan(otherList.size() * 2);
|
||||||
assertThat(list.size()).isGreaterThanOrEqualTo(list.size() * 2);
|
assertThat(list.size()).isGreaterThanOrEqualTo(otherList.size() * 2);
|
||||||
assertThat(list.size()).isLessThan(list.size() * 2);
|
assertThat(list.size()).isLessThan(otherList.size() * 2);
|
||||||
assertThat(list.size()).isLessThanOrEqualTo(list.size() * 2);
|
assertThat(list.size()).isLessThanOrEqualTo(otherList.size() * 2);
|
||||||
|
assertThat(list).hasSize(otherList.size());
|
||||||
|
assertThat(list).hasSize(array.length);
|
||||||
|
assertThat(list).hasSize(string.length());
|
||||||
|
assertThat(list).hasSize(stringBuilder.length());
|
||||||
|
|
||||||
assertThat(array.length).isEqualTo(0);
|
assertThat(array.length).isEqualTo(0);
|
||||||
assertThat(array.length).isZero();
|
assertThat(array.length).isZero();
|
||||||
@@ -45,6 +49,10 @@ public class Size {
|
|||||||
assertThat(array.length).isGreaterThanOrEqualTo(otherArray.length + 1);
|
assertThat(array.length).isGreaterThanOrEqualTo(otherArray.length + 1);
|
||||||
assertThat(array.length).isLessThan(otherArray.length - 3);
|
assertThat(array.length).isLessThan(otherArray.length - 3);
|
||||||
assertThat(array.length).isLessThanOrEqualTo(1 - otherArray.length);
|
assertThat(array.length).isLessThanOrEqualTo(1 - otherArray.length);
|
||||||
|
assertThat(array).hasSize(list.size());
|
||||||
|
assertThat(array).hasSize(otherArray.length);
|
||||||
|
assertThat(array).hasSize(string.length());
|
||||||
|
assertThat(array).hasSize(stringBuilder.length());
|
||||||
|
|
||||||
assertThat(string.length()).isEqualTo(0);
|
assertThat(string.length()).isEqualTo(0);
|
||||||
assertThat(string.length()).isZero();
|
assertThat(string.length()).isZero();
|
||||||
@@ -62,6 +70,10 @@ public class Size {
|
|||||||
assertThat(string.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
|
assertThat(string.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
|
||||||
assertThat(string.length()).isLessThan(otherArray.length - 3);
|
assertThat(string.length()).isLessThan(otherArray.length - 3);
|
||||||
assertThat(string.length()).isLessThanOrEqualTo(1 - otherArray.length);
|
assertThat(string.length()).isLessThanOrEqualTo(1 - otherArray.length);
|
||||||
|
assertThat(string).hasSize(otherList.size());
|
||||||
|
assertThat(string).hasSize(array.length);
|
||||||
|
assertThat(string).hasSize(string.length());
|
||||||
|
assertThat(string).hasSize(stringBuilder.length());
|
||||||
|
|
||||||
assertThat(stringBuilder.length()).isEqualTo(0);
|
assertThat(stringBuilder.length()).isEqualTo(0);
|
||||||
assertThat(stringBuilder.length()).isZero();
|
assertThat(stringBuilder.length()).isZero();
|
||||||
@@ -79,5 +91,9 @@ public class Size {
|
|||||||
assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
|
assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
|
||||||
assertThat(stringBuilder.length()).isLessThan(otherArray.length - 3);
|
assertThat(stringBuilder.length()).isLessThan(otherArray.length - 3);
|
||||||
assertThat(stringBuilder.length()).isLessThanOrEqualTo(1 - otherArray.length);
|
assertThat(stringBuilder.length()).isLessThanOrEqualTo(1 - otherArray.length);
|
||||||
|
assertThat(stringBuilder).hasSize(otherList.size());
|
||||||
|
assertThat(stringBuilder).hasSize(array.length);
|
||||||
|
assertThat(stringBuilder).hasSize(string.length());
|
||||||
|
assertThat(stringBuilder).hasSize(stringBuilder.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user