diff --git a/README.md b/README.md index 93af54d..c34fbf1 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,9 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the from: assertThat(array.length).isEqualTo(anotherArray.length); to: assertThat(array).hasSameSizeAs(anotherArray); + + from: assertThat(array).hasSize(anotherArray.length); + to: assertThat(array).hasSameSizeAs(anotherArray); ``` and additionally with AssertJ 13.2.0 or later @@ -181,6 +184,9 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the from: assertThat("string".length()).isEqualTo(collection.size()) to: assertThat("string").hasSameSizeAs(collection); + + from: assertThat("string".length()).hasSize("strong".length()) + to: assertThat("string").hasSameSizeAs("strong"); ``` - AssertThatBinaryExpression @@ -330,6 +336,7 @@ Feel free to use the code (in package de.platon42.intellij.jupiter) for your pro #### V0.7 (unreleased) - Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions (really, Jetbrains, this sucks for no reason). +- Extended AssertThatSize inspection to transform ```hasSize()``` into ```hasSameSizeAs()```, if possible. #### V0.6 (22-Apr-19) - New AssertThatStringExpression inspection that will move ```isEmpty()```, ```equals()```, ```equalsIgnoreCase()```, ```contains()```, diff --git a/build.gradle b/build.gradle index cef0c0c..2823f93 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,7 @@ patchPluginXml {

V0.6 (22-Apr-19)

-

V0.5 (18-Apr-19)

-

Full changelog available at Github project site.

""" } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractAssertJInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractAssertJInspection.kt index 892dd5b..3e5cecb 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractAssertJInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractAssertJInspection.kt @@ -29,7 +29,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with %s()" const val REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE = "Remove unwrapping of expected expression and replace %s() with %s()" - const val REMOVE_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with %s()" + const val UNWRAP_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with %s()" val TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP = mapOf( JavaTokenType.EQEQ to MethodNames.IS_EQUAL_TO, @@ -219,7 +219,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { replacementMethod: String, quickFixSupplier: (String, String) -> LocalQuickFix ) { - registerConciseMethod(REMOVE_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier) + registerConciseMethod(UNWRAP_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier) } protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? { diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatGuavaOptionalInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatGuavaOptionalInspection.kt index ead9119..2ca223e 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatGuavaOptionalInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatGuavaOptionalInspection.kt @@ -39,7 +39,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() { 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, ::RemoveExpectedOutmostMethodCallQuickFix) + registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix) } else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) { registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT) } @@ -88,7 +88,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() { ) { registerConciseMethod(REMOVE_EXPECTED_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method -> QuickFixWithPostfixDelegate( - RemoveExpectedOutmostMethodCallQuickFix(desc, method), + UnwrapExpectedStaticMethodCallQuickFix(desc, method), ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT ) } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatJava8OptionalInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatJava8OptionalInspection.kt index 28c869f..5c3a788 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatJava8OptionalInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatJava8OptionalInspection.kt @@ -10,7 +10,7 @@ import de.platon42.intellij.plugins.cajon.findOutmostMethodCall import de.platon42.intellij.plugins.cajon.firstArg import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.quickfixes.RemoveActualOutmostMethodCallQuickFix -import de.platon42.intellij.plugins.cajon.quickfixes.RemoveExpectedOutmostMethodCallQuickFix +import de.platon42.intellij.plugins.cajon.quickfixes.UnwrapExpectedStaticMethodCallQuickFix class AssertThatJava8OptionalInspection : AbstractAssertJInspection() { @@ -33,7 +33,7 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() { if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) { val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return if (CallMatcher.anyOf(OPTIONAL_OF, OPTIONAL_OF_NULLABLE).test(innerExpectedCall)) { - registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix) + registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix) } else if (OPTIONAL_EMPTY.test(innerExpectedCall)) { registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_NOT_PRESENT) } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspection.kt index cfef00b..3357b24 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspection.kt @@ -2,17 +2,17 @@ package de.platon42.intellij.plugins.cajon.inspections import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.* +import com.intellij.psi.util.PsiTreeUtil +import de.platon42.intellij.plugins.cajon.* +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ITERABLE_ASSERT_CLASSNAME -import de.platon42.intellij.plugins.cajon.MethodNames -import de.platon42.intellij.plugins.cajon.findOutmostMethodCall -import de.platon42.intellij.plugins.cajon.firstArg -import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix class AssertThatSizeInspection : AbstractAssertJInspection() { companion object { private const val DISPLAY_NAME = "Asserting the size of an collection, array or string" + private const val REMOVE_SIZE_DESCRIPTION_TEMPLATE = "Remove size determination of expected expression and replace %s() with %s()" private val BONUS_EXPRESSIONS_CALL_MATCHER_MAP = listOf( IS_LESS_THAN_INT to MethodNames.HAS_SIZE_LESS_THAN, @@ -28,14 +28,29 @@ class AssertThatSizeInspection : AbstractAssertJInspection() { return object : JavaElementVisitor() { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { super.visitMethodCallExpression(expression) - if (!ASSERT_THAT_INT.test(expression)) { + val isAssertThatWithInt = ASSERT_THAT_INT.test(expression) + val isHasSize = HAS_SIZE.test(expression) + if (!(isAssertThatWithInt || isHasSize)) { return } val actualExpression = expression.firstArg val isForArrayOrCollection = isArrayLength(actualExpression) || isCollectionSize(actualExpression) val isForString = isCharSequenceLength(actualExpression) - if (isForArrayOrCollection || isForString) { + if (isHasSize && (isForArrayOrCollection + || (isForString && checkAssertedType(expression, ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME))) + ) { + val assertThatCall = PsiTreeUtil.findChildrenOfType(expression, PsiMethodCallExpression::class.java).find { CORE_ASSERT_THAT_MATCHER.test(it) } ?: return + registerConciseMethod( + REMOVE_SIZE_DESCRIPTION_TEMPLATE, + holder, + assertThatCall, + expression, + MethodNames.HAS_SAME_SIZE_AS + ) { desc, method -> + ReplaceSizeMethodCallQuickFix(desc, method, expectedIsCollection = true, keepActualAsIs = true) + } + } else if (isForArrayOrCollection || isForString) { val expectedCallExpression = expression.findOutmostMethodCall() ?: return val constValue = calculateConstantParameterValue(expectedCallExpression, 0) if (IS_EQUAL_TO_INT.test(expectedCallExpression)) { diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSizeMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSizeMethodCallQuickFix.kt index fe9968a..e986d58 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSizeMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSizeMethodCallQuickFix.kt @@ -11,14 +11,17 @@ class ReplaceSizeMethodCallQuickFix( description: String, private val replacementMethod: String, private val noExpectedExpression: Boolean = false, - private val expectedIsCollection: Boolean = false + private val expectedIsCollection: Boolean = false, + private val keepActualAsIs: Boolean = false ) : AbstractCommonQuickFix(description) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) { val element = descriptor.startElement val methodCallExpression = element as? PsiMethodCallExpression ?: return - val assertExpression = methodCallExpression.firstArg - replaceCollectionSizeOrArrayLength(assertExpression) + if (!keepActualAsIs) { + val assertExpression = methodCallExpression.firstArg + replaceCollectionSizeOrArrayLength(assertExpression) + } val oldExpectedExpression = element.findOutmostMethodCall() ?: return if (expectedIsCollection) { diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/RemoveExpectedOutmostMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/UnwrapExpectedStaticMethodCallQuickFix.kt similarity index 87% rename from src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/RemoveExpectedOutmostMethodCallQuickFix.kt rename to src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/UnwrapExpectedStaticMethodCallQuickFix.kt index 17022b6..9ac6f4f 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/RemoveExpectedOutmostMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/UnwrapExpectedStaticMethodCallQuickFix.kt @@ -8,7 +8,7 @@ import de.platon42.intellij.plugins.cajon.findOutmostMethodCall import de.platon42.intellij.plugins.cajon.firstArg import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall -class RemoveExpectedOutmostMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) { +class UnwrapExpectedStaticMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) { val element = descriptor.startElement diff --git a/src/test/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspectionTest.kt b/src/test/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspectionTest.kt index e8f13d0..5a1f8ba 100644 --- a/src/test/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspectionTest.kt +++ b/src/test/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspectionTest.kt @@ -27,6 +27,7 @@ internal class AssertThatSizeInspectionTest : AbstractCajonTest() { executeQuickFixes(myFixture, Regex.fromLiteral("Replace isGreaterThanOrEqualTo() with hasSizeGreaterThanOrEqualTo()"), 4) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThan() with hasSizeLessThan()"), 4) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThanOrEqualTo() with hasSizeLessThanOrEqualTo()"), 4) + executeQuickFixes(myFixture, Regex.fromLiteral("Remove size determination of expected expression and replace hasSize() with hasSameSizeAs()"), 12) myFixture.checkResultByFile("SizeAfter.java") } } diff --git a/src/test/resources/inspections/Size/SizeAfter.java b/src/test/resources/inspections/Size/SizeAfter.java index 18c5077..f807a52 100644 --- a/src/test/resources/inspections/Size/SizeAfter.java +++ b/src/test/resources/inspections/Size/SizeAfter.java @@ -24,10 +24,14 @@ public class Size { assertThat(list).hasSize(string.length()); assertThat(list).hasSize(stringBuilder.length()); assertThat(list).hasSize(1); - assertThat(list).hasSizeGreaterThan(list.size() * 2); - assertThat(list).hasSizeGreaterThanOrEqualTo(list.size() * 2); - assertThat(list).hasSizeLessThan(list.size() * 2); - assertThat(list).hasSizeLessThanOrEqualTo(list.size() * 2); + assertThat(list).hasSizeGreaterThan(otherList.size() * 2); + assertThat(list).hasSizeGreaterThanOrEqualTo(otherList.size() * 2); + assertThat(list).hasSizeLessThan(otherList.size() * 2); + assertThat(list).hasSizeLessThanOrEqualTo(otherList.size() * 2); + assertThat(list).hasSameSizeAs(otherList); + assertThat(list).hasSameSizeAs(array); + assertThat(list).hasSize(string.length()); + assertThat(list).hasSize(stringBuilder.length()); assertThat(array).isEmpty(); assertThat(array).isEmpty(); @@ -45,6 +49,10 @@ public class Size { assertThat(array).hasSizeGreaterThanOrEqualTo(otherArray.length + 1); assertThat(array).hasSizeLessThan(otherArray.length - 3); assertThat(array).hasSizeLessThanOrEqualTo(1 - otherArray.length); + assertThat(array).hasSameSizeAs(list); + assertThat(array).hasSameSizeAs(otherArray); + assertThat(array).hasSize(string.length()); + assertThat(array).hasSize(stringBuilder.length()); assertThat(string).isEmpty(); assertThat(string).isEmpty(); @@ -62,6 +70,10 @@ public class Size { assertThat(string).hasSizeGreaterThanOrEqualTo(otherArray.length + 1); assertThat(string).hasSizeLessThan(otherArray.length - 3); assertThat(string).hasSizeLessThanOrEqualTo(1 - otherArray.length); + assertThat(string).hasSameSizeAs(otherList); + assertThat(string).hasSameSizeAs(array); + assertThat(string).hasSameSizeAs(string); + assertThat(string).hasSameSizeAs(stringBuilder); assertThat(stringBuilder).isEmpty(); assertThat(stringBuilder).isEmpty(); @@ -79,5 +91,9 @@ public class Size { assertThat(stringBuilder).hasSizeGreaterThanOrEqualTo(otherArray.length + 1); assertThat(stringBuilder).hasSizeLessThan(otherArray.length - 3); assertThat(stringBuilder).hasSizeLessThanOrEqualTo(1 - otherArray.length); + assertThat(stringBuilder).hasSameSizeAs(otherList); + assertThat(stringBuilder).hasSameSizeAs(array); + assertThat(stringBuilder).hasSameSizeAs(string); + assertThat(stringBuilder).hasSameSizeAs(stringBuilder); } } diff --git a/src/test/resources/inspections/Size/SizeBefore.java b/src/test/resources/inspections/Size/SizeBefore.java index bc7ea07..af48da1 100644 --- a/src/test/resources/inspections/Size/SizeBefore.java +++ b/src/test/resources/inspections/Size/SizeBefore.java @@ -24,10 +24,14 @@ public class Size { assertThat(list.size()).isEqualTo(string.length()); assertThat(list.size()).isEqualTo(stringBuilder.length()); assertThat(list.size()).isEqualTo(1); - assertThat(list.size()).isGreaterThan(list.size() * 2); - assertThat(list.size()).isGreaterThanOrEqualTo(list.size() * 2); - assertThat(list.size()).isLessThan(list.size() * 2); - assertThat(list.size()).isLessThanOrEqualTo(list.size() * 2); + assertThat(list.size()).isGreaterThan(otherList.size() * 2); + assertThat(list.size()).isGreaterThanOrEqualTo(otherList.size() * 2); + assertThat(list.size()).isLessThan(otherList.size() * 2); + assertThat(list.size()).isLessThanOrEqualTo(otherList.size() * 2); + assertThat(list).hasSize(otherList.size()); + assertThat(list).hasSize(array.length); + assertThat(list).hasSize(string.length()); + assertThat(list).hasSize(stringBuilder.length()); assertThat(array.length).isEqualTo(0); assertThat(array.length).isZero(); @@ -45,6 +49,10 @@ public class Size { assertThat(array.length).isGreaterThanOrEqualTo(otherArray.length + 1); assertThat(array.length).isLessThan(otherArray.length - 3); assertThat(array.length).isLessThanOrEqualTo(1 - otherArray.length); + assertThat(array).hasSize(list.size()); + assertThat(array).hasSize(otherArray.length); + assertThat(array).hasSize(string.length()); + assertThat(array).hasSize(stringBuilder.length()); assertThat(string.length()).isEqualTo(0); assertThat(string.length()).isZero(); @@ -62,6 +70,10 @@ public class Size { assertThat(string.length()).isGreaterThanOrEqualTo(otherArray.length + 1); assertThat(string.length()).isLessThan(otherArray.length - 3); assertThat(string.length()).isLessThanOrEqualTo(1 - otherArray.length); + assertThat(string).hasSize(otherList.size()); + assertThat(string).hasSize(array.length); + assertThat(string).hasSize(string.length()); + assertThat(string).hasSize(stringBuilder.length()); assertThat(stringBuilder.length()).isEqualTo(0); assertThat(stringBuilder.length()).isZero(); @@ -79,5 +91,9 @@ public class Size { assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(otherArray.length + 1); assertThat(stringBuilder.length()).isLessThan(otherArray.length - 3); assertThat(stringBuilder.length()).isLessThanOrEqualTo(1 - otherArray.length); + assertThat(stringBuilder).hasSize(otherList.size()); + assertThat(stringBuilder).hasSize(array.length); + assertThat(stringBuilder).hasSize(string.length()); + assertThat(stringBuilder).hasSize(stringBuilder.length()); } }