Fixed missing description for JoinAssertThatStatements and detection of equivalent expressions.

This commit is contained in:
Chris Hodges 2019-04-29 19:42:46 +02:00
parent 941ddfdb5e
commit 0b2ce470db
7 changed files with 44 additions and 23 deletions

View File

@ -78,10 +78,8 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
assertThat(expected).anotherCondition(); assertThat(expected).anotherCondition();
to: assertThat(expected).someCondition().anotherCondition(); to: assertThat(expected).someCondition().anotherCondition();
``` ```
Joining will work on actual expressions inside assertThat() that are Joining will work on actual expressions inside assertThat() that are equivalent expressions,
- the same variable reference except for method calls with known side-effect methods such as ```Iterator.next()``` -- please notify me about others.
- textually equal binary expressions
- the same method calls (except for known side-effect methods such as ```Iterator.next()``` -- please notify me about others)
The comments of the statements will be preserved. When using ```.extracting()``` or similar, the statements will not be merged. The comments of the statements will be preserved. When using ```.extracting()``` or similar, the statements will not be merged.
@ -345,6 +343,9 @@ Feel free to use the code (in package de.platon42.intellij.jupiter) for your pro
## Changelog ## Changelog
#### V0.8 (unreleased)
- Fixed missing description for JoinAssertThatStatements and detection of equivalent expressions (sorry, released it too hastily).
#### V0.7 (28-Apr-19) #### V0.7 (28-Apr-19)
- Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions - Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions
(really, Jetbrains, this sucks for no reason). (really, Jetbrains, this sucks for no reason).

View File

@ -5,7 +5,7 @@ plugins {
} }
group 'de.platon42' group 'de.platon42'
version '0.7' version '0.8'
repositories { repositories {
mavenCentral() mavenCentral()
@ -40,6 +40,10 @@ intellij {
patchPluginXml { patchPluginXml {
changeNotes """ changeNotes """
<h4>V0.8 (unreleased)</h4>
<ul>
<li>Fixed missing description for JoinAssertThatStatements and detection of equivalent expressions (sorry, released it too hastily).
</ul>
<h4>V0.7 (28-Apr-19)</h4> <h4>V0.7 (28-Apr-19)</h4>
<ul> <ul>
<li>Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions <li>Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions
@ -48,15 +52,6 @@ patchPluginXml {
<li>Implemented first version of JoinAssertThatStatements inspection that will try to merge assertThat() statements with the same <li>Implemented first version of JoinAssertThatStatements inspection that will try to merge assertThat() statements with the same
actual object together, preserving comments. actual object together, preserving comments.
</ul> </ul>
<h4>V0.6 (22-Apr-19)</h4>
<ul>
<li>New AssertThatStringExpression inspection that will move isEmpty(), equals(), equalsIgnoreCase(), contains(),
startsWith(), and endsWith() out of actual expression.
<li>Extended AssertThatSize inspection to take strings and CharSequences into account, too.
<li>New AssertThatInvertedBooleanCondition inspection that will remove inverted boolean expressions inside assertThat().
<li>Renamed a few inspections to better/shorter names.
<li>New AssertThatInstanceOf inspection that moves instanceof expressions out of assertThat().
</ul>
<p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p> <p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p>
""" """
} }

View File

@ -4,6 +4,7 @@ import com.intellij.codeInspection.ProblemHighlightType
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.PsiTreeUtil
import com.siyeh.ig.psiutils.TrackingEquivalenceChecker
import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.quickfixes.JoinStatementsQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.JoinStatementsQuickFix
@ -25,6 +26,7 @@ class JoinAssertThatStatementsInspection : AbstractAssertJInspection() {
var sameCount = 0 var sameCount = 0
var firstStatement: PsiStatement? = null var firstStatement: PsiStatement? = null
var lastStatement: PsiStatement? = null var lastStatement: PsiStatement? = null
val equivalenceChecker = TrackingEquivalenceChecker()
for (statement in statements) { for (statement in statements) {
val assertThatCall = isLegitAssertThatCall(statement) val assertThatCall = isLegitAssertThatCall(statement)
var reset = true var reset = true
@ -34,11 +36,9 @@ class JoinAssertThatStatementsInspection : AbstractAssertJInspection() {
actualExpression = assertThatCall.firstArg actualExpression = assertThatCall.firstArg
if (!reset) { if (!reset) {
val isSame = when (actualExpression) { val isSame = when (actualExpression) {
is PsiReferenceExpression -> (actualExpression.qualifierExpression == (lastActualExpression as? PsiReferenceExpression)?.qualifierExpression) is PsiMethodCallExpression -> equivalenceChecker.expressionsAreEquivalent(actualExpression, lastActualExpression)
is PsiMethodCallExpression -> (actualExpression.text == (lastActualExpression as? PsiMethodCallExpression)?.text)
&& !KNOWN_METHODS_WITH_SIDE_EFFECTS.test(actualExpression) && !KNOWN_METHODS_WITH_SIDE_EFFECTS.test(actualExpression)
is PsiPolyadicExpression -> (actualExpression.text == (lastActualExpression as? PsiPolyadicExpression)?.text) else -> equivalenceChecker.expressionsAreEquivalent(actualExpression, lastActualExpression)
else -> false
} }
if (isSame) { if (isSame) {
sameCount++ sameCount++

View File

@ -0,0 +1,7 @@
<html>
<body>
Joins consecutive assertThat() statements with the same actual expression together.
<!-- tooltip end -->
<br>Retains comments during operation. If the AssertThat()-Statement contains .extracting() methods, they will not be joined.
</body>
</html>

View File

@ -10,11 +10,11 @@ internal class JoinAssertThatStatementsInspectionTest : AbstractCajonTest() {
@Test @Test
@TestDataSubPath("inspections/JoinStatements") @TestDataSubPath("inspections/JoinStatements")
internal fun assertThat_size_of_array_or_collection_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) { internal fun assertThat_statements_can_be_joined_together(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest { runTest {
myFixture.enableInspections(JoinAssertThatStatementsInspection::class.java) myFixture.enableInspections(JoinAssertThatStatementsInspection::class.java)
myFixture.configureByFile("JoinStatementsBefore.java") myFixture.configureByFile("JoinStatementsBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Join assertThat() statements"), 6) executeQuickFixes(myFixture, Regex.fromLiteral("Join assertThat() statements"), 5)
myFixture.checkResultByFile("JoinStatementsAfter.java") myFixture.checkResultByFile("JoinStatementsAfter.java")
} }
} }

View File

@ -6,6 +6,8 @@ public class JoinStatements {
private void joinStatements() { private void joinStatements() {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
List<String> otherList = new ArrayList<>();
// the future is always born in pain // the future is always born in pain
/* tricky */ /* tricky */
assertThat(list).as("foo").hasSize(2) assertThat(list).as("foo").hasSize(2)
@ -21,18 +23,26 @@ public class JoinStatements {
// moar! // moar!
.doesNotContain("foobar"); .doesNotContain("foobar");
assertThat("narf").isNotEqualTo("puit").as("bar").contains("barbar").as("foo").hasSize(2); assertThat("narf").isNotEqualTo("puit");
assertThat(list).as("bar").contains("barbar").as("foo").hasSize(2);
assertThat(list).as("evil").extracting(String::length).contains(2); assertThat(list).as("evil").extracting(String::length).contains(2);
assertThat(list).as("bar").contains("barbar"); assertThat(list).as("bar").contains("barbar");
assertThat("narf").isNotEqualTo("puit").as("foo").hasSize(2); assertThat(otherList).contains("puit");
assertThat(list).as("foo").hasSize(2);
if (true) { if (true) {
assertThat(list).doesNotContain("narf").as("bar").contains("barbar"); assertThat(list).doesNotContain("narf").as("bar").contains("barbar");
} }
assertThat(list.get(0)).isNotEmpty().hasSize(3).isEqualTo("bar"); assertThat(list.get(0)).isNotEmpty().hasSize(3).isEqualTo("bar");
assertThat(otherList.get(0)).isNotEmpty();
assertThat(list.get(0)).hasSize(3);
assertThat(list.get(0) + "foo").isEqualTo("bar").doesNotStartWith("foo"); assertThat(list.get(0) + "foo").isEqualTo("bar").doesNotStartWith("foo");
assertThat(otherList.get(0) + "foo").isEqualTo("bar");
assertThat(list.get(0) + "foo").doesNotStartWith("foo");
Iterator<String> iterator = list.iterator(); Iterator<String> iterator = list.iterator();
assertThat(iterator.next()).isEqualTo("foo"); assertThat(iterator.next()).isEqualTo("foo");
assertThat(iterator.next()).isEqualTo("bar"); assertThat(iterator.next()).isEqualTo("bar");

View File

@ -6,6 +6,8 @@ public class JoinStatements {
private void joinStatements() { private void joinStatements() {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
List<String> otherList = new ArrayList<>();
// the future is always born in pain // the future is always born in pain
/* tricky */assertThat(list).as("foo").hasSize(2); /* do one */ /* do another */ /* tricky */assertThat(list).as("foo").hasSize(2); /* do one */ /* do another */
assertThat(list).as("bar").contains("barbar"); // comment to keep assertThat(list).as("bar").contains("barbar"); // comment to keep
@ -24,7 +26,7 @@ public class JoinStatements {
assertThat(list).as("evil").extracting(String::length).contains(2); assertThat(list).as("evil").extracting(String::length).contains(2);
assertThat(list).as("bar").contains("barbar"); assertThat(list).as("bar").contains("barbar");
assertThat("narf").isNotEqualTo("puit"); assertThat(otherList).contains("puit");
assertThat(list).as("foo").hasSize(2); assertThat(list).as("foo").hasSize(2);
if (true) { if (true) {
assertThat(list).doesNotContain("narf"); assertThat(list).doesNotContain("narf");
@ -34,9 +36,15 @@ public class JoinStatements {
assertThat(list.get(0)).hasSize(3); assertThat(list.get(0)).hasSize(3);
assertThat(list.get(0)).isEqualTo("bar"); assertThat(list.get(0)).isEqualTo("bar");
assertThat(otherList.get(0)).isNotEmpty();
assertThat(list.get(0)).hasSize(3);
assertThat(list.get(0) + "foo").isEqualTo("bar"); assertThat(list.get(0) + "foo").isEqualTo("bar");
assertThat(list.get(0) + "foo").doesNotStartWith("foo"); assertThat(list.get(0) + "foo").doesNotStartWith("foo");
assertThat(otherList.get(0) + "foo").isEqualTo("bar");
assertThat(list.get(0) + "foo").doesNotStartWith("foo");
Iterator<String> iterator = list.iterator(); Iterator<String> iterator = list.iterator();
assertThat(iterator.next()).isEqualTo("foo"); assertThat(iterator.next()).isEqualTo("foo");
assertThat(iterator.next()).isEqualTo("bar"); assertThat(iterator.next()).isEqualTo("bar");