Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f91fb3ccf | ||
|
|
b58d8cfd2f |
@@ -17,7 +17,7 @@ For example:
|
|||||||
assertThat(collection.size()).isEqualTo(5);
|
assertThat(collection.size()).isEqualTo(5);
|
||||||
```
|
```
|
||||||
|
|
||||||
If the collection has more or less than 5 elements, the assertion will fail, but will not
|
If the collection has more or less than five elements, the assertion will fail, but will not
|
||||||
tell you about the contents, making it hard to guess what went wrong.
|
tell you about the contents, making it hard to guess what went wrong.
|
||||||
|
|
||||||
Instead, if you wrote the same assertion the following way:
|
Instead, if you wrote the same assertion the following way:
|
||||||
@@ -26,12 +26,24 @@ Instead, if you wrote the same assertion the following way:
|
|||||||
assertThat(collection).hasSize(5);
|
assertThat(collection).hasSize(5);
|
||||||
```
|
```
|
||||||
|
|
||||||
Then AssertJ would tell you the contents of the collection on failure.
|
Then AssertJ would tell you the _actual contents_ of the collection on failure.
|
||||||
|
|
||||||
## Conversion of JUnit assertions to AssertJ
|
## Conversion of JUnit assertions to AssertJ
|
||||||
|
|
||||||
The plugin also supports the conversion of the most common JUnit 4 assertions to AssertJ.
|
The plugin also supports the conversion of the most common JUnit 4 assertions to AssertJ.
|
||||||
|
|
||||||
|
## Lookup and refactoring of string-based extracting()
|
||||||
|
|
||||||
|
AssertJ allows [extracting POJO fields/properties on iterables/arrays](http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#extracted-properties-assertion).
|
||||||
|
|
||||||
|
Using strings is not safe for refactoring (and before Java 8 Lambdas were available,
|
||||||
|
creating extractor functions just for testing purpose was a bit too tedious).
|
||||||
|
|
||||||
|
This plugin adds support for referencing these fields (so you can ctrl(/cmd)-click on the
|
||||||
|
string to go to the definition) and also allows safe refactoring on the
|
||||||
|
fields (refactoring a getter method without a corresponding field will not work
|
||||||
|
correctly right now).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The plugin will report inspections in your opened editor file as warnings.
|
The plugin will report inspections in your opened editor file as warnings.
|
||||||
@@ -103,7 +115,6 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
|
|||||||
from: assertThat(array.length).isGreaterThanOrEqualTo(expression);
|
from: assertThat(array.length).isGreaterThanOrEqualTo(expression);
|
||||||
to: assertThat(array).hasSizeGreaterThanOrEqualTo(expression);
|
to: assertThat(array).hasSizeGreaterThanOrEqualTo(expression);
|
||||||
```
|
```
|
||||||
|
|
||||||
and analogously for collections...
|
and analogously for collections...
|
||||||
|
|
||||||
- AssertThatBinaryExpressionIsTrueOrFalse
|
- AssertThatBinaryExpressionIsTrueOrFalse
|
||||||
@@ -120,7 +131,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
|
|||||||
from: assertThat(null == objActual).isFalse();
|
from: assertThat(null == objActual).isFalse();
|
||||||
to: assertThat(objActual).isNotNull();
|
to: assertThat(objActual).isNotNull();
|
||||||
```
|
```
|
||||||
and many, many more combinations (more than 150).
|
...and many, many more combinations (more than 150).
|
||||||
|
|
||||||
- AssertThatJava8Optional
|
- AssertThatJava8Optional
|
||||||
```
|
```
|
||||||
@@ -207,6 +218,23 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
|
|||||||
|
|
||||||
AssertJ for Guava needs to be available in the classpath.
|
AssertJ for Guava needs to be available in the classpath.
|
||||||
|
|
||||||
|
### Implemented referencing
|
||||||
|
|
||||||
|
```
|
||||||
|
.extracting("field")
|
||||||
|
.extracting("outerfield.fieldInsideObjectTypeOfOuterfield.andSoOn")
|
||||||
|
.extracting("property") // where the class has a getProperty() (or isProperty() for boolean) method
|
||||||
|
.extracting("bareMethod") // supported with AssertJ 13.12.0
|
||||||
|
.extracting(Extractors.byName("fieldOrPropertyOrBareMethod")
|
||||||
|
.extracting(Extractors.byName("fieldOrPropertyOrBareMethod.orAPathLikeAbove")
|
||||||
|
.extracting(Extractors.resultOf("bareMethod")
|
||||||
|
.extractingResultOf("bareMethod")
|
||||||
|
.flatExtracting("fieldOrPropertyOrBareMethod.orAPathLikeAbove")
|
||||||
|
.flatExtracting(Extractors.byName("fieldOrPropertyOrBareMethod.orAPathLikeAbove")
|
||||||
|
.flatExtracting(Extractors.resultOf("bareMethod")
|
||||||
|
```
|
||||||
|
Works on both POJOs and ```Iterable```s/```Array```s.
|
||||||
|
|
||||||
## Development notice
|
## Development notice
|
||||||
|
|
||||||
Cajon is written in Kotlin 1.3.
|
Cajon is written in Kotlin 1.3.
|
||||||
@@ -218,7 +246,20 @@ Feel free to use the code (in package de.platon42.intellij.jupiter) for your pro
|
|||||||
## TODO
|
## TODO
|
||||||
- AssertThatNegatedBooleanExpression
|
- AssertThatNegatedBooleanExpression
|
||||||
- AssertThatInstanceOf
|
- AssertThatInstanceOf
|
||||||
- Referencing string properties inside extracting()
|
- AssertThatStringOps
|
||||||
|
```
|
||||||
|
from: assertThat(string.contains(foobar)).isTrue();
|
||||||
|
to: assertThat(string).contains(foobar);
|
||||||
|
from: assertThat(string.startsWith(foobar)).isTrue();
|
||||||
|
to: assertThat(string).startsWith(foobar);
|
||||||
|
from: assertThat(string.endsWith(foobar)).isTrue();
|
||||||
|
to: assertThat(string).endsWith(foobar);
|
||||||
|
from: assertThat(string.equalsIgnoreCase(foobar)).isTrue();
|
||||||
|
to: assertThat(string).isEqualToIgnoringCase(foobar);
|
||||||
|
```
|
||||||
|
Analogously with ```isFalse()```.
|
||||||
|
|
||||||
|
- AssumeInsteadOfReturn
|
||||||
- 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")...
|
||||||
@@ -228,16 +269,24 @@ 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). Minimal version is now 2017.3.
|
||||||
|
- Fixed missing Guava imports (if not already present) for AssertThatGuavaInspection. This was a major PITA to get right.
|
||||||
|
- 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).
|
||||||
|
- 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.
|
||||||
|
|
||||||
#### 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.
|
||||||
- New inspection AssertThatGuavaOptional that operates on Guava Optional objects and tries to use contains(), isPresent(), and isAbsent() instead.
|
- New inspection AssertThatGuavaOptional that operates on Guava ```Optional``` objects and tries to use ```contains()```, ```isPresent()```, and ```isAbsent()``` instead.
|
||||||
- Added support in AssertThatBinaryExpressionIsTrueOrFalse for is(Not)EqualTo(Boolean.TRUE/FALSE).
|
- Added support in AssertThatBinaryExpressionIsTrueOrFalse for ```is(Not)EqualTo(Boolean.TRUE/FALSE)```.
|
||||||
|
|
||||||
#### V0.3 (07-Apr-19)
|
#### V0.3 (07-Apr-19)
|
||||||
- New inspection AssertThatBinaryExpressionIsTrueOrFalse that will find and fix common binary expressions and equals() statements (more than 150 combinations) inside assertThat().
|
- New inspection AssertThatBinaryExpressionIsTrueOrFalse that will find and fix common binary expressions and ```equals()``` statements (more than 150 combinations) inside ```assertThat()```.
|
||||||
- Merged AssertThatObjectIsNull and AssertThatObjectIsNotNull to AssertThatObjectIsNullOrNotNull.
|
- Merged AssertThatObjectIsNull and AssertThatObjectIsNotNull to AssertThatObjectIsNullOrNotNull.
|
||||||
- Support for hasSizeLessThan(), hasSizeLessThanOrEqualTo(), hasSizeGreaterThanOrEqualTo(), and hasSizeGreaterThan() for AssertThatSizeInspection (with AssertJ >=13.2.0).
|
- Support for ```hasSizeLessThan()```, ```hasSizeLessThanOrEqualTo()```, ```hasSizeGreaterThanOrEqualTo()```, and ```hasSizeGreaterThan()``` for AssertThatSizeInspection (with AssertJ >=13.2.0).
|
||||||
- Really fixed highlighting for JUnit conversion. Sorry.
|
- Really fixed highlighting for JUnit conversion. Sorry.
|
||||||
|
|
||||||
#### V0.2 (01-Apr-19)
|
#### V0.2 (01-Apr-19)
|
||||||
|
|||||||
+11
-3
@@ -5,7 +5,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group 'de.platon42'
|
group 'de.platon42'
|
||||||
version '0.4'
|
version '0.5'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -22,9 +22,8 @@ dependencies {
|
|||||||
testCompile "org.assertj:assertj-guava:3.2.1"
|
testCompile "org.assertj:assertj-guava:3.2.1"
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0'
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0'
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0'
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0'
|
||||||
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.4.0'
|
|
||||||
testImplementation "org.jetbrains.kotlin:kotlin-test"
|
testImplementation "org.jetbrains.kotlin:kotlin-test"
|
||||||
testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
|
// testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
@@ -41,6 +40,15 @@ intellij {
|
|||||||
|
|
||||||
patchPluginXml {
|
patchPluginXml {
|
||||||
changeNotes """
|
changeNotes """
|
||||||
|
<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>
|
||||||
<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.
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -23,6 +25,8 @@ class AssertJClassNames {
|
|||||||
const val ABSTRACT_ITERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIterableAssert"
|
const val ABSTRACT_ITERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIterableAssert"
|
||||||
@NonNls
|
@NonNls
|
||||||
const val ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.EnumerableAssert"
|
const val ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.EnumerableAssert"
|
||||||
|
@NonNls
|
||||||
|
const val EXTRACTORS_CLASSNAME = "org.assertj.core.extractor.Extractors"
|
||||||
|
|
||||||
@NonNls
|
@NonNls
|
||||||
const val GUAVA_OPTIONAL_CLASSNAME = "com.google.common.base.Optional"
|
const val GUAVA_OPTIONAL_CLASSNAME = "com.google.common.base.Optional"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
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
|
||||||
|
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 {
|
||||||
|
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
|
||||||
|
}
|
||||||
+35
-16
@@ -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() {
|
||||||
@@ -29,6 +28,8 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
|||||||
const val MORE_CONCISE_MESSAGE_TEMPLATE = "%s() would be more concise than %s()"
|
const val MORE_CONCISE_MESSAGE_TEMPLATE = "%s() would be more concise than %s()"
|
||||||
|
|
||||||
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 = "Unwrap expected expression and replace %s() with %s()"
|
||||||
|
const val REMOVE_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,
|
||||||
@@ -174,31 +175,49 @@ 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
|
registerConciseMethod(REPLACE_DESCRIPTION_TEMPLATE, oldExpectedCallExpression, replacementMethod, quickFixSupplier, holder, expression)
|
||||||
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
|
}
|
||||||
|
|
||||||
|
private fun registerConciseMethod(
|
||||||
|
descriptionTemplate: String,
|
||||||
|
oldExpectedCallExpression: PsiMethodCallExpression,
|
||||||
|
replacementMethod: String,
|
||||||
|
quickFixSupplier: (String, String) -> LocalQuickFix,
|
||||||
|
holder: ProblemsHolder,
|
||||||
|
expression: PsiMethodCallExpression
|
||||||
|
) {
|
||||||
|
val originalMethod = getOriginalMethodName(oldExpectedCallExpression) ?: return
|
||||||
|
val description = descriptionTemplate.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)
|
holder.registerProblem(expression, message, quickfix)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun registerRemoveExpectedOutmostMethod(
|
protected fun registerRemoveExpectedOutmostMethod(
|
||||||
holder: ProblemsHolder,
|
holder: ProblemsHolder,
|
||||||
expression: PsiMethodCallExpression,
|
expression: PsiMethodCallExpression,
|
||||||
expectedCallExpression: PsiMethodCallExpression,
|
oldExpectedCallExpression: PsiMethodCallExpression,
|
||||||
replacementMethod: String
|
replacementMethod: String,
|
||||||
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
) {
|
) {
|
||||||
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return
|
registerConciseMethod(REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE, oldExpectedCallExpression, replacementMethod, quickFixSupplier, holder, expression)
|
||||||
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
|
}
|
||||||
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
|
|
||||||
val quickfix = RemoveExpectedOutmostMethodCallQuickFix(description, replacementMethod)
|
protected fun registerRemoveActualOutmostMethod(
|
||||||
holder.registerProblem(expression, message, quickfix)
|
holder: ProblemsHolder,
|
||||||
|
expression: PsiMethodCallExpression,
|
||||||
|
oldExpectedCallExpression: PsiMethodCallExpression,
|
||||||
|
replacementMethod: String,
|
||||||
|
quickFixSupplier: (String, String) -> LocalQuickFix
|
||||||
|
) {
|
||||||
|
registerConciseMethod(REMOVE_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE, oldExpectedCallExpression, replacementMethod, quickFixSupplier, holder, expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? {
|
protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? {
|
||||||
@@ -239,6 +258,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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+15
-16
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+69
-20
@@ -1,13 +1,14 @@
|
|||||||
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 com.siyeh.ig.callMatcher.CallMatcher
|
||||||
import de.platon42.intellij.plugins.cajon.AssertJClassNames
|
import de.platon42.intellij.plugins.cajon.*
|
||||||
import de.platon42.intellij.plugins.cajon.MethodNames
|
import de.platon42.intellij.plugins.cajon.quickfixes.*
|
||||||
import de.platon42.intellij.plugins.cajon.firstArg
|
|
||||||
import de.platon42.intellij.plugins.cajon.map
|
|
||||||
|
|
||||||
class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
||||||
|
|
||||||
@@ -27,35 +28,83 @@ 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 (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
|
||||||
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
|
registerRemoveExpectedOutmostMethod(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 (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
|
||||||
|
registerRemoveExpectedOutmostMethod(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
|
||||||
|
) {
|
||||||
|
registerRemoveActualOutmostMethod(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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+16
-9
@@ -4,11 +4,13 @@ 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.siyeh.ig.callMatcher.CallMatcher
|
||||||
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 +27,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 (CallMatcher.anyOf(OPTIONAL_OF, OPTIONAL_OF_NULLABLE).test(innerExpectedCall)) {
|
||||||
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
|
registerRemoveExpectedOutmostMethod(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 +48,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)
|
registerRemoveActualOutmostMethod(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)
|
registerRemoveActualOutmostMethod(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)
|
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, replacementMethod) { desc, method ->
|
||||||
|
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-23
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+43
-55
@@ -1,10 +1,12 @@
|
|||||||
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
|
||||||
import com.siyeh.ig.callMatcher.CallMatcher
|
import com.siyeh.ig.callMatcher.CallMatcher
|
||||||
import com.siyeh.ig.callMatcher.CallMatcher.anyOf
|
import com.siyeh.ig.callMatcher.CallMatcher.anyOf
|
||||||
|
import com.siyeh.ig.callMatcher.CallMatcher.staticCall
|
||||||
import de.platon42.intellij.plugins.cajon.AssertJClassNames
|
import de.platon42.intellij.plugins.cajon.AssertJClassNames
|
||||||
import de.platon42.intellij.plugins.cajon.MethodNames
|
import de.platon42.intellij.plugins.cajon.MethodNames
|
||||||
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitAssertMethodCallQuickFix
|
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitAssertMethodCallQuickFix
|
||||||
@@ -18,91 +20,91 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
|
|||||||
private val MAPPINGS = listOf(
|
private val MAPPINGS = listOf(
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes("boolean")
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes("boolean")
|
||||||
),
|
),
|
||||||
MethodNames.IS_TRUE, false
|
MethodNames.IS_TRUE, false
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes("boolean")
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes("boolean")
|
||||||
),
|
),
|
||||||
MethodNames.IS_FALSE, false
|
MethodNames.IS_FALSE, false
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)
|
||||||
),
|
),
|
||||||
MethodNames.IS_NULL, false
|
MethodNames.IS_NULL, false
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)
|
||||||
),
|
),
|
||||||
MethodNames.IS_NOT_NULL, false
|
MethodNames.IS_NOT_NULL, false
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("double", "double", "double"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("double", "double", "double"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("float", "float", "float")
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("float", "float", "float")
|
||||||
),
|
),
|
||||||
MethodNames.IS_CLOSE_TO, hasDelta = true
|
MethodNames.IS_CLOSE_TO, hasDelta = true
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2)
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2)
|
||||||
),
|
),
|
||||||
MethodNames.IS_EQUAL_TO
|
MethodNames.IS_EQUAL_TO
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("double", "double", "double"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("double", "double", "double"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("float", "float", "float")
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("float", "float", "float")
|
||||||
),
|
),
|
||||||
MethodNames.IS_NOT_CLOSE_TO, hasDelta = true
|
MethodNames.IS_NOT_CLOSE_TO, hasDelta = true
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2)
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2)
|
||||||
),
|
),
|
||||||
MethodNames.IS_NOT_EQUAL_TO
|
MethodNames.IS_NOT_EQUAL_TO
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2)
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2)
|
||||||
),
|
),
|
||||||
MethodNames.IS_SAME_AS
|
MethodNames.IS_SAME_AS
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2)
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2)
|
||||||
),
|
),
|
||||||
MethodNames.IS_NOT_SAME_AS
|
MethodNames.IS_NOT_SAME_AS
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double[]", "double[]", "double"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double[]", "double[]", "double"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("double[]", "double[]", "double"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("double[]", "double[]", "double"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float[]", "float[]", "float"),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float[]", "float[]", "float"),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("float[]", "float[]", "float")
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("float[]", "float[]", "float")
|
||||||
),
|
),
|
||||||
MethodNames.CONTAINS_EXACTLY, hasDelta = true
|
MethodNames.CONTAINS_EXACTLY, hasDelta = true
|
||||||
),
|
),
|
||||||
Mapping(
|
Mapping(
|
||||||
anyOf(
|
anyOf(
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2),
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2),
|
||||||
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3)
|
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3)
|
||||||
),
|
),
|
||||||
MethodNames.CONTAINS_EXACTLY
|
MethodNames.CONTAINS_EXACTLY
|
||||||
)
|
)
|
||||||
@@ -121,43 +123,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(
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
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 de.platon42.intellij.plugins.cajon.*
|
||||||
|
|
||||||
|
class ForGuavaPostFix {
|
||||||
|
companion object {
|
||||||
|
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 assertThatCall = PsiTreeUtil.findChildrenOfType(statement, PsiMethodCallExpression::class.java).find { CORE_ASSERT_THAT_MATCHER.test(it) } ?: return@exit
|
||||||
|
|
||||||
|
val newMethodCall = createGuavaAssertThat(element, assertThatCall.firstArg)
|
||||||
|
newMethodCall.resolveMethod()?.addAsStaticImport(element, AssertJClassNames.ASSERTIONS_CLASSNAME)
|
||||||
|
val parentCall = PsiTreeUtil.getParentOfType(assertThatCall, PsiMethodCallExpression::class.java) ?: return@exit
|
||||||
|
parentCall.replaceQualifier(newMethodCall)
|
||||||
|
parentCall.shortenAndReformat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-17
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-10
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-29
@@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+9
-33
@@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-6
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-19
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-16
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-14
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
package de.platon42.intellij.plugins.cajon.references
|
||||||
|
|
||||||
|
import com.intellij.lang.jvm.JvmModifier
|
||||||
|
import com.intellij.openapi.util.TextRange
|
||||||
|
import com.intellij.patterns.PlatformPatterns
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.util.PropertyUtilBase
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import com.intellij.psi.util.PsiTypesUtil
|
||||||
|
import com.intellij.util.ProcessingContext
|
||||||
|
import com.siyeh.ig.callMatcher.CallMatcher
|
||||||
|
import de.platon42.intellij.plugins.cajon.AssertJClassNames
|
||||||
|
import de.platon42.intellij.plugins.cajon.CORE_ASSERT_THAT_MATCHER
|
||||||
|
import de.platon42.intellij.plugins.cajon.firstArg
|
||||||
|
|
||||||
|
class ExtractorReferenceContributor : PsiReferenceContributor() {
|
||||||
|
|
||||||
|
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 RESULT_OF = CallMatcher.staticCall(AssertJClassNames.EXTRACTORS_CLASSNAME, "resultOf")
|
||||||
|
.parameterTypes(CommonClassNames.JAVA_LANG_STRING)!!
|
||||||
|
|
||||||
|
private val propertyOrFieldReferenceProvider = PropertyOrFieldReferenceProvider()
|
||||||
|
private val iterablePropertyOrFieldReferenceProvider = IterablePropertyOrFieldReferenceProvider()
|
||||||
|
private val iterableResultOfReferenceProvider = IterableResultOfReferenceProvider()
|
||||||
|
|
||||||
|
private fun lookupFieldOrProperty(containingClass: PsiClass, path: String, startOffset: Int): List<Pair<TextRange, List<PsiElement>>> {
|
||||||
|
val partName = path.substring(startOffset).substringBefore(".")
|
||||||
|
val nextOffset = startOffset + partName.length + 1
|
||||||
|
|
||||||
|
val matchedGetter = PropertyUtilBase.findPropertyGetter(containingClass, partName, false, true)
|
||||||
|
val fieldResult = PropertyUtilBase.findPropertyField(containingClass, partName, false)
|
||||||
|
val textRange = TextRange(startOffset + 1, nextOffset)
|
||||||
|
val matchedBareMethod = containingClass.allMethods.find { (it.name == partName) && !it.hasModifier(JvmModifier.STATIC) }
|
||||||
|
val targets = listOfNotNull<PsiElement>(fieldResult, matchedGetter, matchedBareMethod)
|
||||||
|
if (targets.isNotEmpty()) {
|
||||||
|
val results = listOf(textRange to targets)
|
||||||
|
if (nextOffset >= path.length) {
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
val nextClass = PsiTypesUtil.getPsiClass(matchedGetter?.returnType ?: fieldResult?.type) ?: return results
|
||||||
|
return listOf(results, lookupFieldOrProperty(nextClass, path, nextOffset)).flatten()
|
||||||
|
}
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lookupMethod(containingClass: PsiClass, methodName: String): List<Pair<TextRange, List<PsiElement>>>? {
|
||||||
|
val matchedMethod = containingClass.allMethods.find { (it.name == methodName) && !it.hasModifier(JvmModifier.STATIC) } ?: return null
|
||||||
|
val textRange = TextRange(1, methodName.length + 1)
|
||||||
|
return listOf(textRange to listOf(matchedMethod))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findActualType(element: PsiElement): PsiClassType? {
|
||||||
|
val assertThatCall = PsiTreeUtil.findChildrenOfType(element, PsiMethodCallExpression::class.java)
|
||||||
|
.find { CORE_ASSERT_THAT_MATCHER.test(it) } ?: return null
|
||||||
|
return assertThatCall.firstArg.type as? PsiClassType
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findAndCreateReferences(element: PsiElement, finder: (PsiLiteralExpression) -> List<Pair<TextRange, List<PsiElement>>>?): Array<PsiReference> {
|
||||||
|
val literal = element as PsiLiteralExpression
|
||||||
|
val results = finder(literal)
|
||||||
|
if (results != null) {
|
||||||
|
return results.map { ExtractorReference(literal, it.first, it.second) }.toTypedArray()
|
||||||
|
}
|
||||||
|
return PsiReference.EMPTY_ARRAY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
|
||||||
|
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression::class.java), propertyOrFieldReferenceProvider)
|
||||||
|
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression::class.java), iterablePropertyOrFieldReferenceProvider)
|
||||||
|
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression::class.java), iterableResultOfReferenceProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExtractorReference(literal: PsiLiteralExpression, range: TextRange, private val targets: List<PsiElement>) :
|
||||||
|
PsiPolyVariantReferenceBase<PsiLiteralExpression>(literal, range, true) {
|
||||||
|
|
||||||
|
override fun resolve(): PsiElement? {
|
||||||
|
return multiResolve(false).map(ResolveResult::getElement).firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> {
|
||||||
|
return PsiElementResolveResult.createResults(targets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PropertyOrFieldReferenceProvider : PsiReferenceProvider() {
|
||||||
|
|
||||||
|
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
||||||
|
return findAndCreateReferences(element, ::findReferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findReferences(element: PsiLiteralExpression): List<Pair<TextRange, List<PsiElement>>>? {
|
||||||
|
val literal = element.value as? String ?: return null
|
||||||
|
var methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression::class.java) ?: return null
|
||||||
|
var isResultOf = false
|
||||||
|
if (BY_NAME.test(methodCallExpression)) {
|
||||||
|
methodCallExpression = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return null
|
||||||
|
} else if (RESULT_OF.test(methodCallExpression)) {
|
||||||
|
methodCallExpression = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return null
|
||||||
|
isResultOf = true
|
||||||
|
}
|
||||||
|
if (!EXTRACTING_FROM_OBJECT.test(methodCallExpression)) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
val containingClass = PsiTypesUtil.getPsiClass(findActualType(methodCallExpression)) ?: return null
|
||||||
|
return if (isResultOf) lookupMethod(containingClass, literal) else lookupFieldOrProperty(containingClass, literal, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IterablePropertyOrFieldReferenceProvider : PsiReferenceProvider() {
|
||||||
|
|
||||||
|
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
||||||
|
return findAndCreateReferences(element, ::findReferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findReferences(element: PsiLiteralExpression): List<Pair<TextRange, List<PsiElement>>>? {
|
||||||
|
val literal = element.value as? String ?: return null
|
||||||
|
var methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression::class.java) ?: return null
|
||||||
|
var isResultOf = false
|
||||||
|
if (BY_NAME.test(methodCallExpression)) {
|
||||||
|
methodCallExpression = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return null
|
||||||
|
} else if (RESULT_OF.test(methodCallExpression)) {
|
||||||
|
methodCallExpression = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return null
|
||||||
|
isResultOf = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CallMatcher.anyOf(EXTRACTING_FROM_ITERABLE, FLAT_EXTRACTING_FROM_ITERABLE).test(methodCallExpression)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val iterableType = findActualType(methodCallExpression) ?: return null
|
||||||
|
val innerType = iterableType.resolveGenerics().substitutor.substitute(iterableType.parameters[0])
|
||||||
|
val containingClass = PsiTypesUtil.getPsiClass(innerType) ?: return null
|
||||||
|
return if (isResultOf) lookupMethod(containingClass, literal) else lookupFieldOrProperty(containingClass, literal, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IterableResultOfReferenceProvider : PsiReferenceProvider() {
|
||||||
|
|
||||||
|
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
|
||||||
|
return findAndCreateReferences(element, ::findReferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findReferences(element: PsiLiteralExpression): List<Pair<TextRange, List<PsiElement>>>? {
|
||||||
|
val literal = element.value as? String ?: return null
|
||||||
|
val methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression::class.java) ?: return null
|
||||||
|
if (!EXTRACTING_RESULT_OF_FROM_ITERABLE.test(methodCallExpression)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val iterableType = findActualType(methodCallExpression) ?: return null
|
||||||
|
val innerType = iterableType.resolveGenerics().substitutor.substitute(iterableType.parameters[0])
|
||||||
|
val containingClass = PsiTypesUtil.getPsiClass(innerType) ?: return null
|
||||||
|
return lookupMethod(containingClass, literal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,10 +7,11 @@
|
|||||||
Cajon is an IntelliJ IDEA Plugin for shortening and optimizing AssertJ assertions.
|
Cajon is an IntelliJ IDEA Plugin for shortening and optimizing AssertJ assertions.
|
||||||
It adds inspections and quick fixes to fully make use of the AssertJ methods
|
It adds inspections and quick fixes to fully make use of the AssertJ methods
|
||||||
to make the intention clear and concise. It can also convert JUnit 4 assertions to AssertJ.
|
to make the intention clear and concise. It can also convert JUnit 4 assertions to AssertJ.
|
||||||
|
It supports referencing inside extracting()-methods with strings, adding refactoring safety.
|
||||||
]]></description>
|
]]></description>
|
||||||
|
|
||||||
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
|
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
|
||||||
<idea-version since-build="172.0"/>
|
<idea-version since-build="173.2290.1"/>
|
||||||
|
|
||||||
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
|
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
|
||||||
on how to target different products -->
|
on how to target different products -->
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
<depends>com.intellij.modules.java</depends>
|
<depends>com.intellij.modules.java</depends>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<psi.referenceContributor implementation="de.platon42.intellij.plugins.cajon.references.ExtractorReferenceContributor"/>
|
||||||
<localInspection groupPath="Java" shortName="AssertThatObjectIsNullOrNotNull" enabledByDefault="true" level="WARNING"
|
<localInspection groupPath="Java" shortName="AssertThatObjectIsNullOrNotNull" enabledByDefault="true" level="WARNING"
|
||||||
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatObjectIsNullOrNotNullInspection"/>
|
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatObjectIsNullOrNotNullInspection"/>
|
||||||
<localInspection groupPath="Java" shortName="AssertThatBooleanIsTrueOrFalse" enabledByDefault="true" level="WARNING"
|
<localInspection groupPath="Java" shortName="AssertThatBooleanIsTrueOrFalse" enabledByDefault="true" level="WARNING"
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ package de.platon42.intellij.playground;
|
|||||||
|
|
||||||
import org.assertj.core.api.ListAssert;
|
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 java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -122,10 +125,27 @@ public class Playground {
|
|||||||
assertThat(!false).isTrue();
|
assertThat(!false).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stringIsEmpty() {
|
private void stringStuff() {
|
||||||
String foo = "bar";
|
String foo = "bar";
|
||||||
assertThat(foo).isEqualTo("");
|
assertThat(foo).isEqualTo("");
|
||||||
assertThat(foo).hasSize(0);
|
assertThat(foo).hasSize(0);
|
||||||
|
assertThat(foo.contains("foobar")).isTrue();
|
||||||
|
assertThat(foo).contains("foobar");
|
||||||
|
assertThat(foo.startsWith("foobar")).isTrue();
|
||||||
|
assertThat(foo).startsWith("foobar");
|
||||||
|
assertThat(foo.endsWith("foobar")).isTrue();
|
||||||
|
assertThat(foo).endsWith("foobar");
|
||||||
|
assertThat(foo.equalsIgnoreCase("foo")).isTrue();
|
||||||
|
assertThat(foo).isEqualToIgnoringCase("foo");
|
||||||
|
|
||||||
|
assertThat(foo.contains("foobar")).isFalse();
|
||||||
|
assertThat(foo).doesNotContain("foobar");
|
||||||
|
assertThat(foo.startsWith("foobar")).isFalse();
|
||||||
|
assertThat(foo).doesNotStartWith("foobar");
|
||||||
|
assertThat(foo.endsWith("foobar")).isFalse();
|
||||||
|
assertThat(foo).doesNotEndWith("foobar");
|
||||||
|
assertThat(foo.equalsIgnoreCase("foo")).isFalse();
|
||||||
|
assertThat(foo).isNotEqualToIgnoringCase("foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void java8Optional() {
|
private void java8Optional() {
|
||||||
@@ -291,6 +311,60 @@ public class Playground {
|
|||||||
assertThat(new float[1]).containsExactly(new float[2], offset(1.0f));
|
assertThat(new float[1]).containsExactly(new float[2], offset(1.0f));
|
||||||
assertThat(new float[1]).as("array equals").containsExactly(new float[2], offset(1.0f));
|
assertThat(new float[1]).as("array equals").containsExactly(new float[2], offset(1.0f));
|
||||||
|
|
||||||
|
assertThat(new Object()).extracting("toString");
|
||||||
assertThat(new Object()).extracting(Object::toString, Object::hashCode);
|
assertThat(new Object()).extracting(Object::toString, Object::hashCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
Contact contact = new Contact();
|
||||||
|
List<Contact> contactList = Collections.emptyList();
|
||||||
|
|
||||||
|
assertThat(contact).extracting("name").isEqualTo("foo");
|
||||||
|
assertThat(contact).extracting("age", "country", "address.street", "street", "address.noMailings", "address.REALLYnoMAILINGS").containsExactly(1, "Elmst. 42");
|
||||||
|
assertThat(contact).extracting(Extractors.byName("name")).isEqualTo("foo");
|
||||||
|
assertThat(contact).extracting(Extractors.resultOf("getStreet")).isEqualTo("foo");
|
||||||
|
assertThat(contact).extracting(Extractors.resultOf("getStreet"), Extractors.byName("narf")).isEqualTo("foo");
|
||||||
|
|
||||||
|
assertThat(contactList).extracting("name").isEqualTo("foo");
|
||||||
|
assertThat(contactList).extracting("name", "moar").isEqualTo("foo");
|
||||||
|
assertThat(contactList).extracting("name", String.class).isEqualTo("foo");
|
||||||
|
assertThat(contactList).extracting(Extractors.byName("name")).isEqualTo("foo");
|
||||||
|
assertThat(contactList).extracting(Extractors.resultOf("getStreet"), Extractors.byName("narf")).isEqualTo("foo");
|
||||||
|
assertThat(contactList).extractingResultOf("getStreet").isEqualTo("foo");
|
||||||
|
assertThat(contactList).extractingResultOf("getStreet", String.class).isEqualTo("foo");
|
||||||
|
assertThat(contactList).flatExtracting("age", "address.street", "street").containsExactly(1, "Elmst. 42");
|
||||||
|
assertThat(contactList).flatExtracting("age").containsExactly(1, "Elmst. 42");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Contact {
|
||||||
|
private String name;
|
||||||
|
private Integer age;
|
||||||
|
private Address address;
|
||||||
|
|
||||||
|
public String getStreet() {
|
||||||
|
return address.getStreet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Address {
|
||||||
|
private String street;
|
||||||
|
private String country;
|
||||||
|
|
||||||
|
public String getStreet() {
|
||||||
|
return street;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCountry() {
|
||||||
|
return country;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNoMailings() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getREALLYnoMAILINGS() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException
|
|||||||
@AddLocalJarToModule(Assertions::class)
|
@AddLocalJarToModule(Assertions::class)
|
||||||
abstract class AbstractCajonTest {
|
abstract class AbstractCajonTest {
|
||||||
|
|
||||||
// See https://github.com/junit-team/junit5/issues/157
|
// See https://github.com/junit-team/junit5/issues/157, should be resolved with junit5 5.5 M2
|
||||||
protected fun runTest(body: () -> Unit) {
|
protected fun runTest(body: () -> Unit) {
|
||||||
val throwables = arrayOfNulls<Throwable>(1)
|
val throwables = arrayOfNulls<Throwable>(1)
|
||||||
|
|
||||||
|
|||||||
+30
-6
@@ -9,22 +9,46 @@ import org.assertj.core.api.Assertions
|
|||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
@AddLocalJarToModule(com.google.common.base.Optional::class, org.assertj.guava.api.Assertions::class, Assertions::class)
|
@AddLocalJarToModule(com.google.common.base.Optional::class, org.assertj.guava.api.Assertions::class, Assertions::class)
|
||||||
|
@TestDataSubPath("inspections/AssertThatGuavaOptional")
|
||||||
internal class AssertThatGuavaOptionalInspectionTest : AbstractCajonTest() {
|
internal class AssertThatGuavaOptionalInspectionTest : AbstractCajonTest() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestDataSubPath("inspections/AssertThatGuavaOptional")
|
|
||||||
internal fun assertThat_get_or_isPresent_for_Guava_Optional_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
internal fun assertThat_get_or_isPresent_for_Guava_Optional_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
runTest {
|
runTest {
|
||||||
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("Unwrap actual expression and replace isEqualTo() with isPresent()"), 2)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with isPresent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 3)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 3)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with isAbsent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 3)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 3)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isAbsent()"), 2)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with isAbsent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isTrue() with isPresent()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isTrue() with isPresent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isFalse() with isAbsent()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isFalse() with isAbsent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with contains()"), 3)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with contains()"), 1)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap expected expression and replace isEqualTo() with contains()"), 6)
|
||||||
myFixture.checkResultByFile("AssertThatGuavaOptionalAfter.java")
|
myFixture.checkResultByFile("AssertThatGuavaOptionalAfter.java")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun adds_missing_Guava_import_any_order(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
|
||||||
|
myFixture.configureByFile("WithoutPriorGuavaImportBefore.java")
|
||||||
|
executeQuickFixes(myFixture, Regex(".*eplace .* with .*"), 7)
|
||||||
|
myFixture.checkResultByFile("WithoutPriorGuavaImportAfter.java")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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(".*eplace .* with .*"), 6)
|
||||||
|
myFixture.checkResultByFile("WithoutPriorGuavaImportAfter.java")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+11
-8
@@ -14,14 +14,17 @@ internal class AssertThatJava8OptionalInspectionTest : AbstractCajonTest() {
|
|||||||
runTest {
|
runTest {
|
||||||
myFixture.enableInspections(AssertThatJava8OptionalInspection::class.java)
|
myFixture.enableInspections(AssertThatJava8OptionalInspection::class.java)
|
||||||
myFixture.configureByFile("AssertThatJava8OptionalBefore.java")
|
myFixture.configureByFile("AssertThatJava8OptionalBefore.java")
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isPresent()"), 2)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with isPresent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 3)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with isPresent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isNotPresent()"), 3)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with isNotPresent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isNotPresent()"), 2)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with isNotPresent()"), 2)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isTrue() with isPresent()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isTrue() with isPresent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isFalse() with isNotPresent()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isNotPresent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with contains()"), 3)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 1)
|
||||||
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isSameAs() with containsSame()"), 1)
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isFalse() with isNotPresent()"), 1)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap expected expression and replace isEqualTo() with contains()"), 2)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with contains()"), 1)
|
||||||
|
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isSameAs() with containsSame()"), 1)
|
||||||
myFixture.checkResultByFile("AssertThatJava8OptionalAfter.java")
|
myFixture.checkResultByFile("AssertThatJava8OptionalAfter.java")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
package de.platon42.intellij.plugins.cajon.references
|
||||||
|
|
||||||
|
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.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
|
||||||
|
@TestDataSubPath("references")
|
||||||
|
internal class ExtractorReferenceContributorTest : AbstractCajonTest() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_for_field_extracting(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference1.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).isEqualTo("private String name;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_for_first_part_of_a_path(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference2.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).isEqualTo("protected Address address;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_for_second_part_of_a_path_and_both_getter_and_field(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference3.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).startsWith("private String street;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_on_a_bare_method_call(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference4.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).startsWith("public Boolean getREALLYnoMAILINGS()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_with_only_Getter_on_second_part(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference5.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).startsWith("public boolean isNoMailings()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_using_byName_extractor(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference6.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).isEqualTo("private String name;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_using_resultOf_extractor(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference7.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).startsWith("public String getStreetName()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_for_field_extraction_on_list(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference8.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).isEqualTo("private String name;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_for_field_flat_extraction_of_path_on_list(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference9.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).startsWith("private String street;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun extractor_is_able_to_find_reference_for_extraction_on_result_of_method(@MyFixture myFixture: JavaCodeInsightTestFixture) {
|
||||||
|
runTest {
|
||||||
|
myFixture.configureByFiles("FindReference10.java", "Address.java", "Contact.java")
|
||||||
|
assertThat(myFixture.elementAtCaret.text).startsWith("public String getStreetName()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
public class Address {
|
||||||
|
private String street;
|
||||||
|
private String country;
|
||||||
|
|
||||||
|
private String getStreet() {
|
||||||
|
return street;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCountry() {
|
||||||
|
return country;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNoMailings() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getREALLYnoMAILINGS() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
public class Contact {
|
||||||
|
private String name;
|
||||||
|
public Integer age;
|
||||||
|
protected Address address;
|
||||||
|
public String getStreetName()
|
||||||
|
{
|
||||||
|
return address.getStreet();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference1 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
Contact contact = new Contact();
|
||||||
|
|
||||||
|
assertThat(contact).extracting("name<caret>").isEqualTo("foo");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference10 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
List<Contact> contactList = Collections.emptyList();
|
||||||
|
|
||||||
|
assertThat(contactList).extractingResultOf("getStreetName<caret>").isEqualTo("foo");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference2 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
Contact contact = new Contact();
|
||||||
|
|
||||||
|
assertThat(contact).extracting("address<caret>.street", "streetName").containsExactly(1, "Elmst. 42");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference3 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
Contact contact = new Contact();
|
||||||
|
|
||||||
|
assertThat(contact).extracting("address.street<caret>", "address.REALLYnoMAILINGS").containsExactly(1, "Elmst. 42");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference4 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
Contact contact = new Contact();
|
||||||
|
|
||||||
|
assertThat(contact).extracting("address.getREALLYnoMAILINGS<caret>", "address.country").containsExactly(1, "Elmst. 42");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference5 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
Contact contact = new Contact();
|
||||||
|
|
||||||
|
assertThat(contact).extracting("address.noMailings<caret>").containsExactly(1, "Elmst. 42");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference6 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
Contact contact = new Contact();
|
||||||
|
|
||||||
|
assertThat(contact).extracting(Extractors.byName("name<caret>")).isEqualTo("foo");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference7 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
Contact contact = new Contact();
|
||||||
|
|
||||||
|
assertThat(contact).extracting(Extractors.resultOf("getStreetName<caret>")).isEqualTo("foo");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference8 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
List<Contact> contactList = Collections.emptyList();
|
||||||
|
|
||||||
|
assertThat(contactList).extracting("name<caret>").isEqualTo("foo");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import org.assertj.core.extractor.Extractors;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FindReference9 {
|
||||||
|
|
||||||
|
private void findReferences() {
|
||||||
|
List<Contact> contactList = Collections.emptyList();
|
||||||
|
|
||||||
|
assertThat(contactList).flatExtracting("age", "address.street<caret>", "streetName").containsExactly(1, "Elmst. 42");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user