diff --git a/.travis.yml b/.travis.yml
index eedc000..ebc3f32 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,5 @@
language: java
jdk:
- - oraclejdk8
- openjdk8
before_script:
diff --git a/README.md b/README.md
index b72b8fa..1abbe5f 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,9 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
## Implemented inspections and quickfixes
- JoinAssertThatStatements
+
+ Joins multiple ```assertThat()``` statements with same actual expression together.
+
```
from: assertThat(expected).someCondition();
assertThat(expected).anotherCondition();
@@ -82,8 +85,11 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
except for method calls with known side-effect methods such as ```Iterator.next()``` -- please notify me about others.
The comments of the statements will be preserved. When using ```.extracting()``` or similar, the statements will not be merged.
-
+
- AssertThatObjectIsNullOrNotNull
+
+ Uses ```isNull()``` and ```isNotNull()``` instead.
+
```
from: assertThat(object).isEqualTo(null);
to: assertThat(object).isNull();
@@ -93,12 +99,18 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
```
- AssertThatBooleanCondition
+
+ Uses ```isTrue()``` and ```isFalse()``` instead.
+
```
from: assertThat(booleanValue).isEqualTo(true/false/Boolean.TRUE/Boolean.FALSE);
to: assertThat(booleanValue).isTrue()/isFalse();
```
- AssertThatInvertedBooleanCondition
+
+ Inverts the boolean condition to make it more readable.
+
```
from: assertThat(!booleanValue).isEqualTo(true/false/Boolean.TRUE/Boolean.FALSE);
from: assertThat(!booleanValue).isTrue()/isFalse();
@@ -106,6 +118,9 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
```
- AssertThatInstanceOf
+
+ Moves ```instanceof``` expressions out of ```assertThat()```.
+
```
from: assertThat(object instanceof classname).isEqualTo(true);
from: assertThat(object instanceof classname).isTrue();
@@ -117,13 +132,21 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
```
- AssertThatStringIsEmpty
+
+ Uses ```isEmpty()``` for empty string assertions.
+
```
from: assertThat(charSequence/string).isEqualTo("");
from: assertThat(charSequence/string).hasSize(0);
to: assertThat(charSequence/string).isEmpty();
```
+ The ```assertThat(string.length()).isEqualTo(0);``` case is handled in the AssertThatSize inspection.
+
- AssertThatStringExpression
+
+ Moves string operations inside assertThat() out.
+
```
from: assertThat(stringActual.isEmpty()).isTrue();
to: assertThat(stringActual).isEmpty();
@@ -147,12 +170,19 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
Analogously with ```isFalse()```.
- AssertThatEnumerableIsEmpty
+
+ Uses ```isEmpty()``` for ```hasSize(0)``` iterable assertions instead.
+
```
from: assertThat(enumerable).hasSize(0);
to: assertThat(enumerable).isEmpty();
```
- AssertThatSize
+
+ Makes assertions on sizes of arrays, collections, strings,
+ or ```CharSequence```s more concise.
+
```
from: assertThat(array.length).isEqualTo(0);
from: assertThat(array.length).isLessThanOrEqualTo(0);
@@ -201,6 +231,9 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
```
- AssertThatBinaryExpression
+
+ Splits a boolean condition represented by binary expression out of ```assertThat()```.
+
```
from: assertThat(primActual == primExpected).isTrue();
to: assertThat(primActual).isEqualTo(primExpected);
@@ -220,6 +253,11 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
...and many, many more combinations (more than 150).
- AssertThatJava8Optional
+
+ Examines the statement for Java 8 Optional type and whether the statement
+ effectively tries to assert the presence, absence or content and then
+ replaces the statement by better assertions.
+
```
from: assertThat(opt.isPresent()).isEqualTo(true);
from: assertThat(opt.isPresent()).isNotEqualTo(false);
@@ -249,6 +287,11 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
```
- AssertThatGuavaOptional
+
+ Examines the statement for Google Guava Optional type and whether the statement
+ effectively tries to assert the presence, absence or content and then
+ replaces the statement by better assertions.
+
```
from: assertThat(opt.isPresent()).isEqualTo(true);
from: assertThat(opt.isPresent()).isNotEqualTo(false);
@@ -276,7 +319,54 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
AssertJ for Guava needs to be available in the classpath.
+- AssumeThatInsteadOfReturn
+
+ Tries to detect bogus uses of return statements in test methods and replaces them by ```assumeThat()``` calls.
+
+ Novices will use these to skip test execution by bailing out early on some preconditions not met.
+ However, this suggests that the test has actually been run and passed instead of showing the test
+ as being skipped.
+
+ Return statements in ```if``` statements in main test methods (must be annotated with JUnit 4 or
+ Jupiter @Test annotations) will be verified to have at least one ```assertThat()``` statement in the code flow.
+ Method calls within the same class will be examined for ```assertThat()``` statements, too.
+ However, at most 50 statements and down to five recursions will be tolerated before giving up.
+
+ Currently, the quickfix may lose some comments during operation. The other branch of the ```if``` statement
+ will be inlined (blocks with declarations will remain a code block due to variable scope).
+
+ The generated ```assumeThat()``` statement could be optimized further (similar to ```assertThat()```).
+
+ Example:
+
+ ```
+ @Test
+ public void check_fuel_emission() {
+ if (System.getProperty("manufacturer").equals("Volkswagen")) {
+ return;
+ }
+ double nitroxppm = doWltpDrivingCycle();
+ assertThat(nitroxppm).isLessThan(500.0);
+ }
+ ```
+ will be transformed to
+ ```
+ @Test
+ public void check_fuel_emission() {
+ assumeThat(System.getProperty("manufacturer").equals("Volkswagen")).isFalse();
+ double nitroxppm = doWltpDrivingCycle();
+ assertThat(nitroxppm).isLessThan(500.0);
+ }
+ ```
+
- JUnitAssertToAssertJ
+
+ Tries to convert most of the JUnit 4 assertions to AssertJ format.
+
+ Does not support Hamcrest-Matchers.
+ If you need that kind of conversion, you might want to check out the
+ [Assertions2AssertJ plugin](https://plugins.jetbrains.com/plugin/10345-assertions2assertj) by Ric Emery.
+
```
assertTrue(condition);
assertTrue(message, condition);
@@ -332,7 +422,6 @@ The IntelliJ framework actually uses the JUnit 3 TestCase for plugin testing and
Feel free to use the code (in package de.platon42.intellij.jupiter) for your projects (with attribution).
## Planned features
-- AssumeThatInsteadOfReturn
- Extraction with property names to lambda with Java 8
```
from: assertThat(object).extracting("propOne", "propNoGetter", "propTwo.innerProp")...
@@ -343,7 +432,7 @@ Feel free to use the code (in package de.platon42.intellij.jupiter) for your pro
## Changelog
-#### V0.8 (unreleased)
+#### V0.8 (05-May-19)
- Fixed missing description for JoinAssertThatStatements and detection of equivalent expressions (sorry, released it too hastily).
- Fixed ```isEmpty()``` for enumerables and strings and ```isNull()``` for object conversions to be applied only if it is the terminal method call as ```isEmpty()``` and ```isNull()``` return void.
- Heavily reworked inspections for edge cases, such as multiple ```isEqualTo()``` calls inside a single statement.
@@ -351,6 +440,7 @@ Feel free to use the code (in package de.platon42.intellij.jupiter) for your pro
- Corrected highlighting for many inspections.
- Fixed family names for inspections in batch mode.
- Reworded many inspection messages for better understanding.
+- Added a first version of a new inspection that tries to detect bogus uses of return statements in test methods and replaces them by ```assumeThat()``` calls.
#### V0.7 (28-Apr-19)
- Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions
diff --git a/build.gradle b/build.gradle
index 34c7cde..54f59ec 100644
--- a/build.gradle
+++ b/build.gradle
@@ -42,7 +42,7 @@ intellij {
patchPluginXml {
changeNotes """
-
V0.8 (unreleased)
+ V0.8 (05-May-19)
- Fixed missing description for JoinAssertThatStatements and detection of equivalent expressions (sorry, released it too hastily).
- Fixed isEmpty() for enumerables and strings and isNull() for object conversions to be applied only if it is the terminal method call as isEmpty() and isNull() return void.
@@ -51,6 +51,7 @@ patchPluginXml {
- Corrected highlighting for many inspections.
- Fixed family names for inspections in batch mode.
- Reworded many inspection messages for better understanding.
+
- Added a first version of a new inspection that tries to detect bogus uses of return statements in test methods and replaces them by assumeThat() calls.
V0.7 (28-Apr-19)
diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/AssertJClassNames.kt b/src/main/java/de/platon42/intellij/plugins/cajon/AssertJClassNames.kt
index c6ab1e3..3d7b125 100644
--- a/src/main/java/de/platon42/intellij/plugins/cajon/AssertJClassNames.kt
+++ b/src/main/java/de/platon42/intellij/plugins/cajon/AssertJClassNames.kt
@@ -7,6 +7,9 @@ class AssertJClassNames {
@NonNls
const val ASSERTIONS_CLASSNAME = "org.assertj.core.api.Assertions"
+ @NonNls
+ const val ASSUMPTIONS_CLASSNAME = "org.assertj.core.api.Assumptions"
+
@NonNls
const val DESCRIPTABLE_INTERFACE = "org.assertj.core.api.Descriptable"
@NonNls
diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/Extensions.kt b/src/main/java/de/platon42/intellij/plugins/cajon/Extensions.kt
index b8834be..20f7b01 100644
--- a/src/main/java/de/platon42/intellij/plugins/cajon/Extensions.kt
+++ b/src/main/java/de/platon42/intellij/plugins/cajon/Extensions.kt
@@ -12,7 +12,10 @@ import de.platon42.intellij.plugins.cajon.inspections.AbstractAssertJInspection
val PsiMethodCallExpression.qualifierExpression: PsiExpression get() = methodExpression.qualifierExpression!!
val PsiMethodCallExpression.firstArg: PsiExpression get() = getArg(0)
-fun PsiElement.hasAssertThat() = text.contains("assertThat")
+fun PsiElement.hasAssertThat(): Boolean {
+ val elementText = text
+ return elementText.startsWith("${MethodNames.ASSERT_THAT}(") || elementText.contains(".${MethodNames.ASSERT_THAT}(")
+}
fun PsiMethodCallExpression.replaceQualifier(qualifier: PsiElement) {
qualifierExpression.replace(qualifier)
diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/MethodNames.kt b/src/main/java/de/platon42/intellij/plugins/cajon/MethodNames.kt
index e03dfd2..37c9269 100644
--- a/src/main/java/de/platon42/intellij/plugins/cajon/MethodNames.kt
+++ b/src/main/java/de/platon42/intellij/plugins/cajon/MethodNames.kt
@@ -12,6 +12,9 @@ class MethodNames {
@NonNls
const val ASSERT_THAT = "assertThat"
+ @NonNls
+ const val ASSUME_THAT = "assumeThat"
+
@NonNls
const val AS = "as"
@NonNls
diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssumeThatInsteadOfReturnInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssumeThatInsteadOfReturnInspection.kt
new file mode 100644
index 0000000..0d45c04
--- /dev/null
+++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssumeThatInsteadOfReturnInspection.kt
@@ -0,0 +1,146 @@
+package de.platon42.intellij.plugins.cajon.inspections
+
+import com.intellij.codeInspection.ProblemHighlightType
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.psi.*
+import de.platon42.intellij.plugins.cajon.hasAssertThat
+import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceIfByAssumeThatQuickFix
+
+class AssumeThatInsteadOfReturnInspection : AbstractAssertJInspection() {
+
+ companion object {
+ private const val DISPLAY_NAME = "Replace conditional test exits by assumeThat() statements with same actual expression"
+ private const val REPLACE_RETURN_BY_ASSUME_THAT_DESCRIPTION = "Conditional return should probably be an assumeThat() statement instead"
+
+ private const val MAX_RECURSION_DEPTH = 5
+ private const val MAX_STATEMENTS_COUNT = 50
+
+ private val TEST_ANNOTATIONS = listOf(
+ "org.junit.Test",
+ "org.junit.jupiter.api.Test",
+ "org.junit.jupiter.api.TestTemplate",
+ "org.junit.jupiter.api.params.ParameterizedTest"
+ )
+
+ private fun hasEmptyReturn(statement: PsiStatement): Boolean {
+ return when (statement) {
+ is PsiBlockStatement -> {
+ val psiReturnStatement = (statement.firstChild as? PsiCodeBlock)?.statements?.singleOrNull() as? PsiReturnStatement
+ (psiReturnStatement != null) && (psiReturnStatement.returnValue == null)
+ }
+ is PsiReturnStatement -> statement.returnValue == null
+ else -> false
+ }
+ }
+
+ private fun registerProblem(holder: ProblemsHolder, isOnTheFly: Boolean, statement: PsiStatement, removeElse: Boolean) {
+ val problemDescriptor = holder.manager.createProblemDescriptor(
+ statement,
+ statement,
+ REPLACE_RETURN_BY_ASSUME_THAT_DESCRIPTION,
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ isOnTheFly,
+ ReplaceIfByAssumeThatQuickFix(removeElse)
+ )
+ holder.registerProblem(problemDescriptor)
+ }
+ }
+
+ override fun getDisplayName() = DISPLAY_NAME
+
+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
+ return object : JavaElementVisitor() {
+ override fun visitMethod(method: PsiMethod) {
+ super.visitMethod(method)
+ if (TEST_ANNOTATIONS.none(method::hasAnnotation)) {
+ return
+ }
+ val containingClass = method.containingClass ?: return
+ val visitor: PsiElementVisitor = TestMethodVisitor(holder, isOnTheFly, containingClass)
+ method.accept(visitor)
+ }
+ }
+ }
+
+ class TestMethodVisitor(
+ private val holder: ProblemsHolder,
+ private val isOnTheFly: Boolean,
+ private val containingClass: PsiClass
+ ) : JavaRecursiveElementWalkingVisitor() {
+
+ private var contSearch = true
+
+ override fun visitExpressionStatement(statement: PsiExpressionStatement) {
+ if (contSearch) {
+ val methodCallExpression = statement.expression as? PsiMethodCallExpression
+ if (methodCallExpression != null) {
+ if (methodCallExpression.hasAssertThat()) {
+ contSearch = false
+ } else {
+ val method = methodCallExpression.resolveMethod()
+ if (method?.containingClass == containingClass) {
+ val recursionVisitor = CheckForAssertThatCallsVisitor(containingClass, 1)
+ method.accept(recursionVisitor)
+ if (recursionVisitor.aborted || recursionVisitor.foundAssertThat) {
+ contSearch = false
+ }
+ }
+ }
+ }
+ }
+ if (contSearch) {
+ super.visitExpressionStatement(statement)
+ }
+ }
+
+ override fun visitIfStatement(statement: PsiIfStatement) {
+ if (contSearch) {
+ checkBranch(statement, statement.thenBranch, false)
+ checkBranch(statement, statement.elseBranch, true)
+ }
+ }
+
+ private fun checkBranch(statement: PsiIfStatement, branch: PsiStatement?, removeElse: Boolean) {
+ if (branch != null) {
+ if (hasEmptyReturn(branch)) {
+ registerProblem(holder, isOnTheFly, statement, removeElse)
+ } else {
+ branch.accept(TestMethodVisitor(holder, isOnTheFly, containingClass))
+ }
+ }
+ }
+ }
+
+ class CheckForAssertThatCallsVisitor(private val containingClass: PsiClass, private var depth: Int) : JavaRecursiveElementWalkingVisitor() {
+ var foundAssertThat = false
+ private var statementCount = 0
+ var aborted = false
+
+ override fun visitExpressionStatement(statement: PsiExpressionStatement) {
+ if (foundAssertThat || aborted) {
+ return
+ }
+ if (++statementCount > MAX_STATEMENTS_COUNT) {
+ aborted = true
+ return
+ }
+ super.visitExpressionStatement(statement)
+ val methodCallExpression = statement.expression as? PsiMethodCallExpression
+ if (methodCallExpression != null) {
+ foundAssertThat = methodCallExpression.hasAssertThat()
+ val method = methodCallExpression.resolveMethod()
+ if (method?.containingClass == containingClass) {
+ if (depth < MAX_RECURSION_DEPTH) {
+ val recursionVisitor = CheckForAssertThatCallsVisitor(containingClass, depth + 1)
+ method.accept(recursionVisitor)
+ foundAssertThat = recursionVisitor.foundAssertThat
+ statementCount += recursionVisitor.statementCount
+ aborted = recursionVisitor.aborted
+ } else {
+ aborted = true
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JoinAssertThatStatementsInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JoinAssertThatStatementsInspection.kt
index a2a01a6..306730d 100644
--- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JoinAssertThatStatementsInspection.kt
+++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JoinAssertThatStatementsInspection.kt
@@ -11,7 +11,7 @@ import de.platon42.intellij.plugins.cajon.quickfixes.JoinStatementsQuickFix
class JoinAssertThatStatementsInspection : AbstractAssertJInspection() {
companion object {
- private const val DISPLAY_NAME = "Joining multiple assertThat() statements with same actual expression"
+ private const val DISPLAY_NAME = "Join multiple assertThat() statements with same actual expression"
private const val CAN_BE_JOINED_DESCRIPTION = "Multiple assertThat() statements can be joined together"
}
@@ -53,7 +53,7 @@ class JoinAssertThatStatementsInspection : AbstractAssertJInspection() {
}
if (reset) {
if (sameCount > 1) {
- registerProblem(firstStatement, lastStatement)
+ registerProblem(holder, isOnTheFly, firstStatement!!, lastStatement!!)
}
firstStatement = statement
lastStatement = null
@@ -62,22 +62,10 @@ class JoinAssertThatStatementsInspection : AbstractAssertJInspection() {
}
}
if (sameCount > 1) {
- registerProblem(firstStatement, lastStatement)
+ registerProblem(holder, isOnTheFly, firstStatement!!, lastStatement!!)
}
}
- private fun registerProblem(firstStatement: PsiStatement?, lastStatement: PsiStatement?) {
- val problemDescriptor = holder.manager.createProblemDescriptor(
- firstStatement!!,
- lastStatement!!,
- CAN_BE_JOINED_DESCRIPTION,
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- isOnTheFly,
- JoinStatementsQuickFix()
- )
- holder.registerProblem(problemDescriptor)
- }
-
private fun isLegitAssertThatCall(statement: PsiStatement?): PsiMethodCallExpression? {
if ((statement is PsiExpressionStatement) && (statement.expression is PsiMethodCallExpression)) {
if (!statement.hasAssertThat()) {
@@ -90,4 +78,16 @@ class JoinAssertThatStatementsInspection : AbstractAssertJInspection() {
}
}
}
+
+ private fun registerProblem(holder: ProblemsHolder, isOnTheFly: Boolean, firstStatement: PsiStatement, lastStatement: PsiStatement) {
+ val problemDescriptor = holder.manager.createProblemDescriptor(
+ firstStatement,
+ lastStatement,
+ CAN_BE_JOINED_DESCRIPTION,
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ isOnTheFly,
+ JoinStatementsQuickFix()
+ )
+ holder.registerProblem(problemDescriptor)
+ }
}
\ No newline at end of file
diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/JoinStatementsQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/JoinStatementsQuickFix.kt
index a033dcf..8e8c87f 100644
--- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/JoinStatementsQuickFix.kt
+++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/JoinStatementsQuickFix.kt
@@ -3,9 +3,9 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.*
-import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.findStaticMethodCall
+import de.platon42.intellij.plugins.cajon.shortenAndReformat
class JoinStatementsQuickFix : AbstractCommonQuickFix(JOIN_STATEMENTS_MESSAGE) {
@@ -48,6 +48,6 @@ class JoinStatementsQuickFix : AbstractCommonQuickFix(JOIN_STATEMENTS_MESSAGE) {
previousStatement.delete()
} while (previousStatement !== firstStatement)
val codeBlock = PsiTreeUtil.getParentOfType(lastStatement, PsiCodeBlock::class.java) ?: return
- CodeStyleManager.getInstance(project).reformat(codeBlock)
+ codeBlock.shortenAndReformat()
}
}
\ No newline at end of file
diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceIfByAssumeThatQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceIfByAssumeThatQuickFix.kt
new file mode 100644
index 0000000..9444f5a
--- /dev/null
+++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceIfByAssumeThatQuickFix.kt
@@ -0,0 +1,49 @@
+package de.platon42.intellij.plugins.cajon.quickfixes
+
+import com.intellij.codeInspection.ProblemDescriptor
+import com.intellij.openapi.project.Project
+import com.intellij.psi.JavaPsiFacade
+import com.intellij.psi.PsiBlockStatement
+import com.intellij.psi.PsiDeclarationStatement
+import com.intellij.psi.PsiIfStatement
+import de.platon42.intellij.plugins.cajon.*
+
+class ReplaceIfByAssumeThatQuickFix(private val removeElse: Boolean) : AbstractCommonQuickFix(REPLACE_IF_MESSAGE) {
+
+ companion object {
+ private const val REPLACE_IF_MESSAGE = "Replace if statement by assumeTrue()"
+ }
+
+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
+ val ifStatement = descriptor.startElement as PsiIfStatement
+
+ val condition = ifStatement.condition ?: return
+ val factory = JavaPsiFacade.getElementFactory(ifStatement.project)
+ val assumptionExpression = if (removeElse) MethodNames.IS_TRUE else MethodNames.IS_FALSE
+ val assumeThatStatement = factory.createStatementFromText(
+ "${AssertJClassNames.ASSUMPTIONS_CLASSNAME}.${MethodNames.ASSUME_THAT}(true).$assumptionExpression();",
+ ifStatement
+ )
+ val assumeThatMethodCall = assumeThatStatement.findStaticMethodCall() ?: return
+ assumeThatMethodCall.firstArg.replace(condition)
+ assumeThatMethodCall.resolveMethod()?.addAsStaticImport(ifStatement)
+
+ val branchToKeep = (if (removeElse) ifStatement.thenBranch else ifStatement.elseBranch)?.copy()
+ val parentBlock = ifStatement.parent
+ if (branchToKeep != null) {
+ val anchorElement = ifStatement.nextSibling
+ if (branchToKeep is PsiBlockStatement) {
+ val codeBlock = branchToKeep.codeBlock
+ val hasDeclarations = codeBlock.statements.any { it is PsiDeclarationStatement }
+ if (hasDeclarations) {
+ parentBlock.addAfter(branchToKeep, anchorElement)
+ } else {
+ parentBlock.addRangeAfter(codeBlock.firstBodyElement, codeBlock.lastBodyElement, anchorElement)
+ }
+ } else {
+ parentBlock.addAfter(branchToKeep, anchorElement)
+ }
+ }
+ ifStatement.replace(assumeThatStatement).shortenAndReformat()
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index 416cbcd..0ba2a5f 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -45,6 +45,8 @@
+
diff --git a/src/main/resources/inspectionDescriptions/AssumeThatInsteadOfReturn.html b/src/main/resources/inspectionDescriptions/AssumeThatInsteadOfReturn.html
new file mode 100644
index 0000000..4d716f6
--- /dev/null
+++ b/src/main/resources/inspectionDescriptions/AssumeThatInsteadOfReturn.html
@@ -0,0 +1,18 @@
+
+
+Tries to detect bogus uses of return statements in test methods and replaces them by assumeThat() calls.
+
+
+Novices will use these to skip test execution by bailing out early on some preconditions not met.
+However, this suggests that the test has actually been run and passed instead of showing the test
+as being skipped.
+Return statements in if statements in main test methods
+ (must be annotated with JUnit 4 or Jupiter @Test annotations)
+ will be verified to have at least one assertThat() statement in the code flow.
+ Method calls within the same class will be examined for assertThat() statements, too.
+ However, at most 50 statements and down to five recursions will be tolerated before giving up.
+
+Currently, the quickfix may lose some comments during operation. The other branch of the if statement
+ will be inlined (blocks with declarations will remain a code block due to variable scope).
+
+
\ No newline at end of file
diff --git a/src/main/resources/inspectionDescriptions/JUnitAssertToAssertJ.html b/src/main/resources/inspectionDescriptions/JUnitAssertToAssertJ.html
index 512346c..262ba38 100644
--- a/src/main/resources/inspectionDescriptions/JUnitAssertToAssertJ.html
+++ b/src/main/resources/inspectionDescriptions/JUnitAssertToAssertJ.html
@@ -1,11 +1,11 @@
-Tries to convert most of the JUnit 4 assertions to AssertJ-Format.
+Tries to convert most of the JUnit 4 assertions to AssertJ format.
Works for assertTrue(), assertFalse(), assertNull(), assertNotNull(), assertEquals(), assertNotEquals(), assertSame() assertNotSame(), assertArrayEquals().
Copes with variants with message and without, handles special versions for double and float types (including arrays).
-Does not support Hamcrest-Matchers. If you need that kind of conversion, you might want to check out the Assertions2AssertJ plugin by Ric Emery.
+ Does not support Hamcrest-Matchers. If you need that kind of conversion, you might want to check out the Assertions2AssertJ plugin by Ric Emery.
\ No newline at end of file
diff --git a/src/test/java/de/platon42/intellij/playground/Playground.java b/src/test/java/de/platon42/intellij/playground/Playground.java
deleted file mode 100644
index aa8a115..0000000
--- a/src/test/java/de/platon42/intellij/playground/Playground.java
+++ /dev/null
@@ -1,449 +0,0 @@
-package de.platon42.intellij.playground;
-
-import org.assertj.core.api.ListAssert;
-import org.assertj.core.data.Offset;
-import org.assertj.core.extractor.Extractors;
-
-import java.util.*;
-
-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 {
-
- private void sizeOfList() {
- assertThat("string").as("foo").hasSize(0);
- assertThat(new StringBuilder()).as("bar").hasSize(0);
- ListAssert etc = assertThat(new ArrayList()).as("etc");
- etc.hasSize(0);
- assertThat(new Long[1]).as("etc").hasSize(0);
-
- assertThat("string").as("foo").isEmpty();
- assertThat(new StringBuilder()).as("bar").isEmpty();
- assertThat(new ArrayList()).as("etc").isEmpty();
- assertThat(new Long[1]).as("etc").isEmpty();
-
- assertThat(new ArrayList<>().size()).isEqualTo(1);
- assertThat(new ArrayList().size()).isEqualTo(1);
- assertThat(new ArrayList().size()).isGreaterThanOrEqualTo(1);
- assertThat(new ArrayList().size()).isZero();
- assertThat(new ArrayList()).hasSizeGreaterThan(1);
- assertThat(new ArrayList()).hasSameSizeAs(new ArrayList<>());
- assertThat(new Long[1]).as("etc").hasSameSizeAs(new Long[2]);
- assertThat(new Long[1]).as("etc").hasSameSizeAs(new Long[2]);
- }
-
- private void joinStatements() {
- List list = new ArrayList<>();
- assertThat(list).as("foo").hasSize(2);
- assertThat(list).as("bar").contains("barbar"); // comment to keep
- assertThat(list).as("etc").contains("etcetc");
-
- // moar!
- assertThat(list).doesNotContain("foobar");
-
- assertThat("narf").isNotEqualTo("puit");
- assertThat(list).as("bar").contains("barbar");
- assertThat(list).as("foo").hasSize(2);
- assertThat(list).as("evil").extracting(String::length).contains(2);
-
- assertThat(list).as("bar").contains("barbar");
- assertThat("narf").isNotEqualTo("puit");
- assertThat(list).as("foo").hasSize(2);
- if (true) {
- assertThat(list).doesNotContain("narf");
- assertThat(list).as("bar").contains("barbar");
- }
- assertThat(list.get(0)).isNotEmpty();
- assertThat(list.get(0)).hasSize(3);
- assertThat(list.get(0)).isEqualTo("bar");
-
- assertThat(list.get(0) + "foo").isEqualTo("bar");
- assertThat(list.get(0) + "foo").doesNotStartWith("foo");
-
- Iterator iterator = list.iterator();
- assertThat(iterator.next()).isEqualTo("foo");
- assertThat(iterator.next()).isEqualTo("bar");
- }
-
- private void sizeOfArray() {
- assertThat(new String[1].length).isLessThanOrEqualTo(1);
- assertThat(new String[1]).hasSameSizeAs(new Object());
- assertThat("").isEqualTo(null);
- assertThat(true).isTrue();
- assertThat(true).isEqualTo(true);
- assertThat(Boolean.TRUE).isEqualTo(Boolean.FALSE);
- assertThat(Boolean.TRUE).isEqualTo(true);
- }
-
- private void booleanIsTrueOrFalse() {
- boolean primitive = false;
- Boolean object = java.lang.Boolean.TRUE;
-
- assertThat(primitive).isEqualTo(Boolean.TRUE);
- assertThat(primitive).isEqualTo(Boolean.FALSE);
- assertThat(object).isEqualTo(Boolean.TRUE);
- assertThat(object).isEqualTo(Boolean.FALSE);
- assertThat(primitive).isEqualTo(true);
- assertThat(primitive).isEqualTo(false);
- assertThat(object).isEqualTo(true);
- assertThat(object).isEqualTo(false);
-
- assertThat(primitive).isNotEqualTo(Boolean.TRUE);
- assertThat(primitive).isNotEqualTo(Boolean.FALSE);
- assertThat(object).isNotEqualTo(Boolean.TRUE);
- assertThat(object).isNotEqualTo(Boolean.FALSE);
- assertThat(primitive).isNotEqualTo(true);
- assertThat(primitive).isNotEqualTo(false);
- assertThat(object).isNotEqualTo(true);
- assertThat(object).isNotEqualTo(false);
-
- assertThat(primitive).as("nah").isEqualTo(true && !true);
- assertThat(object).isEqualTo(Boolean.TRUE && !Boolean.TRUE);
-
- assertThat("").isEqualTo(Boolean.TRUE);
- }
-
- private void binaryExpression() {
- int primExp = 42;
- int primAct = 1337;
- Double numberObjExp = 42.0;
- Double numberObjAct = 1337.0;
- String stringExp = "foo";
- String stringAct = "bar";
-
- assertThat(primAct == primExp).isTrue();
- assertThat(primAct == 1).isTrue();
- assertThat(primAct == primExp).isEqualTo(false);
- assertThat(primAct != primExp).isEqualTo(true);
- assertThat(1 != primAct).isTrue();
- assertThat(primAct != primExp).isNotEqualTo(true);
- assertThat(primAct > primExp).isNotEqualTo(false);
- assertThat(primAct > primExp).isFalse();
- assertThat(primAct > 1).isFalse();
- assertThat(primAct >= 1).isTrue();
- assertThat(primAct >= primExp).isEqualTo(false);
- assertThat(1 <= primAct).isFalse();
- assertThat(1 > primAct).isTrue();
- assertThat(primAct < primExp).isNotEqualTo(true);
- assertThat(primAct <= primExp).isNotEqualTo(false);
- assertThat(primAct <= primExp).isFalse();
- assertThat(primAct <= 1).isFalse();
- assertThat(numberObjAct == 1).isTrue();
- assertThat(numberObjAct == numberObjExp).isEqualTo(false);
- assertThat(numberObjAct != numberObjExp).isEqualTo(true);
- assertThat(1 != numberObjAct).isTrue();
- assertThat(numberObjAct != numberObjExp).isNotEqualTo(true);
- assertThat(numberObjAct > numberObjExp).isNotEqualTo(false);
- assertThat(numberObjAct > 1).isFalse();
- assertThat(numberObjAct >= numberObjExp).isTrue();
- assertThat(numberObjAct >= numberObjExp).isEqualTo(false);
- assertThat(1 <= numberObjAct).isFalse();
- assertThat(numberObjAct < numberObjExp).isEqualTo(true);
- assertThat(numberObjAct < numberObjExp).isNotEqualTo(true);
- assertThat(numberObjAct <= numberObjExp).isNotEqualTo(false);
- assertThat(numberObjAct <= 1).isFalse();
- assertThat(numberObjAct.equals(numberObjExp)).isFalse();
- assertThat(stringAct == stringExp).isNotEqualTo(false);
- assertThat(stringAct.equals(stringExp)).isEqualTo(true);
- assertThat(stringAct != stringExp).isFalse();
- assertThat(stringAct == null).isNotEqualTo(true);
- assertThat(null == stringAct).isEqualTo(false);
-
- assertThat(null == null).isTrue();
- assertThat(!false).isTrue();
- }
-
- private void stringStuff() {
- String foo = "bar";
- assertThat(foo).isEqualTo("");
- 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");
-
- ArrayList list = new ArrayList<>();
- long[] otherArray = new long[4];
-
- String string = "string";
- assertThat(string.length()).isEqualTo(0);
- assertThat(string.length()).isZero();
- assertThat(string.length()).isNotZero();
- assertThat(string.length()).as("hi").isGreaterThan(0);
- assertThat(string.length()).isGreaterThanOrEqualTo(1);
- assertThat(string.length()).isLessThan(1);
- assertThat(string.length()).isLessThanOrEqualTo(0);
- assertThat(string.length()).isEqualTo(list.size());
- assertThat(string.length()).isEqualTo(otherArray.length);
- assertThat(string.length()).isEqualTo(1);
- assertThat(string.length()).isGreaterThan(otherArray.length - 1);
- assertThat(string.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
- assertThat(string.length()).isLessThan(otherArray.length - 3);
- assertThat(string.length()).isLessThanOrEqualTo(1 - otherArray.length);
-
- StringBuilder stringBuilder = new StringBuilder();
- assertThat(stringBuilder.length()).isEqualTo(0);
- assertThat(stringBuilder.length()).isZero();
- assertThat(stringBuilder.length()).isNotZero();
- assertThat(stringBuilder.length()).as("hi").isGreaterThan(0);
- assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(1);
- assertThat(stringBuilder.length()).isLessThan(1);
- assertThat(stringBuilder.length()).isLessThanOrEqualTo(0);
- assertThat(stringBuilder.length()).isEqualTo(list.size());
- assertThat(stringBuilder.length()).isEqualTo(otherArray.length);
- assertThat(stringBuilder.length()).isEqualTo(1);
- assertThat(stringBuilder.length()).isGreaterThan(otherArray.length - 1);
- assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
- assertThat(stringBuilder.length()).isLessThan(otherArray.length - 3);
- assertThat(stringBuilder.length()).isLessThanOrEqualTo(1 - otherArray.length);
- }
-
- private void java8Optional() {
- Optional opt = Optional.empty();
-
- assertThat(opt.isPresent()).isEqualTo(true);
- assertThat(opt.isPresent()).isEqualTo(Boolean.TRUE);
- assertThat(opt.isPresent()).isNotEqualTo(false);
- assertThat(opt.isPresent()).isNotEqualTo(Boolean.FALSE);
- assertThat(opt.isPresent()).isTrue();
-
- assertThat(opt.isPresent()).isEqualTo(false);
- assertThat(opt.isPresent()).isEqualTo(Boolean.FALSE);
- assertThat(opt.isPresent()).isNotEqualTo(true);
- assertThat(opt.isPresent()).isNotEqualTo(Boolean.TRUE);
- assertThat(opt.isPresent()).isFalse();
-
- assertThat(opt.get()).isEqualTo("foo");
- assertThat(opt.get()).isSameAs("foo");
-
- assertThat(opt).isEqualTo(Optional.of("foo"));
- assertThat(opt).isEqualTo(Optional.ofNullable("foo"));
- assertThat(opt).isNotEqualTo(Optional.of("foo"));
- assertThat(opt).isNotEqualTo(Optional.ofNullable("foo"));
-
- assertThat(opt).isEqualTo(Optional.empty());
- assertThat(opt).isNotEqualTo(Optional.empty());
- assertThat(opt).isPresent();
- }
-
- private void assertThatGuavaOptional() {
- com.google.common.base.Optional opt = com.google.common.base.Optional.absent();
-
- assertThat(opt.isPresent()).isEqualTo(true);
- assertThat(opt.isPresent()).isEqualTo(Boolean.TRUE);
- assertThat(opt.isPresent()).isNotEqualTo(false);
- assertThat(opt.isPresent()).isNotEqualTo(Boolean.FALSE);
- assertThat(opt.isPresent()).isTrue();
-
- assertThat(opt.isPresent()).isEqualTo(false);
- assertThat(opt.isPresent()).isEqualTo(Boolean.FALSE);
- assertThat(opt.isPresent()).isNotEqualTo(true);
- assertThat(opt.isPresent()).isNotEqualTo(Boolean.TRUE);
- 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(com.google.common.base.Optional.of("foo"));
- assertThat(opt).isEqualTo(com.google.common.base.Optional.fromNullable("foo"));
- assertThat(opt).isNotEqualTo(com.google.common.base.Optional.of("foo"));
- assertThat(opt).isNotEqualTo(com.google.common.base.Optional.fromNullable("foo"));
-
- assertThat(opt).isEqualTo(com.google.common.base.Optional.absent());
- assertThat(opt).isNotEqualTo(com.google.common.base.Optional.absent());
- assertThat(opt).isAbsent();
- }
-
- private void assertThatInstance() {
- String foo = "foo";
- assertThat(foo instanceof String).isTrue();
- assertThat(foo).isInstanceOf(String.class);
- assertThat(foo).isNotInstanceOf(String.class);
- }
-
- private void junitAssertions() {
- assertFalse(!(new int[3].length == new ArrayList().size()));
- assertThat(!(new int[3].length == new ArrayList().size())).isFalse();
- assertThat((new int[3].length == new ArrayList().size())).isTrue();
- assertThat(new int[3].length == new ArrayList().size()).isTrue();
- assertThat(new int[3].length).isEqualTo(new ArrayList().size());
- assertThat(new int[3]).hasSameSizeAs(new ArrayList());
-
- assertTrue(true);
- assertTrue("message", true);
- assertFalse(true);
- assertFalse("message", true);
- assertEquals(1L, 2L);
- assertEquals("message", 1L, 2L);
- assertNotEquals(1L, 2L);
- assertNotEquals("message", 1L, 2L);
- assertEquals(4.0, 4.4, 3.3);
- assertThat(3.0).isCloseTo(4.0, Offset.offset(2.3));
- assertThat(new int[1]).isEqualTo(new int[2]);
-
- String foo = "foo";
- String bar = "bar";
-
- assertTrue(foo == "foo");
- assertTrue("oh no!", foo == "foo");
- assertFalse(foo == "bar");
- assertFalse("boom!", foo == "bar");
-
- assertNull(foo);
- assertNull("oh no!", foo);
- assertNotNull(foo);
- assertNotNull("oh no!", foo);
-
- assertEquals(bar, foo);
- assertEquals("equals", bar, foo);
- assertNotEquals(bar, foo);
- assertNotEquals("equals", bar, foo);
-
- assertSame(bar, foo);
- assertSame("same", bar, foo);
- assertNotSame(bar, foo);
- assertNotSame("same", bar, foo);
-
- assertEquals(1.0, 2.0, 0.1);
- assertEquals("equals", 1.0, 2.0, 0.1);
- assertEquals(1.0f, 2.0f, 0.1f);
- assertEquals("equals", 1.0f, 2.0f, 0.1f);
-
- assertNotEquals(1.0, 2.0);
- assertNotEquals(1.0, 2.0, 0.1);
- assertNotEquals("equals", 1.0, 2.0);
- assertNotEquals("equals", 1.0, 2.0, 0.1);
- assertNotEquals(1.0f, 2.0f);
- assertNotEquals(1.0f, 2.0f, 0.1f);
- assertNotEquals("equals", 1.0f, 2.0f);
- assertNotEquals("equals", 1.0f, 2.0f, 0.1f);
-
- assertArrayEquals(new int[2], new int[1]);
- assertArrayEquals("array equals", new int[2], new int[1]);
-
- assertArrayEquals(new double[2], new double[1], 1.0);
- assertArrayEquals("array equals", new double[2], new double[1], 1.0);
- assertArrayEquals(new float[2], new float[1], 1.0f);
- assertArrayEquals("array equals", new float[2], new float[1], 1.0f);
-
-
- assertThat(foo == "foo").isTrue();
- assertThat(foo == "foo").as("oh no!").isTrue();
- assertThat(foo == "bar").isFalse();
- assertThat(foo == "bar").as("boom!").isFalse();
-
- assertThat(foo).isNull();
- assertThat(foo).as("oh no!").isNull();
- assertThat(foo).isNotNull();
- assertThat(foo).as("oh no!").isNotNull();
-
- assertThat(foo).isEqualTo(bar);
- assertThat(foo).as("equals").isEqualTo(bar);
- assertThat(foo).isNotEqualTo(bar);
- assertThat(foo).as("equals").isNotEqualTo(bar);
-
- assertThat(foo).isSameAs(bar);
- assertThat(foo).as("same").isSameAs(bar);
- assertThat(foo).isNotSameAs(bar);
- assertThat(foo).as("same").isNotSameAs(bar);
-
- assertThat(2.0).isEqualTo(1.0);
- assertThat(2.0).isCloseTo(1.0, offset(0.1));
- assertThat(2.0).as("equals").isEqualTo(1.0);
- assertThat(2.0).as("equals").isCloseTo(1.0, offset(0.1));
- assertThat(2.0f).isEqualTo(1.0f);
- assertThat(2.0f).isCloseTo(1.0f, offset(0.1f));
- assertThat(2.0f).as("equals").isEqualTo(1.0f);
- assertThat(2.0f).as("equals").isCloseTo(1.0f, offset(0.1f));
-
- assertThat(2.0).isNotEqualTo(1.0);
- assertThat(2.0).isNotCloseTo(1.0, offset(0.1));
- assertThat(2.0).as("equals").isNotEqualTo(1.0);
- assertThat(2.0).as("equals").isNotCloseTo(1.0, offset(0.1));
- assertThat(2.0f).isNotEqualTo(1.0f);
- assertThat(2.0f).isNotCloseTo(1.0f, offset(0.1f));
- assertThat(2.0f).as("equals").isNotEqualTo(1.0f);
- assertThat(2.0f).as("equals").isNotCloseTo(1.0f, offset(0.1f));
-
- assertThat(new int[1]).isEqualTo(new int[2]);
- assertThat(new int[1]).as("array equals").isEqualTo(new int[2]);
-
- assertThat(new double[1]).containsExactly(new double[2], offset(1.0));
- 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("toString");
- assertThat(new Object()).extracting(Object::toString, Object::hashCode);
- }
-
- private void findReferences() {
- Contact contact = new Contact();
- List 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;
- }
- }
-}
\ No newline at end of file
diff --git a/src/test/java/de/platon42/intellij/plugins/cajon/AbstractCajonTest.kt b/src/test/java/de/platon42/intellij/plugins/cajon/AbstractCajonTest.kt
index 7799e8e..933223a 100644
--- a/src/test/java/de/platon42/intellij/plugins/cajon/AbstractCajonTest.kt
+++ b/src/test/java/de/platon42/intellij/plugins/cajon/AbstractCajonTest.kt
@@ -11,13 +11,17 @@ import de.platon42.intellij.jupiter.TestDataPath
import de.platon42.intellij.jupiter.TestJdk
import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThat
+import org.junit.jupiter.api.DisplayNameGeneration
+import org.junit.jupiter.api.DisplayNameGenerator
import org.junit.jupiter.api.extension.ExtendWith
import java.lang.reflect.InvocationTargetException
+import java.lang.reflect.Method
@ExtendWith(LightCodeInsightExtension::class)
@TestDataPath("src/test/resources")
@TestJdk(LanguageLevel.JDK_1_8, annotations = true, useInternal = true)
@AddLocalJarToModule(Assertions::class)
+@DisplayNameGeneration(AbstractCajonTest.CutOffFixtureDisplayNameGenerator::class)
abstract class AbstractCajonTest {
// See https://github.com/junit-team/junit5/issues/157, should be resolved with junit5 5.5 M2
@@ -64,4 +68,11 @@ abstract class AbstractCajonTest {
assertThat(quickfixes).`as`("Fixes matched by $regex: ${myFixture.getAllQuickFixes().map { it.text }}").hasSize(expectedFixes)
quickfixes.forEach(myFixture::launchAction)
}
+
+ class CutOffFixtureDisplayNameGenerator : DisplayNameGenerator.ReplaceUnderscores() {
+ override fun generateDisplayNameForMethod(testClass: Class<*>?, testMethod: Method?): String {
+ val nameForMethod = super.generateDisplayNameForMethod(testClass, testMethod)
+ return nameForMethod.substringBefore("$")
+ }
+ }
}
\ No newline at end of file
diff --git a/src/test/java/de/platon42/intellij/plugins/cajon/inspections/AssumeThatInsteadOfReturnInspectionTest.kt b/src/test/java/de/platon42/intellij/plugins/cajon/inspections/AssumeThatInsteadOfReturnInspectionTest.kt
new file mode 100644
index 0000000..99cc250
--- /dev/null
+++ b/src/test/java/de/platon42/intellij/plugins/cajon/inspections/AssumeThatInsteadOfReturnInspectionTest.kt
@@ -0,0 +1,24 @@
+package de.platon42.intellij.plugins.cajon.inspections
+
+import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
+import de.platon42.intellij.jupiter.AddLocalJarToModule
+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
+import org.junit.jupiter.api.Test
+
+@AddLocalJarToModule(Assertions::class, Test::class, org.junit.Test::class)
+internal class AssumeThatInsteadOfReturnInspectionTest : AbstractCajonTest() {
+
+ @Test
+ @TestDataSubPath("inspections/AssumeThat")
+ internal fun conditional_returns_can_be_replaced_by_assumeThat(@MyFixture myFixture: JavaCodeInsightTestFixture) {
+ runTest {
+ myFixture.enableInspections(AssumeThatInsteadOfReturnInspection::class.java)
+ myFixture.configureByFile("AssumeThatBefore.java")
+ executeQuickFixes(myFixture, Regex.fromLiteral("Replace if statement by assumeTrue()"), 4)
+ myFixture.checkResultByFile("AssumeThatAfter.java")
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/inspections/AssumeThat/AssumeThatAfter.java b/src/test/resources/inspections/AssumeThat/AssumeThatAfter.java
new file mode 100644
index 0000000..475457c
--- /dev/null
+++ b/src/test/resources/inspections/AssumeThat/AssumeThatAfter.java
@@ -0,0 +1,151 @@
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assumptions.assumeThat;
+
+public class AssumeThat {
+
+ @Test
+ public void junit4_return_very_early() {
+ assumeThat(new Random().nextBoolean()).isFalse();
+ System.out.println("sweet!"); // single else statement
+ String foobar = System.getProperty("foobar");
+ assertThat(foobar).isNotEmpty();
+ }
+
+ @Test
+ public void junit4_return_in_else_branch_with_declaration_in_code_block_and_lots_of_comments() {
+ // primary comments
+ assumeThat(new Random().nextBoolean()).isTrue();
+ {
+ // Block start comment will be retained
+ String anotherString = "narf"; // This one is likely to be kept
+ assertThat(foobar).isNotEmpty();
+ assertThat(foobar).isEqualTo(anotherString);
+ // Block end comment is also going to be retained
+ } /* weird places */
+ // well, well, let's do some checks
+ String foobar = System.getProperty("foobar");
+ assertThat(foobar).isNotEmpty();
+ }
+
+ @org.junit.jupiter.api.Test
+ public void junit5_return_after_call_without_else_branch() {
+ String foobar = System.getProperty("car_manufacturer");
+ assumeThat(foobar.equals("Volkswagen")).isFalse();
+ assertThat(foobar).isNotEmpty();
+ }
+
+ @org.junit.jupiter.api.TestTemplate
+ public void junit5_return_inside_recursion_with_comments() {
+ String foobar = System.getProperty("car_manufacturer");
+ if (foobar != null) {
+ assumeThat(!foobar.equals("Volkswagen")).isTrue();
+ // I doubted this comment will be retained -- but surprise!
+ assertThat(foobar).isNotEmpty();
+ // we might keep this one alright.
+ foobar = "narf";
+ // And the final one? Again what learned.
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ if(foobar.length() == 0)
+ {
+ return;
+ }
+ assertThat(foobar).endsWith("!!!");
+ }
+
+ @Test
+ public void junit4_return_after_assertion() {
+ String foobar = System.getProperty("car_manufacturer");
+ assertThat(foobar).isNotNull();
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ @Test
+ public void junit4_return_after_assertions_in_subroutine() {
+ String foobar = System.getProperty("car_manufacturer");
+ assertStuff(foobar);
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ @Test
+ public void junit4_return_after_assertions_in_deep_subroutine() {
+ String foobar = System.getProperty("car_manufacturer");
+ firstMethod();
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ @Test
+ public void junit4_return_after_assertions_in_deep_subroutine_with_recursion() {
+ String foobar = System.getProperty("car_manufacturer");
+ firstMethodWithPotentialRecursion();
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ @Test
+ public void junit4_no_harm_with_infinite_recursion() {
+ String foobar = System.getProperty("car_manufacturer");
+ infiniteRecursion();
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ private void assertStuff(String foobar) {
+ if (new Random().nextBoolean()) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ assertThat(foobar).isNull();
+ }
+ }
+
+ private void firstMethod() {
+ if (new Random().nextBoolean()) {
+ assertStuff("narf");
+ }
+ }
+
+ private void firstMethodWithPotentialRecursion() {
+ if (new Random().nextBoolean()) {
+ assertStuff("narf");
+ } else {
+ infiniteRecursion();
+ }
+ }
+
+ private void infiniteRecursion() {
+ secondaryRecursion();
+ secondaryRecursion();
+ }
+
+ private void secondaryRecursion() {
+ infiniteRecursion();
+ infiniteRecursion();
+ }
+}
diff --git a/src/test/resources/inspections/AssumeThat/AssumeThatBefore.java b/src/test/resources/inspections/AssumeThat/AssumeThatBefore.java
new file mode 100644
index 0000000..9239824
--- /dev/null
+++ b/src/test/resources/inspections/AssumeThat/AssumeThatBefore.java
@@ -0,0 +1,156 @@
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AssumeThat {
+
+ @Test
+ public void junit4_return_very_early() {
+ if (new Random().nextBoolean()) {
+ return;
+ } else System.out.println("sweet!"); // single else statement
+ String foobar = System.getProperty("foobar");
+ assertThat(foobar).isNotEmpty();
+ }
+
+ @Test
+ public void junit4_return_in_else_branch_with_declaration_in_code_block_and_lots_of_comments() {
+ // primary comments
+ if (new Random().nextBoolean()) /* strange place for a comment */ {
+ // Block start comment will be retained
+ String anotherString = "narf"; // This one is likely to be kept
+ assertThat(foobar).isNotEmpty();
+ assertThat(foobar).isEqualTo(anotherString);
+ // Block end comment is also going to be retained
+ } /* weird places */ else /* more weird places */ { // this one is lost
+ return; // Would be sweet to keep this comment, too.
+ } // another comment lost
+ // well, well, let's do some checks
+ String foobar = System.getProperty("foobar");
+ assertThat(foobar).isNotEmpty();
+ }
+
+ @org.junit.jupiter.api.Test
+ public void junit5_return_after_call_without_else_branch() {
+ String foobar = System.getProperty("car_manufacturer");
+ if (foobar.equals("Volkswagen")) return; // no need for Volkswagen to perform tests
+ assertThat(foobar).isNotEmpty();
+ }
+
+ @org.junit.jupiter.api.TestTemplate
+ public void junit5_return_inside_recursion_with_comments() {
+ String foobar = System.getProperty("car_manufacturer");
+ if (foobar != null) {
+ if (!foobar.equals("Volkswagen")) {
+ // I doubted this comment will be retained -- but surprise!
+ assertThat(foobar).isNotEmpty();
+ // we might keep this one alright.
+ foobar = "narf";
+ // And the final one? Again what learned.
+ } else {
+ // ooops, how did that happen?
+ return;
+ }
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ if(foobar.length() == 0)
+ {
+ return;
+ }
+ assertThat(foobar).endsWith("!!!");
+ }
+
+ @Test
+ public void junit4_return_after_assertion() {
+ String foobar = System.getProperty("car_manufacturer");
+ assertThat(foobar).isNotNull();
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ @Test
+ public void junit4_return_after_assertions_in_subroutine() {
+ String foobar = System.getProperty("car_manufacturer");
+ assertStuff(foobar);
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ @Test
+ public void junit4_return_after_assertions_in_deep_subroutine() {
+ String foobar = System.getProperty("car_manufacturer");
+ firstMethod();
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ @Test
+ public void junit4_return_after_assertions_in_deep_subroutine_with_recursion() {
+ String foobar = System.getProperty("car_manufacturer");
+ firstMethodWithPotentialRecursion();
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ @Test
+ public void junit4_no_harm_with_infinite_recursion() {
+ String foobar = System.getProperty("car_manufacturer");
+ infiniteRecursion();
+ if (!foobar.equals("Volkswagen")) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ return;
+ }
+ assertThat(foobar).startsWith("another ecology rapist");
+ }
+
+ private void assertStuff(String foobar) {
+ if (new Random().nextBoolean()) {
+ assertThat(foobar).isNotEmpty();
+ } else {
+ assertThat(foobar).isNull();
+ }
+ }
+
+ private void firstMethod() {
+ if (new Random().nextBoolean()) {
+ assertStuff("narf");
+ }
+ }
+
+ private void firstMethodWithPotentialRecursion() {
+ if (new Random().nextBoolean()) {
+ assertStuff("narf");
+ } else {
+ infiniteRecursion();
+ }
+ }
+
+ private void infiniteRecursion() {
+ secondaryRecursion();
+ secondaryRecursion();
+ }
+
+ private void secondaryRecursion() {
+ infiniteRecursion();
+ infiniteRecursion();
+ }
+}