Compare commits

...
5 Commits
51 changed files with 360 additions and 55 deletions
+28 -3
View File
@@ -92,6 +92,23 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
The behavior regarding the insertion of line breaks between the expressions can be configured in the
inspection settings.
- JoinVarArgsContains
Looks for ```.contains()```, ```.doesNotContain()```, and .```containsOnlyOnce()``` calls for iterables
within the same statement. The available quickfix can join the arguments to variadic version of the call
and remove the surplus one.
```
from: assertThat(expected).contains("foo").doesNotContain("bar").contains("etc").doesNotContain("huh");
to: assertThat(expected).contains("foo", "etc").doesNotContain("bar", "huh");
```
Will not be performed on more complex statements with ```.extracting()``` or ```.as()``` to avoid
changing semantics or losing descriptions.
Note that the quickfix does not handle comments very well and might remove them during the operation.
You may need to perform some manual reformatting, if the line gets too long after applying the fix.
- AssertThatObjectIsNullOrNotNull
Uses ```isNull()``` and ```isNotNull()``` instead.
@@ -343,7 +360,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
to: assertThat(opt).isPresent();
from: assertThat(opt).isEqualTo(Optional.of("foo"));
from: assertThat(opt).isEqualTo(Optional.ofNullable("foo"));
from: assertThat(opt).isEqualTo(Optional.ofNullable("foo")); // only for constant "foo"
to: assertThat(opt).contains("foo");
from: assertThat(opt).isEqualTo(Optional.empty());
@@ -380,7 +397,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
to: assertThat(opt).isPresent();
from: assertThat(opt).isEqualTo(Optional.of("foo"));
from: assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
from: assertThat(opt).isEqualTo(Optional.fromNullable("foo")); // only for constant "foo"
to: assertThat(opt).contains("foo");
from: assertThat(opt).isEqualTo(Optional.absent());
@@ -509,7 +526,7 @@ 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
- Joining .contains() expressions
- More Optional fixes such as opt1.get() == opt2.get() etc.
- Converting ```foo.compareTo(bar) == 0``` to ```isEqualTo()``` (yes, I've *really* seen code like that)
- Extraction with property names to lambda with Java 8
@@ -520,6 +537,14 @@ Feel free to use the code (in package ```de.platon42.intellij.jupiter```) for yo
## Changelog
#### V1.3 (03-Aug-19)
- New JoinVarArgsContains inspection that will detect multiple ```.contains()```, ```.doesNotContain()```,
and ```.containsOnlyOnce()``` calls within the same statement that could be joined together using variadic arguments.
- AssertJ 3.13.0 broke some inspections due to new ```AbstractStringAssert::isEqualTo()``` method.
- AssertThatJava8Optional and AssertThatGuavaOptional inspections do not longer try to fix
```assertThat(optional).isEqualTo(Optional.fromNullable(expression))``` to ```contains()```
when ```expression``` is not a non-null constant expression.
#### V1.2 (23-Jun-19)
- Due to popular demand the JoinAssertThatStatements inspection will now add line breaks on joining statements.
The amount of statements joined without causing line breaks can be configured but defaults to 1 (always).
+15 -10
View File
@@ -1,13 +1,13 @@
plugins {
id 'java'
id 'org.jetbrains.intellij' version '0.4.9'
id 'org.jetbrains.kotlin.jvm' version '1.3.40'
id 'org.jetbrains.kotlin.jvm' version '1.3.41'
id 'jacoco'
id 'com.github.kt3k.coveralls' version '2.8.2'
id 'com.github.kt3k.coveralls' version '2.8.4'
}
group 'de.platon42'
version '1.2'
version '1.3'
repositories {
mavenCentral()
@@ -20,10 +20,10 @@ repositories {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testCompile "org.assertj:assertj-core:3.12.2"
testCompile "org.assertj:assertj-core:3.13.0"
testCompile "org.assertj:assertj-guava:3.2.1"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.0-RC2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.0-RC2'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.1'
testImplementation "org.jetbrains.kotlin:kotlin-test"
// testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
}
@@ -35,17 +35,22 @@ compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
intellij {
version '2019.1.3'
version '2019.2'
// pluginName 'Concise AssertJ Optimizing Nitpicker (Cajon)'
updateSinceUntilBuild false
plugins = ['java']
}
patchPluginXml {
changeNotes """
<h4>V1.2 (23-Jun-19)</h4>
<h4>V1.3 (03-Aug-19)</h4>
<ul>
<li>Due to popular demand the JoinAssertThatStatements inspection will now add line breaks on joining statements.
The amount of statements joined without causing line breaks can be configured but defaults to 1 (always).
<li>New JoinVarArgsContains inspection that will detect multiple .contains(), .doesNotContain(), and .containsOnlyOnce()
calls within the same statement that could be joined together using variadic arguments.
<li>AssertJ 3.13.0 broke some inspections due to new AbstractStringAssert::isEqualTo() method.
<li>AssertThatJava8Optional and AssertThatGuavaOptional inspections do not longer try to fix
assertThat(optional).isEqualTo(Optional.fromNullable(expression)) to contains()
when expression is not a non-null constant expression.
</ul>
<p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p>
"""
@@ -36,14 +36,18 @@ val MORE_EXTENSION_POINTS = CallMatcher.instanceCall(
"hasOnlyOneElementSatisfying", "anyMatch", "noneMatch", "anySatisfy", "noneSatisfy"
)!!
val NOT_ACTUAL_ASSERTIONS = CallMatcher.anyOf(
ALL_ASSERT_THAT_MATCHERS,
val COMPLEX_CALLS_THAT_MAKES_STUFF_TRICKY = CallMatcher.anyOf(
DESCRIBED_AS,
WITH_REPRESENTATION_AND_SUCH,
USING_COMPARATOR,
IN_HEXADECIMAL_OR_BINARY
)!!
val NOT_ACTUAL_ASSERTIONS = CallMatcher.anyOf(
ALL_ASSERT_THAT_MATCHERS,
COMPLEX_CALLS_THAT_MAKES_STUFF_TRICKY
)!!
val KNOWN_METHODS_WITH_SIDE_EFFECTS = CallMatcher.anyOf(
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_ITERATOR, "next")
)!!
@@ -106,7 +106,7 @@ fun PsiMethodCallExpression.getExpectedNullNonNullResult(): Boolean? {
if (isNull || isNotNull) {
return isNotNull
} else {
val isEqualTo = AbstractAssertJInspection.IS_EQUAL_TO_OBJECT.test(this)
val isEqualTo = CallMatcher.anyOf(AbstractAssertJInspection.IS_EQUAL_TO_OBJECT, AbstractAssertJInspection.IS_EQUAL_TO_STRING).test(this)
val isNotEqualTo = AbstractAssertJInspection.IS_NOT_EQUAL_TO_OBJECT.test(this)
if ((isEqualTo || isNotEqualTo) && firstArg.type == PsiType.NULL) {
return isNotEqualTo
@@ -86,6 +86,8 @@ class MethodNames {
@NonNls
const val CONTAINS = "contains"
@NonNls
const val CONTAINS_ONLY_ONCE = "containsOnlyOnce"
@NonNls
const val DOES_NOT_CONTAIN = "doesNotContain"
@NonNls
const val CONTAINS_EXACTLY = "containsExactly"
@@ -13,6 +13,7 @@ import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_A
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_BOOLEAN_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_COMPARABLE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_INTEGER_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_STRING_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ASSERTIONS_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ASSERT_INTERFACE
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ENUMERABLE_ASSERT_INTERFACE
@@ -81,6 +82,8 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
val IS_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ASSERT_INTERFACE, MethodNames.IS_EQUAL_TO)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val IS_EQUAL_TO_STRING = CallMatcher.instanceCall(ABSTRACT_STRING_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO)
.parameterTypes(CommonClassNames.JAVA_LANG_STRING)!!
val IS_NOT_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ASSERT_INTERFACE, MethodNames.IS_NOT_EQUAL_TO)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val IS_EQUAL_TO_BOOLEAN = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO)
@@ -30,7 +30,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
val outmostMethodCall = statement.findOutmostMethodCall() ?: return
if (GUAVA_OPTIONAL_GET.test(actualExpression)) {
val expectedCallExpression = staticMethodCall.gatherAssertionCalls().singleOrNull() ?: return
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
if (CallMatcher.anyOf(IS_EQUAL_TO_OBJECT, IS_EQUAL_TO_STRING).test(expectedCallExpression)) {
registerMoveOutMethod(holder, outmostMethodCall, actualExpression, MethodNames.CONTAINS) { desc, method ->
QuickFixWithPostfixDelegate(
RemoveActualOutmostMethodCallQuickFix(desc, method),
@@ -70,6 +70,9 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
if (IS_EQUAL_TO_OBJECT.test(expression)) {
val innerExpectedCall = expression.firstArg as? PsiMethodCallExpression ?: return
if (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
if (GUAVA_OPTIONAL_FROM_NULLABLE.test(innerExpectedCall)) {
innerExpectedCall.firstArg.calculateConstantValue() ?: return
}
registerRemoveExpectedOutmostMethod(holder, expression, expression, MethodNames.CONTAINS) { desc, method ->
QuickFixWithPostfixDelegate(
UnwrapExpectedStaticMethodCallQuickFix(desc, method),
@@ -28,7 +28,7 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
val outmostMethodCall = statement.findOutmostMethodCall() ?: return
if (OPTIONAL_GET.test(actualExpression)) {
val expectedCallExpression = staticMethodCall.gatherAssertionCalls().singleOrNull() ?: return
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
if (CallMatcher.anyOf(IS_EQUAL_TO_OBJECT, IS_EQUAL_TO_STRING).test(expectedCallExpression)) {
registerMoveOutMethod(holder, outmostMethodCall, actualExpression, MethodNames.CONTAINS) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method)
}
@@ -60,6 +60,9 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
if (IS_EQUAL_TO_OBJECT.test(expression)) {
val innerExpectedCall = expression.firstArg as? PsiMethodCallExpression ?: return
if (CallMatcher.anyOf(OPTIONAL_OF, OPTIONAL_OF_NULLABLE).test(innerExpectedCall)) {
if (OPTIONAL_OF_NULLABLE.test(innerExpectedCall)) {
innerExpectedCall.firstArg.calculateConstantValue() ?: return
}
registerRemoveExpectedOutmostMethod(holder, expression, expression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix)
} else if (OPTIONAL_EMPTY.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expression, MethodNames.IS_NOT_PRESENT)
@@ -38,7 +38,7 @@ class AssertThatObjectExpressionInspection : AbstractAssertJInspection() {
}
}
OBJECT_TO_STRING.test(assertThatArgument) -> {
staticMethodCall.findFluentCallTo(IS_EQUAL_TO_OBJECT) ?: return
staticMethodCall.findFluentCallTo(IS_EQUAL_TO_OBJECT) ?: staticMethodCall.findFluentCallTo(IS_EQUAL_TO_STRING) ?: return
registerMoveOutMethod(holder, expectedCallExpression, assertThatArgument, MethodNames.HAS_TO_STRING) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method)
}
@@ -2,6 +2,7 @@ package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.hasAssertThat
@@ -21,7 +22,7 @@ class AssertThatObjectIsNullOrNotNullInspection : AbstractAssertJInspection() {
super.visitMethodCallExpression(expression)
if (!expression.hasAssertThat()) return
val isNotEqualTo = IS_NOT_EQUAL_TO_OBJECT.test(expression)
val isEqualTo = IS_EQUAL_TO_OBJECT.test(expression)
val isEqualTo = CallMatcher.anyOf(IS_EQUAL_TO_OBJECT, IS_EQUAL_TO_STRING).test(expression)
val isLastExpression = expression.parent is PsiStatement
if (!((isEqualTo && isLastExpression) || isNotEqualTo)) return
@@ -5,6 +5,7 @@ import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.calculateConstantParameterValue
@@ -23,7 +24,7 @@ class AssertThatStringIsEmptyInspection : AbstractAssertJInspection() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
if (!expression.hasAssertThat()) return
val isEqual = IS_EQUAL_TO_OBJECT.test(expression)
val isEqual = CallMatcher.anyOf(IS_EQUAL_TO_OBJECT, IS_EQUAL_TO_STRING).test(expression)
val hasSize = HAS_SIZE.test(expression)
val isLastExpression = expression.parent is PsiStatement
if (!((isEqual || hasSize) && isLastExpression)) return
@@ -29,7 +29,7 @@ class ImplicitAssertionInspection : AbstractAssertJInspection() {
private val OBJECT_ENUMERABLE_ANY_CONTENT_ASSERTIONS = CallMatcher.instanceCall(
AssertJClassNames.OBJECT_ENUMERABLE_ASSERT_INTERFACE,
MethodNames.CONTAINS, "containsOnly", "containsOnlyNulls", "containsOnlyOnce",
MethodNames.CONTAINS, "containsOnly", "containsOnlyNulls", MethodNames.CONTAINS_ONLY_ONCE,
"containsExactly", "containsExactlyInAnyOrder", "containsExactlyInAnyOrderElementsOf",
"containsAll", "containsAnyOf",
"containsAnyElementsOf", "containsExactlyElementsOf", "containsOnlyElementsOf",
@@ -0,0 +1,53 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.util.TextRange
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiExpressionStatement
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.util.PsiTreeUtil
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.quickfixes.JoinVarArgsContainsQuickFix
class JoinVarArgsContainsInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Join variadic arguments of contains()/containsOnlyOnce()/doesNotContain()"
private const val JOIN_VARARGS_MESSAGE = "Calls to same methods may be joined to variadic version"
private val MATCHERS = listOf(MethodNames.CONTAINS, MethodNames.CONTAINS_ONLY_ONCE, MethodNames.DOES_NOT_CONTAIN)
.map { CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, it) }
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitExpressionStatement(statement: PsiExpressionStatement) {
super.visitStatement(statement)
if (!statement.hasAssertThat()) return
val assertThatCall = PsiTreeUtil.findChildrenOfType(statement, PsiMethodCallExpression::class.java).find { ALL_ASSERT_THAT_MATCHERS.test(it) } ?: return
val allCalls = assertThatCall.collectMethodCallsUpToStatement().toList()
if (allCalls.find(COMPLEX_CALLS_THAT_MAKES_STUFF_TRICKY::test) != null) return
val onlyAssertionCalls = allCalls
.filterNot { NOT_ACTUAL_ASSERTIONS.test(it) }
.toList()
for (methodMatcher in MATCHERS) {
if (onlyAssertionCalls.count(methodMatcher::test) > 1) {
val outmostMethodCall = statement.findOutmostMethodCall() ?: return
val quickFix = JoinVarArgsContainsQuickFix(MATCHERS)
val textRange = TextRange(outmostMethodCall.qualifierExpression.textLength, outmostMethodCall.textLength)
holder.registerProblem(outmostMethodCall, textRange, JOIN_VARARGS_MESSAGE, quickFix)
return
}
}
}
}
}
}
@@ -0,0 +1,38 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiMethodCallExpression
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.*
class JoinVarArgsContainsQuickFix(private val matchers: Iterable<CallMatcher>) : AbstractCommonQuickFix(JOIN_VARARGS_DESCRIPTION) {
companion object {
private const val JOIN_VARARGS_DESCRIPTION = "Join multiple arguments to variadic argument method calls"
}
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
var outmostCallExpression = descriptor.startElement as? PsiMethodCallExpression ?: return
for (matcher in matchers) {
val assertThatMethodCall = outmostCallExpression.findStaticMethodCall() ?: return
val methodsToFix = assertThatMethodCall.gatherAssertionCalls()
val matchedCalls = methodsToFix.filter(matcher::test)
if (matchedCalls.size > 1) {
val mainCall = matchedCalls.first()
val args = mutableListOf(*mainCall.argumentList.expressions)
for (secondaryCall in matchedCalls.asSequence().drop(1)) {
args.addAll(secondaryCall.argumentList.expressions)
}
val newMainCall = createExpectedMethodCall(mainCall, mainCall.methodExpression.qualifiedName, *args.toTypedArray())
newMainCall.replaceQualifierFromMethodCall(mainCall)
mainCall.replace(newMainCall)
for (secondaryCall in matchedCalls.asSequence().drop(1)) {
val newQualifier = secondaryCall.qualifierExpression
outmostCallExpression = secondaryCall.replace(newQualifier).findOutmostMethodCall() ?: return
}
}
}
}
}
@@ -7,6 +7,7 @@ import com.intellij.psi.*
import com.intellij.psi.util.PropertyUtilBase
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.PsiTypesUtil
import com.intellij.util.ArrayUtil
import com.intellij.util.ProcessingContext
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.*
@@ -70,6 +71,11 @@ class ExtractorReferenceContributor : PsiReferenceContributor() {
class ExtractorReference(literal: PsiLiteralExpression, range: TextRange, private val targets: List<PsiElement>) :
PsiPolyVariantReferenceBase<PsiLiteralExpression>(literal, range, true) {
// Do not remove due to compatiblity issue with IDEA <= 2018.2
override fun getVariants(): Array<Any> {
return ArrayUtil.EMPTY_OBJECT_ARRAY
}
override fun resolve(): PsiElement? {
return multiResolve(false).map(ResolveResult::getElement).firstOrNull()
}
+3 -1
View File
@@ -1,7 +1,7 @@
<idea-plugin>
<id>de.platon42.cajon</id>
<name>Concise AssertJ Optimizing Nitpicker (Cajon)</name>
<vendor email="chrisly@platon42.de" url="https://github.com/chrisly42/cajon-plugin">Platon42</vendor>
<vendor email="chrisly@platon42.de" url="https://github.com/chrisly42/cajon-plugin">Chris 'platon42' Hodges</vendor>
<description><![CDATA[
Cajon is an IntelliJ IDEA Plugin for shortening and optimizing AssertJ assertions.
@@ -48,6 +48,8 @@
<localInspection groupPath="Java" shortName="JoinAssertThatStatements" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.JoinAssertThatStatementsInspection"/>
<localInspection groupPath="Java" shortName="JoinVarArgsContains" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.JoinVarArgsContainsInspection"/>
<localInspection groupPath="Java" shortName="AssumeThatInsteadOfReturn" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssumeThatInsteadOfReturnInspection"/>
@@ -0,0 +1,11 @@
<html>
<body>
Finds assertions where multiple .contains(), .containsOnlyOnce() or .doesNotContain() are
used in a single statement that could be joined together.
<!-- tooltip end -->
Only works when variadic arguments are possible and will not be performed on more complex
statements with .extracting() or .as() to avoid changing semantics.
<br>
Note that the quickfix does not handle comments very well and might remove them during the operation.
</body>
</html>
@@ -11,7 +11,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.*;
import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy;
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.extension.*;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
@@ -88,7 +88,6 @@ public class LightCodeInsightExtension implements ParameterResolver, AfterTestEx
TestLoggerFactory.onTestFinished(true);
} catch (Throwable e) {
TestLoggerFactory.onTestFinished(false);
e.fillInStackTrace();
throwables[0] = e;
}
};
@@ -112,7 +111,7 @@ public class LightCodeInsightExtension implements ParameterResolver, AfterTestEx
}
}
private static class LightCodeInsightFixtureTestCaseWrapper extends LightCodeInsightFixtureTestCase {
private static class LightCodeInsightFixtureTestCaseWrapper extends LightJavaCodeInsightFixtureTestCase {
private final ExtensionContext extensionContext;
private LightCodeInsightFixtureTestCaseWrapper(ExtensionContext extensionContext) {
@@ -159,7 +158,7 @@ public class LightCodeInsightExtension implements ParameterResolver, AfterTestEx
};
}
protected void addJarContaining(ModifiableRootModel model, Class clazz) {
void addJarContaining(ModifiableRootModel model, Class clazz) {
try {
Path jarPath = Paths.get(clazz.getProtectionDomain().getCodeSource().getLocation().toURI());
@@ -0,0 +1,19 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class JoinVarArgsContainsInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/JoinVarArgsContains")
internal fun join_contains_and_doesNotContain_together_where_possible(@MyFixture myFixture: JavaCodeInsightTestFixture) {
myFixture.enableInspections(JoinVarArgsContainsInspection::class.java)
myFixture.configureByFile("JoinVarArgsContainsBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Join multiple arguments to variadic argument method calls"), 3)
myFixture.checkResultByFile("JoinVarArgsContainsAfter.java")
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class BinaryExpression {
@@ -196,7 +197,7 @@ public class BinaryExpression {
assertThat(numberObjAct.equals(numberObjExp)).as("doh!").isTrue().isEqualTo(true);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(stringAct, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class BinaryExpression {
@@ -196,7 +197,7 @@ public class BinaryExpression {
assertThat(numberObjAct.equals(numberObjExp)).as("doh!").isTrue().isEqualTo(true);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(stringAct, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class BooleanCondition {
@@ -32,7 +33,7 @@ public class BooleanCondition {
assertThat(primitive).isTrue().as("foo").isTrue().as("bar").isTrue().isFalse();
assertThat(object).isEqualTo(Boolean.TYPE);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(object, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class BooleanCondition {
@@ -32,7 +33,7 @@ public class BooleanCondition {
assertThat(primitive).isEqualTo(Boolean.TRUE).as("foo").isEqualTo(true).as("bar").isTrue().isFalse();
assertThat(object).isEqualTo(Boolean.TYPE);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(object, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import java.util.*;
@@ -41,7 +42,7 @@ public class CollectionMapExpression {
assertThat(stringList.isEmpty()).as("foo").isEqualTo(false).as("bar").isTrue();
assertThat(stringList.isEmpty()).as("foo").satisfies(it -> it.booleanValue()).as("bar").isFalse();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(stringList, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import java.util.*;
@@ -41,7 +42,7 @@ public class CollectionMapExpression {
assertThat(stringList.isEmpty()).as("foo").isEqualTo(false).as("bar").isTrue();
assertThat(stringList.isEmpty()).as("foo").satisfies(it -> it.booleanValue()).as("bar").isFalse();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(stringList, null);
fail("oh no!");
}
}
@@ -1,6 +1,7 @@
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class EnumerableIsEmpty {
@@ -17,7 +18,7 @@ public class EnumerableIsEmpty {
assertThat("string").as("foo").hasSize(0).hasSameSizeAs("foo").isEmpty();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat("foo", null);
fail("oh no!");
}
}
@@ -1,6 +1,7 @@
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class EnumerableIsEmpty {
@@ -17,7 +18,7 @@ public class EnumerableIsEmpty {
assertThat("string").as("foo").hasSize(0).hasSameSizeAs("foo").hasSize(0);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat("foo", null);
fail("oh no!");
}
}
@@ -1,6 +1,7 @@
import com.google.common.base.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.guava.api.Assertions.assertThat;
public class GuavaOptional {
@@ -30,8 +31,21 @@ public class GuavaOptional {
assertThat(opt).isPresent();
assertThat(opt).isPresent();
//assertThat(opt.get()).isEqualTo(opt.get()); // there's a better version than contains(opt.get())
assertThat(opt.orNull()).isEqualTo(opt.get());
//assertThat(opt.get()).isEqualTo(opt.orNull()); // there's a better version than contains(opt.orNull())
assertThat(opt).contains(opt.get());
assertThat(opt).contains(opt.orNull());
String possibleNullString = System.getProperty("username");
String notNullString = "Narf";
assertThat(opt).as("foo").contains("foo");
assertThat(opt).contains("foo");
assertThat(opt).isEqualTo(Optional.fromNullable(null));
assertThat(opt).isEqualTo(Optional.fromNullable(possibleNullString));
assertThat(opt).isEqualTo(Optional.fromNullable(notNullString));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
@@ -59,7 +73,7 @@ public class GuavaOptional {
assertThat(opt.orNull()).as("foo").isEqualTo(null).isNotNull();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(opt, null);
fail("oh no!");
}
}
@@ -1,6 +1,7 @@
import com.google.common.base.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.guava.api.Assertions.assertThat;
public class GuavaOptional {
@@ -30,8 +31,21 @@ public class GuavaOptional {
assertThat(opt.orNull()).isNotEqualTo(null);
assertThat(opt.orNull()).isNotNull();
//assertThat(opt.get()).isEqualTo(opt.get()); // there's a better version than contains(opt.get())
assertThat(opt.orNull()).isEqualTo(opt.get());
//assertThat(opt.get()).isEqualTo(opt.orNull()); // there's a better version than contains(opt.orNull())
assertThat(opt).contains(opt.get());
assertThat(opt).contains(opt.orNull());
String possibleNullString = System.getProperty("username");
String notNullString = "Narf";
assertThat(opt).as("foo").isEqualTo(Optional.of("foo"));
assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isEqualTo(Optional.fromNullable(null));
assertThat(opt).isEqualTo(Optional.fromNullable(possibleNullString));
assertThat(opt).isEqualTo(Optional.fromNullable(notNullString));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
@@ -59,7 +73,7 @@ public class GuavaOptional {
assertThat(opt.orNull()).as("foo").isEqualTo(null).isNotNull();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(opt, null);
fail("oh no!");
}
}
@@ -6,6 +6,7 @@ import java.util.Optional;
import java.util.function.Consumer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.guava.api.Assertions.assertThat;
public class ImplicitAssertion {
@@ -285,7 +286,7 @@ public class ImplicitAssertion {
assertThat(guavaOptional).extractingValue().isEqualTo("foo");
assertThat(guavaOptional).extractingCharSequence().isEqualTo("foo");
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(string, null);
fail("oh no!");
}
}
@@ -6,6 +6,7 @@ import java.util.Optional;
import java.util.function.Consumer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.guava.api.Assertions.assertThat;
public class ImplicitAssertion {
@@ -285,7 +286,7 @@ public class ImplicitAssertion {
assertThat(guavaOptional).isPresent().extractingValue().isEqualTo("foo");
assertThat(guavaOptional).isPresent().extractingCharSequence().isEqualTo("foo");
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(string, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class InstanceOf {
@@ -22,7 +23,7 @@ public class InstanceOf {
assertThat(object).as("foo").isInstanceOf(Boolean.class).as("bar").isInstanceOf(Boolean.class);
assertThat(object instanceof Boolean).as("foo").isEqualTo(Boolean.TRUE).as("bar").isEqualTo(false);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(object, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class InstanceOf {
@@ -22,7 +23,7 @@ public class InstanceOf {
assertThat(object instanceof Boolean).as("foo").isEqualTo(Boolean.TRUE).as("bar").isEqualTo(true);
assertThat(object instanceof Boolean).as("foo").isEqualTo(Boolean.TRUE).as("bar").isEqualTo(false);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(object, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class InvertedBooleanCondition {
@@ -36,7 +37,7 @@ public class InvertedBooleanCondition {
assertThat(primitive).as("foo").isFalse().as("bar").isFalse();
assertThat(primitive).as("foo").isFalse().as("bar").isTrue();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(object, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class InvertedBooleanCondition {
@@ -36,7 +37,7 @@ public class InvertedBooleanCondition {
assertThat(!primitive).as("foo").isEqualTo(Boolean.TRUE).as("bar").isNotEqualTo(false);
assertThat(!primitive).as("foo").isEqualTo(Boolean.TRUE).as("bar").isNotEqualTo(true);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(object, null);
fail("oh no!");
}
}
@@ -1,6 +1,7 @@
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class Java8Optional {
@@ -29,8 +30,21 @@ public class Java8Optional {
assertThat(opt).isPresent();
assertThat(opt).isPresent();
//assertThat(opt.get()).isEqualTo(opt.get()); // there's a better version than contains(opt.get())
assertThat(opt.orElse(null)).isEqualTo(opt.get());
//assertThat(opt.get()).isEqualTo(opt.orElse(null)); // there's a better version than contains(opt.orElse(null))
assertThat(opt).contains(opt.get());
assertThat(opt).contains(opt.orElse(null));
String possibleNullString = System.getProperty("username");
String notNullString = "Narf";
assertThat(opt).as("foo").contains("foo");
assertThat(opt).contains("foo");
assertThat(opt).isEqualTo(Optional.ofNullable(null));
assertThat(opt).isEqualTo(Optional.ofNullable(possibleNullString));
assertThat(opt).isEqualTo(Optional.ofNullable(notNullString));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.ofNullable("foo"));
@@ -46,7 +60,7 @@ public class Java8Optional {
assertThat(opt.orElse(null)).as("foo").isEqualTo(null).isNotNull();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(opt, null);
fail("oh no!");
}
}
@@ -1,6 +1,7 @@
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class Java8Optional {
@@ -29,8 +30,21 @@ public class Java8Optional {
assertThat(opt.orElse(null)).isNotEqualTo(null);
assertThat(opt.orElse(null)).isNotNull();
//assertThat(opt.get()).isEqualTo(opt.get()); // there's a better version than contains(opt.get())
assertThat(opt.orElse(null)).isEqualTo(opt.get());
//assertThat(opt.get()).isEqualTo(opt.orElse(null)); // there's a better version than contains(opt.orElse(null))
assertThat(opt).contains(opt.get());
assertThat(opt).contains(opt.orElse(null));
String possibleNullString = System.getProperty("username");
String notNullString = "Narf";
assertThat(opt).as("foo").isEqualTo(Optional.of("foo"));
assertThat(opt).isEqualTo(Optional.ofNullable("foo"));
assertThat(opt).isEqualTo(Optional.ofNullable(null));
assertThat(opt).isEqualTo(Optional.ofNullable(possibleNullString));
assertThat(opt).isEqualTo(Optional.ofNullable(notNullString));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.ofNullable("foo"));
@@ -46,7 +60,7 @@ public class Java8Optional {
assertThat(opt.orElse(null)).as("foo").isEqualTo(null).isNotNull();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(opt, null);
fail("oh no!");
}
}
@@ -66,7 +66,7 @@ public class JoinStatements {
assertThat(list.get(--i)).isEqualTo("foo");
assertThat(list.get(--i)).isEqualTo("foo");
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(list, null);
fail("oh no!");
}
}
@@ -63,7 +63,7 @@ public class JoinStatements {
assertThat(list.get(--i)).isEqualTo("foo");
assertThat(list.get(--i)).isEqualTo("foo");
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(list, null);
fail("oh no!");
}
}
@@ -0,0 +1,22 @@
import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class JoinVarArgsContains {
private void joinVarArgsContains() {
List<String> list = new ArrayList<>();
assertThat(list).contains("foo", "bar", "etc").hasSize(2);
assertThat(list).contains("foo").as("narf").contains("bar");
assertThat(list).doesNotContain("foo", "bar");
assertThat(list).containsOnlyOnce("foo", "etc") // will we lose this comment?
.hasSize(2).contains("bar", "narf", "1", "2", "3").doesNotContain("puit", "Jens Stoltenberg is a war-monger", "and an atomic playboy") /* inline */; // the final comment
assertThat(list).contains("foo").doesNotContain("bar").containsOnlyOnce("narf");
org.junit.Assert.assertThat(list, null);
fail("oh no!");
}
}
@@ -0,0 +1,28 @@
import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class JoinVarArgsContains {
private void joinVarArgsContains() {
List<String> list = new ArrayList<>();
assertThat(list).contains("foo").contains(/* foo */ "bar" /* bar */).hasSize(2).contains("etc");
assertThat(list).contains("foo").as("narf").contains("bar");
assertThat(list).doesNotContain("foo").doesNotContain("bar");
assertThat(list).containsOnlyOnce()
.containsOnlyOnce("foo") // will we lose this comment?
.hasSize(2) // this is part of the contains("bar")
.contains("bar").containsOnlyOnce("etc") /* where does this go? */
.contains("narf") // what about this one?
.doesNotContain("puit", "Jens Stoltenberg is a war-monger")
.doesNotContain("and an atomic playboy")
.contains("1", "2", "3") /* inline */; // the final comment
assertThat(list).contains("foo").doesNotContain("bar").containsOnlyOnce("narf");
org.junit.Assert.assertThat(list, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class ObjectExpression {
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class ObjectExpression {
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class ObjectIsNull {
@@ -14,7 +15,7 @@ public class ObjectIsNull {
assertThat(new Object()).as("foo").isNotNull().as("bar").isEqualTo(new Object()).as("etc").isNull();
assertThat(new Object()).as("foo").isEqualTo(null).as("bar").isEqualTo(new Object()).as("etc").isNotNull();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat("foo", null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class ObjectIsNull {
@@ -14,7 +15,7 @@ public class ObjectIsNull {
assertThat(new Object()).as("foo").isNotEqualTo(null).as("bar").isEqualTo(new Object()).as("etc").isEqualTo(null);
assertThat(new Object()).as("foo").isEqualTo(null).as("bar").isEqualTo(new Object()).as("etc").isNotEqualTo(null);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat("foo", null);
fail("oh no!");
}
}
@@ -1,6 +1,7 @@
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class Size {
@@ -104,7 +105,7 @@ public class Size {
assertThat(foo).isEqualTo(0);
assertThat(string.length()).isPositive();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(string, null);
fail("oh no!");
}
}
@@ -1,6 +1,7 @@
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class Size {
@@ -104,7 +105,7 @@ public class Size {
assertThat(foo).isEqualTo(0);
assertThat(string.length()).isPositive();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(string, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class StringExpression {
@@ -50,7 +51,7 @@ public class StringExpression {
assertThat(string.endsWith("foo")).as("foo").isEqualTo(false).as("bar").isTrue();
assertThat(string.endsWith("foo")).as("foo").satisfies(it -> it.booleanValue()).as("bar").isFalse();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(string, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class StringExpression {
@@ -50,7 +51,7 @@ public class StringExpression {
assertThat(string.endsWith("foo")).as("foo").isEqualTo(false).as("bar").isTrue();
assertThat(string.endsWith("foo")).as("foo").satisfies(it -> it.booleanValue()).as("bar").isFalse();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(string, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class StringIsEmpty {
@@ -19,7 +20,7 @@ public class StringIsEmpty {
assertThat(string).as("foo").isEqualTo("").as("bar").hasSize(0).hasSameSizeAs("foo").isEmpty();
assertThat(string).as("foo").isEqualTo("").as("bar").hasSize(0).hasSameSizeAs("foo").isEmpty();
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(string, null);
fail("oh no!");
}
}
@@ -1,4 +1,5 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class StringIsEmpty {
@@ -19,7 +20,7 @@ public class StringIsEmpty {
assertThat(string).as("foo").isEqualTo("").as("bar").hasSize(0).hasSameSizeAs("foo").isEqualTo("");
assertThat(string).as("foo").isEqualTo("").as("bar").hasSize(0).hasSameSizeAs("foo").hasSize(0);
org.junit.Assert.assertThat(foo, null);
org.junit.Assert.assertThat(string, null);
fail("oh no!");
}
}