diff --git a/README.md b/README.md index 74d7a6e..f938c5b 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,22 @@ The plugin also supports the conversion of the most common JUnit 4 assertions to to: assertThat(array).hasSameSizeAs(anotherArray); ``` + with AssertJ 13.2.0 or higher + + ``` + from: assertThat(array.length).isLessThanOrEqualTo(expression); + to: assertThat(array).hasSizeLessThanOrEqualTo(expression); + + from: assertThat(array.length).isLessThan(expression); + to: assertThat(array).hasSizeLessThan(expression); + + from: assertThat(array.length).isGreaterThan(expression); + to: assertThat(array).hasSizeGreaterThan(expression); + + from: assertThat(array.length).isGreaterThanOrEqualTo(expression); + to: assertThat(array).hasSizeGreaterThanOrEqualTo(expression); + ``` + and analogously for collections... - JUnitAssertToAssertJ @@ -107,6 +123,64 @@ The plugin also supports the conversion of the most common JUnit 4 assertions to assertArrayEquals(message, expectedDoubleOrFloatArray, actualDoubleOrFloatArray, delta); ``` +## Development notice + +Cajon is probably the only plugin that uses JUnit 5 Jupiter for unit testing so far (or at least the only one that I'm aware of ;) ). +The IntelliJ framework actually uses the JUnit 3 TestCase for plugin testing and I took me quite a while to make it work with JUnit 5. +Feel free to use the code (in package de.platon42.intellij.jupiter) for your projects (with attribution). + ## TODO +- AssertThatBinaryExpressionIsTrueOrFalse + ``` + from: assertThat(actual == expected).isTrue(); + to: assertThat(actual).isEqualTo(expected); (for primitive types) + to: assertThat(actual).isSameAs(expected); (for objects) + + from: assertThat(actual != expected).isFalse(); + to: assertThat(actual).isNotEqualTo(expected); (for primitive types) + to: assertThat(actual).isNotSameAs(expected); (for objects) + ``` +- AssertThatJava8OptionalContains + ``` + from: assertThat(Optional.of("foo").get()).isEqualTo("foo"); + to: assertThat(Optional.of("foo")).contains("foo"); + ``` +- AssertThatJava8OptionalIsPresentOrAbsent + ``` + from: assertThat(Optional.of("foo").isPresent()).isEqualTo(true); + from: assertThat(!Optional.of("foo").isPresent()).isEqualTo(false); + from: assertThat(Optional.of("foo").isPresent()).isTrue(); + from: assertThat(!Optional.of("foo").isPresent()).isFalse(); + to: assertThat(Optional.of("foo")).isPresent(); + + from: assertThat(Optional.of("foo").isPresent()).isEqualTo(false); + from: assertThat(!Optional.of("foo").isPresent()).isEqualTo(true); + from: assertThat(Optional.of("foo").isPresent()).isFalse(); + from: assertThat(!Optional.of("foo").isPresent()).isTrue(); + to: assertThat(Optional.of("foo")).isNotPresent(); + ``` - AssertThatGuavaOptionalContains -- extraction with property names to lambda with Java 8 \ No newline at end of file + ``` + from: assertThat(Optional.of("foo").get()).isEqualTo("foo"); + to: assertThat(Optional.of("foo")).contains("foo"); + ``` +- AssertThatGuavaOptionalIsPresentOrAbsent + ``` + from: assertThat(Optional.of("foo").isPresent()).isEqualTo(true); + from: assertThat(!Optional.of("foo").isPresent()).isEqualTo(false); + from: assertThat(Optional.of("foo").isPresent()).isTrue(); + from: assertThat(!Optional.of("foo").isPresent()).isFalse(); + to: assertThat(Optional.of("foo")).isPresent(); + + from: assertThat(Optional.of("foo").isPresent()).isEqualTo(false); + from: assertThat(!Optional.of("foo").isPresent()).isEqualTo(true); + from: assertThat(Optional.of("foo").isPresent()).isFalse(); + from: assertThat(!Optional.of("foo").isPresent()).isTrue(); + to: assertThat(Optional.of("foo")).isAbsent(); + ``` +- Referencing string properties inside extracting() +- Extraction with property names to lambda with Java 8 + ``` + from: assertThat(object).extracting("propOne", "propNoGetter", "propTwo.innerProp")... + to: assertThat(object).extracting(type::getPropOne, it -> it.propNoGetter, it -> it.getPropTwo().getInnerProp())... + ``` diff --git a/build.gradle b/build.gradle index 034885a..650a3b0 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group 'de.platon42' -version '0.2' +version '0.3' repositories { mavenCentral() @@ -18,7 +18,8 @@ repositories { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - testCompile "org.assertj:assertj-core:3.11.1" + testCompile "org.assertj:assertj-core:3.12.2" + testCompile "org.assertj:assertj-guava:3.2.1" testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0' testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.4.0' @@ -33,13 +34,19 @@ compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } intellij { - version '2018.3.4' + version '2019.1' // pluginName 'Concise AssertJ Optimizing Nitpicker (Cajon)' updateSinceUntilBuild false } patchPluginXml { changeNotes """ + <h4>V0.3 (xx-Apr-19)</h4> + <ul> + <li>Internally: Upgraded to AssertJ 13.2.2. + <li>Support for hasSizeLessThan(), hasSizeLessThanOrEqualTo(), hasSizeGreaterThanOrEqualTo(), and hasSizeGreaterThan() for AssertThatSizeInspection (with AssertJ >=13.2.0). + <li>Really fixed highlighting for JUnit conversion. Sorry. + </ul> <h4>V0.2 (01-Apr-19)</h4> <ul> <li>Fixed descriptions and quick fix texts. 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 e36f59d..7d561c7 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 @@ -2,10 +2,7 @@ package de.platon42.intellij.plugins.cajon.inspections import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool import com.intellij.codeInspection.ProblemsHolder -import com.intellij.psi.CommonClassNames -import com.intellij.psi.JavaPsiFacade -import com.intellij.psi.PsiCapturedWildcardType -import com.intellij.psi.PsiMethodCallExpression +import com.intellij.psi.* import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.PsiTypesUtil import com.siyeh.ig.callMatcher.CallMatcher @@ -133,4 +130,12 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { val constantEvaluationHelper = JavaPsiFacade.getInstance(expression.project).constantEvaluationHelper return constantEvaluationHelper.computeConstantExpression(valueExpression) } + + protected fun hasAssertJMethod(element: PsiElement, classAndMethod: String): Boolean { + val classname = "org.assertj.core.api.${classAndMethod.substringBeforeLast(".")}" + val findClass = + JavaPsiFacade.getInstance(element.project).findClass(classname, GlobalSearchScope.allScope(element.project)) + ?: return false + return findClass.findMethodsByName(classAndMethod.substringAfterLast(".")).isNotEmpty() + } } \ No newline at end of file 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 fd858dc..ae0e333 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 @@ -53,6 +53,19 @@ class AssertThatSizeInspection : AbstractAssertJInspection() { registerSizeMethod(holder, expression, expectedCallExpression, "isNotEmpty()", noExpectedExpression = true) return } + // new stuff in AssertJ 13.2.0 + if (hasAssertJMethod(expression, "AbstractIterableAssert.hasSizeLessThan")) { + val matchedMethod = listOf( + Pair(IS_GREATER_THAN_INT, "hasSizeGreaterThan()"), + Pair(IS_GREATER_THAN_OR_EQUAL_TO_INT, "hasSizeGreaterThanOrEqualTo()"), + Pair(IS_LESS_THAN_OR_EQUAL_TO_INT, "hasSizeLessThanOrEqualTo()"), + Pair(IS_LESS_THAN_INT, "hasSizeLessThan()") + ).find { it.first.test(expectedCallExpression) }?.second + if (matchedMethod != null) { + registerSizeMethod(holder, expression, expectedCallExpression, matchedMethod) + return + } + } } } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt index b3bbcb9..78c49cb 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt @@ -1,8 +1,6 @@ package de.platon42.intellij.plugins.cajon.inspections -import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemsHolder -import com.intellij.openapi.util.TextRange import com.intellij.psi.CommonClassNames import com.intellij.psi.JavaElementVisitor import com.intellij.psi.PsiElementVisitor @@ -147,8 +145,6 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { holder.registerProblem( expression, message, - ProblemHighlightType.INFORMATION, - null as TextRange?, ReplaceJUnitAssertMethodCallQuickFix(description, hasExpected, replacementMethod) ) } @@ -164,8 +160,6 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { holder.registerProblem( expression, message, - ProblemHighlightType.INFORMATION, - null as TextRange?, ReplaceJUnitDeltaAssertMethodCallQuickFix(description, replacementMethod) ) } diff --git a/src/test/java/de/platon42/intellij/jupiter/LightCodeInsightExtension.java b/src/test/java/de/platon42/intellij/jupiter/LightCodeInsightExtension.java index 9ef2dcb..66a67f6 100644 --- a/src/test/java/de/platon42/intellij/jupiter/LightCodeInsightExtension.java +++ b/src/test/java/de/platon42/intellij/jupiter/LightCodeInsightExtension.java @@ -131,7 +131,6 @@ public class LightCodeInsightExtension implements ParameterResolver, AfterTestEx VirtualFile jarFile = LocalFileSystem.getInstance().findFileByIoFile(jarPath.toFile()); myFixture.allowTreeAccessForFile(jarFile); PsiTestUtil.addLibrary( - myFixture.getModule(), model, jarPath.getFileName().toString().replace(".jar", ""), jarPath.getParent().toString(), diff --git a/src/test/java/de/platon42/intellij/playground/Playground.java b/src/test/java/de/platon42/intellij/playground/Playground.java index c93ab5a..fc5fcac 100644 --- a/src/test/java/de/platon42/intellij/playground/Playground.java +++ b/src/test/java/de/platon42/intellij/playground/Playground.java @@ -4,9 +4,11 @@ import org.assertj.core.api.ListAssert; import org.assertj.core.data.Offset; import java.util.ArrayList; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.data.Offset.offset; +import static org.assertj.guava.api.Assertions.assertThat; import static org.junit.Assert.*; public class Playground { @@ -27,6 +29,7 @@ public class Playground { assertThat(new ArrayList<String>().size()).isEqualTo(1); assertThat(new ArrayList<String>().size()).isGreaterThanOrEqualTo(1); assertThat(new ArrayList<String>().size()).isZero(); + assertThat(new ArrayList<String>()).hasSizeGreaterThan(1); assertThat(new ArrayList<String>()).hasSameSizeAs(new ArrayList<>()); assertThat(new Long[1]).as("etc").hasSameSizeAs(new Long[2]); } @@ -75,6 +78,30 @@ public class Playground { assertThat(foo).hasSize(0); } + private void java8Optional() { + Optional<String> foo = Optional.empty(); + assertThat(foo.get()).isEqualTo("bla"); + assertThat(foo).contains("bla"); + assertThat(foo.isPresent()).isTrue(); + assertThat(!foo.isPresent()).isFalse(); + assertThat(foo).isPresent(); + assertThat(foo.isPresent()).isFalse(); + assertThat(!foo.isPresent()).isTrue(); + assertThat(foo).isNotPresent(); + } + + private void guavaOptional() { + com.google.common.base.Optional<String> foo = com.google.common.base.Optional.absent(); + assertThat(foo.get()).isEqualTo("bla"); + assertThat(foo).contains("bla"); + assertThat(foo.isPresent()).isTrue(); + assertThat(!foo.isPresent()).isFalse(); + assertThat(foo).isPresent(); + assertThat(foo.isPresent()).isFalse(); + assertThat(!foo.isPresent()).isTrue(); + assertThat(foo).isAbsent(); + } + private void junitAssertions() { assertTrue(true); assertTrue("message", true); @@ -183,6 +210,8 @@ public class Playground { assertThat(new double[1]).as("array equals").containsExactly(new double[2], offset(1.0)); 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 Object()).extracting(Object::toString, Object::hashCode); } } 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 bb0b2a6..bf894dc 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 @@ -14,7 +14,7 @@ internal class AssertThatSizeInspectionTest : AbstractCajonTest() { runTest { myFixture.enableInspections(AssertThatSizeInspection::class.java) myFixture.configureByFile("AssertThatSizeBefore.java") - executeQuickFixes(myFixture, Regex("Replace .*"), 20) + executeQuickFixes(myFixture, Regex("Replace .*"), 28) myFixture.checkResultByFile("AssertThatSizeAfter.java") } } diff --git a/src/test/resources/inspections/AssertThatSize/AssertThatSizeAfter.java b/src/test/resources/inspections/AssertThatSize/AssertThatSizeAfter.java index e262639..ddabb49 100644 --- a/src/test/resources/inspections/AssertThatSize/AssertThatSizeAfter.java +++ b/src/test/resources/inspections/AssertThatSize/AssertThatSizeAfter.java @@ -2,7 +2,7 @@ import java.util.ArrayList; import static org.assertj.core.api.Assertions.assertThat; -public class assertThatSize { +public class AssertThatSize { private void assertThatSize() { ArrayList<String> list = new ArrayList<>(); @@ -20,6 +20,10 @@ public class assertThatSize { assertThat(list).hasSameSizeAs(otherList); assertThat(list).hasSameSizeAs(array); 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(array).isEmpty(); assertThat(array).isEmpty(); @@ -31,5 +35,9 @@ public class assertThatSize { assertThat(array).hasSameSizeAs(list); assertThat(array).hasSameSizeAs(otherArray); assertThat(array).hasSize(1); + assertThat(array).hasSizeGreaterThan(otherArray.length - 1); + assertThat(array).hasSizeGreaterThanOrEqualTo(otherArray.length + 1); + assertThat(array).hasSizeLessThan(otherArray.length - 3); + assertThat(array).hasSizeLessThanOrEqualTo(1 - otherArray.length); } } diff --git a/src/test/resources/inspections/AssertThatSize/AssertThatSizeBefore.java b/src/test/resources/inspections/AssertThatSize/AssertThatSizeBefore.java index f38046b..808169a 100644 --- a/src/test/resources/inspections/AssertThatSize/AssertThatSizeBefore.java +++ b/src/test/resources/inspections/AssertThatSize/AssertThatSizeBefore.java @@ -2,7 +2,7 @@ import java.util.ArrayList; import static org.assertj.core.api.Assertions.assertThat; -public class assertThatSize { +public class AssertThatSize { private void assertThatSize() { ArrayList<String> list = new ArrayList<>(); @@ -20,6 +20,10 @@ public class assertThatSize { assertThat(list.size()).isEqualTo(otherList.size()); assertThat(list.size()).isEqualTo(array.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(array.length).isEqualTo(0); assertThat(array.length).isZero(); @@ -31,5 +35,9 @@ public class assertThatSize { assertThat(array.length).isEqualTo(list.size()); assertThat(array.length).isEqualTo(otherArray.length); assertThat(array.length).isEqualTo(1); + assertThat(array.length).isGreaterThan(otherArray.length - 1); + assertThat(array.length).isGreaterThanOrEqualTo(otherArray.length + 1); + assertThat(array.length).isLessThan(otherArray.length - 3); + assertThat(array.length).isLessThanOrEqualTo(1 - otherArray.length); } }