Compare commits

..
3 Commits
19 changed files with 104 additions and 57 deletions
+1
View File
@@ -18,6 +18,7 @@
<option name="configurationPath" value="" /> <option name="configurationPath" value="" />
<option name="exclusions"> <option name="exclusions">
<set> <set>
<option value=".*\.md" />
<option value="src/test/resources/.*" /> <option value="src/test/resources/.*" />
</set> </set>
</option> </option>
+11 -3
View File
@@ -798,7 +798,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
## Development notice ## Development notice
Cajon is written in Kotlin 1.3. Cajon is written in Kotlin 1.4.
Cajon is probably the only plugin that uses JUnit 5 Jupiter for unit testing so far (or at least the only one I'm aware of ;) ). Cajon is probably the only plugin that uses JUnit 5 Jupiter for unit testing so far (or at least the only one I'm aware of ;) ).
The IntelliJ framework actually uses the JUnit 3 TestCase for plugin testing, and it took me quite a while to make it work with JUnit 5. The IntelliJ framework actually uses the JUnit 3 TestCase for plugin testing, and it took me quite a while to make it work with JUnit 5.
@@ -817,13 +817,21 @@ Feel free to use the code (in package ```de.platon42.intellij.jupiter```) for yo
## Changelog ## Changelog
### V1.12 (06-May-21)
- Maintenance. Updated various dependencies (Kotlin 1.50.0) and AssertJ 3.19.0
- Fixed issue#3 reported by hankem where usingRecursiveComparison() was not considered a complex transformation.
#### V1.11 (03-Oct-20) Day of German Unity Edition #### V1.11 (03-Oct-20) Day of German Unity Edition
- Now is being built with JDK 11 (with Java 8 target). - Now is being built with JDK 11 (with Java 8 target).
- Updated various dependencies (Kotlin 1.40.10) and AssertJ 3.17.2. - Updated various dependencies (Kotlin 1.40.10) and AssertJ 3.17.2.
- Fixed the ImplicitAssertion inspection that broke the plugin with IntelliJ 2020.3 EAP as reported by Frédéric Thomas. Thanks! - Fixed the ImplicitAssertion inspection that broke the plugin with IntelliJ 2020.3 EAP as reported by Frédéric Thomas.
Thanks!
- Added new singleElement() from AssertJ >= 3.17.0 to ImplicitAssertionInspection. - Added new singleElement() from AssertJ >= 3.17.0 to ImplicitAssertionInspection.
- Added several cases for ```hasSizeGreaterThan/LessThan/OrEqualTo()``` for EnumerablesEmpty inspection. - Added several cases for ```hasSizeGreaterThan/LessThan/OrEqualTo()``` for EnumerablesEmpty inspection.
- Added inversion of boolean conditions inside ```isEqualTo()``` and ```isNotEqualTo()``` for InvertedBooleanCondition inspection. - Added inversion of boolean conditions inside ```isEqualTo()``` and ```isNotEqualTo()``` for InvertedBooleanCondition
inspection.
#### V1.10 (31-Jul-20) Friday the 31st Edition #### V1.10 (31-Jul-20) Friday the 31st Edition
- Updated libraries to the latest versions (including AssertJ 3.16.1 and Kotlin 1.40-rc). - Updated libraries to the latest versions (including AssertJ 3.16.1 and Kotlin 1.40-rc).
+12 -16
View File
@@ -1,13 +1,13 @@
plugins { plugins {
id 'java' id 'java'
id 'org.jetbrains.intellij' version '0.4.26' id 'org.jetbrains.intellij' version '0.7.2'
id 'org.jetbrains.kotlin.jvm' version '1.4.10' id 'org.jetbrains.kotlin.jvm' version '1.5.0'
id 'jacoco' id 'jacoco'
id 'com.github.kt3k.coveralls' version '2.10.2' id 'com.github.kt3k.coveralls' version '2.11.0'
} }
group 'de.platon42' group 'de.platon42'
version '1.11' version '1.12'
sourceCompatibility = "1.8" sourceCompatibility = "1.8"
targetCompatibility = "1.8" targetCompatibility = "1.8"
@@ -22,10 +22,10 @@ repositories {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testImplementation "org.assertj:assertj-core:3.17.2" testImplementation "org.assertj:assertj-core:3.19.0"
testImplementation "org.assertj:assertj-guava:3.4.0" testImplementation "org.assertj:assertj-guava:3.4.0"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.0-M1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.0-M1'
testImplementation "org.jetbrains.kotlin:kotlin-test" testImplementation "org.jetbrains.kotlin:kotlin-test"
// testImplementation "org.jetbrains.kotlin:kotlin-test-junit" // testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
} }
@@ -39,7 +39,7 @@ compileTestKotlin {
} }
intellij { intellij {
version '2020.2.2' // LATEST-EAP-SNAPSHOT version '2021.1.1' // LATEST-EAP-SNAPSHOT
// pluginName 'Concise AssertJ Optimizing Nitpicker (Cajon)' // pluginName 'Concise AssertJ Optimizing Nitpicker (Cajon)'
updateSinceUntilBuild false updateSinceUntilBuild false
plugins = ['java'] plugins = ['java']
@@ -47,14 +47,10 @@ intellij {
patchPluginXml { patchPluginXml {
changeNotes """ changeNotes """
<h4>V1.11 (03-Oct-20) Day of German Unity Edition</h4> <h4>V1.12 (06-May-21)</h4>
<ul> <ul>
<li>Now is being built with JDK 11 (with Java 8 target). <li>Maintenance. Updated various dependencies (Kotlin 1.50.0) and AssertJ 3.19.0
<li>Updated various dependencies (Kotlin 1.40.10) and AssertJ 3.17.2. <li>Fixed issue#3 reported by hankem where usingRecursiveComparison() was not considered a complex transformation.
<li>Fixed the ImplicitAssertion inspection that broke the plugin with IntelliJ 2020.3 EAP as reported by Frédéric Thomas. Thanks!
<li>Added new singleElement() from AssertJ >= 3.17.0 to ImplicitAssertionInspection.
<li>Added several cases for hasSizeGreaterThan/LessThan/OrEqualTo() for EnumerablesEmpty inspection.
<li>Added inversion of boolean conditions inside isEqualTo() and isNotEqualTo() for InvertedBooleanCondition inspection.
</ul> </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>
""" """
@@ -68,7 +64,7 @@ test {
} }
jacoco { jacoco {
toolVersion = '0.8.6' toolVersion = '0.8.7'
} }
jacocoTestReport { jacocoTestReport {
+2 -1
View File
@@ -1,3 +1,4 @@
kotlin.code.style=official kotlin.code.style=official
kotlin.incremental=true kotlin.incremental=true
intellijPublishToken=perm:dummy intellijPublishToken=perm:dummy
systemProp.jdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"
@@ -21,13 +21,27 @@ val EXTRACTING_CALL_MATCHERS = CallMatcher.anyOf(
val DESCRIBED_AS = CallMatcher.instanceCall(AssertJClassNames.DESCRIPTABLE_INTERFACE, MethodNames.DESCRIBED_AS, MethodNames.AS)!! val DESCRIBED_AS = CallMatcher.instanceCall(AssertJClassNames.DESCRIPTABLE_INTERFACE, MethodNames.DESCRIBED_AS, MethodNames.AS)!!
val WITH_REPRESENTATION_AND_SUCH = CallMatcher.instanceCall(AssertJClassNames.ASSERT_INTERFACE, "withRepresentation", "withThreadDumpOnError")!! val WITH_REPRESENTATION_AND_SUCH = CallMatcher.instanceCall(AssertJClassNames.ASSERT_INTERFACE, "withRepresentation", "withThreadDumpOnError")!!
val USING_COMPARATOR = CallMatcher.instanceCall(AssertJClassNames.ASSERT_INTERFACE, "usingComparator", "usingDefaultComparator")!! val USING_COMPARATOR = CallMatcher.anyOf(
CallMatcher.instanceCall(
AssertJClassNames.ASSERT_INTERFACE,
"usingComparator",
"usingDefaultComparator"
),
CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ASSERT_CLASSNAME, "usingRecursiveComparison"),
CallMatcher.instanceCall(
AssertJClassNames.ABSTRACT_OBJECT_ASSERT_CLASSNAME,
"usingComparatorForFields",
"usingComparatorForType"
)
)!!
val IN_HEXADECIMAL_OR_BINARY = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ASSERT_CLASSNAME, MethodNames.IN_HEXADECIMAL, MethodNames.IN_BINARY)!! val IN_HEXADECIMAL_OR_BINARY = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ASSERT_CLASSNAME, MethodNames.IN_HEXADECIMAL, MethodNames.IN_BINARY)!!
val EXTENSION_POINTS = CallMatcher.instanceCall( val EXTENSION_POINTS = CallMatcher.instanceCall(
AssertJClassNames.EXTENSION_POINTS_INTERFACE, AssertJClassNames.EXTENSION_POINTS_INTERFACE,
"is", "isNot", "has", "doesNotHave", "is", "isNot", "has", "doesNotHave",
"satisfies" "satisfies"
)!! )!!
val MORE_EXTENSION_POINTS = CallMatcher.instanceCall( val MORE_EXTENSION_POINTS = CallMatcher.instanceCall(
AssertJClassNames.OBJECT_ENUMERABLE_ASSERT_INTERFACE, AssertJClassNames.OBJECT_ENUMERABLE_ASSERT_INTERFACE,
"are", "areNot", "have", "doNotHave", "are", "areNot", "have", "doNotHave",
@@ -177,12 +177,12 @@ abstract class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool()
.parameterCount(0)!! .parameterCount(0)!!
val CHAR_SEQUENCE_LENGTH = CallMatcher.instanceCall("java.lang.CharSequence", "length") val CHAR_SEQUENCE_LENGTH = CallMatcher.instanceCall("java.lang.CharSequence", "length")
.parameterCount(0)!! .parameterCount(0)!!
val OBJECT_EQUALS = CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_OBJECT, "equals") val OBJECT_EQUALS = CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_OBJECT, MethodNames.EQUALS)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!! .parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val OPTIONAL_GET = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "get") val OPTIONAL_GET = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "get")
.parameterCount(0)!! .parameterCount(0)!!
val OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "isPresent") val OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, MethodNames.IS_PRESENT)
.parameterCount(0)!! .parameterCount(0)!!
val OPTIONAL_OR_ELSE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "orElse") val OPTIONAL_OR_ELSE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "orElse")
.parameterCount(1)!! .parameterCount(1)!!
@@ -196,7 +196,7 @@ abstract class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool()
val GUAVA_OPTIONAL_GET = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "get") val GUAVA_OPTIONAL_GET = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "get")
.parameterCount(0)!! .parameterCount(0)!!
val GUAVA_OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "isPresent") val GUAVA_OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, MethodNames.IS_PRESENT)
.parameterCount(0)!! .parameterCount(0)!!
val GUAVA_OPTIONAL_OR_NULL = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "orNull") val GUAVA_OPTIONAL_OR_NULL = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "orNull")
.parameterCount(0)!! .parameterCount(0)!!
@@ -4,39 +4,51 @@ import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
open class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTool() { abstract class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTool() {
companion object { companion object {
@NonNls @NonNls
const val JUNIT_ASSERT_CLASSNAME = "org.junit.Assert" const val JUNIT_ASSERT_CLASSNAME = "org.junit.Assert"
@NonNls @NonNls
const val JUNIT_ASSUME_CLASSNAME = "org.junit.Assume" const val JUNIT_ASSUME_CLASSNAME = "org.junit.Assume"
@NonNls @NonNls
const val ASSERT_TRUE_METHOD = "assertTrue" const val ASSERT_TRUE_METHOD = "assertTrue"
@NonNls @NonNls
const val ASSERT_FALSE_METHOD = "assertFalse" const val ASSERT_FALSE_METHOD = "assertFalse"
@NonNls @NonNls
const val ASSERT_NULL_METHOD = "assertNull" const val ASSERT_NULL_METHOD = "assertNull"
@NonNls @NonNls
const val ASSERT_NOT_NULL_METHOD = "assertNotNull" const val ASSERT_NOT_NULL_METHOD = "assertNotNull"
@NonNls @NonNls
const val ASSERT_EQUALS_METHOD = "assertEquals" const val ASSERT_EQUALS_METHOD = "assertEquals"
@NonNls @NonNls
const val ASSERT_NOT_EQUALS_METHOD = "assertNotEquals" const val ASSERT_NOT_EQUALS_METHOD = "assertNotEquals"
@NonNls @NonNls
const val ASSERT_SAME_METHOD = "assertSame" const val ASSERT_SAME_METHOD = "assertSame"
@NonNls @NonNls
const val ASSERT_NOT_SAME_METHOD = "assertNotSame" const val ASSERT_NOT_SAME_METHOD = "assertNotSame"
@NonNls @NonNls
const val ASSERT_ARRAY_EQUALS_METHOD = "assertArrayEquals" const val ASSERT_ARRAY_EQUALS_METHOD = "assertArrayEquals"
@NonNls @NonNls
const val ASSUME_TRUE_METHOD = "assumeTrue" const val ASSUME_TRUE_METHOD = "assumeTrue"
@NonNls @NonNls
const val ASSUME_FALSE_METHOD = "assumeFalse" const val ASSUME_FALSE_METHOD = "assumeFalse"
@NonNls @NonNls
const val ASSUME_NOT_NULL_METHOD = "assumeNotNull" const val ASSUME_NOT_NULL_METHOD = "assumeNotNull"
@NonNls @NonNls
const val ASSUME_NO_EXCEPTION = "assumeNoException" const val ASSUME_NO_EXCEPTION = "assumeNoException"
@@ -27,9 +27,9 @@ class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() {
val value = expression.calculateConstantParameterValue(0) ?: return val value = expression.calculateConstantParameterValue(0) ?: return
val isEmpty = (CallMatcher.anyOf(HAS_SIZE, HAS_SIZE_LESS_THAN_OR_EQUAL_TO_INT).test(expression) && (value == 0)) || val isEmpty = (CallMatcher.anyOf(HAS_SIZE, HAS_SIZE_LESS_THAN_OR_EQUAL_TO_INT).test(expression) && (value == 0)) ||
(HAS_SIZE_LESS_THAN_INT.test(expression) && (value == 1)); (HAS_SIZE_LESS_THAN_INT.test(expression) && (value == 1))
val isNotEmpty = (HAS_SIZE_GREATER_THAN_INT.test(expression) && (value == 0)) || val isNotEmpty = (HAS_SIZE_GREATER_THAN_INT.test(expression) && (value == 0)) ||
(HAS_SIZE_GREATER_THAN_OR_EQUAL_TO_INT.test(expression) && (value == 1)); (HAS_SIZE_GREATER_THAN_OR_EQUAL_TO_INT.test(expression) && (value == 1))
if (isEmpty && isLastExpression) { if (isEmpty && isLastExpression) {
registerSimplifyMethod(holder, expression, MethodNames.IS_EMPTY) registerSimplifyMethod(holder, expression, MethodNames.IS_EMPTY)
@@ -79,25 +79,25 @@ class AssertThatFileExpressionInspection : AbstractMoveOutInspection() {
private val MAPPINGS_SINCE_ASSERTJ_3_14_0 = listOf( private val MAPPINGS_SINCE_ASSERTJ_3_14_0 = listOf(
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0), CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0),
"isEmpty", expectedMatcher = IS_ZERO_LONG, noExpectedExpression = true MethodNames.IS_EMPTY, expectedMatcher = IS_ZERO_LONG, noExpectedExpression = true
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0), CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0),
"isEmpty", expectedMatcher = IS_EQUAL_TO_LONG, noExpectedExpression = true, MethodNames.IS_EMPTY, expectedMatcher = IS_EQUAL_TO_LONG, noExpectedExpression = true,
additionalCondition = ARG_IS_ZERO_CONST additionalCondition = ARG_IS_ZERO_CONST
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0), CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0),
"isNotEmpty", expectedMatcher = IS_NOT_ZERO_LONG, noExpectedExpression = true MethodNames.IS_NOT_EMPTY, expectedMatcher = IS_NOT_ZERO_LONG, noExpectedExpression = true
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0), CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0),
"isNotEmpty", expectedMatcher = IS_NOT_EQUAL_TO_LONG, noExpectedExpression = true, MethodNames.IS_NOT_EMPTY, expectedMatcher = IS_NOT_EQUAL_TO_LONG, noExpectedExpression = true,
additionalCondition = ARG_IS_ZERO_CONST additionalCondition = ARG_IS_ZERO_CONST
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0), CallMatcher.instanceCall(CommonClassNames.JAVA_IO_FILE, "length").parameterCount(0),
"hasSize", expectedMatcher = IS_EQUAL_TO_LONG, MethodNames.HAS_SIZE, expectedMatcher = IS_EQUAL_TO_LONG,
additionalCondition = ARG_IS_NOT_ZERO_CONST additionalCondition = ARG_IS_NOT_ZERO_CONST
) )
) )
@@ -5,6 +5,7 @@ import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiExpressionStatement import com.intellij.psi.PsiExpressionStatement
import com.siyeh.ig.callMatcher.CallMatcher import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.MethodNames
class AssertThatPathExpressionInspection : AbstractMoveOutInspection() { class AssertThatPathExpressionInspection : AbstractMoveOutInspection() {
@@ -19,11 +20,11 @@ class AssertThatPathExpressionInspection : AbstractMoveOutInspection() {
"isAbsolute", "isRelative", expectBoolean = true "isAbsolute", "isRelative", expectBoolean = true
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(JAVA_NIO_PATH, "startsWith").parameterTypes(JAVA_NIO_PATH), CallMatcher.instanceCall(JAVA_NIO_PATH, MethodNames.STARTS_WITH).parameterTypes(JAVA_NIO_PATH),
"startsWithRaw", expectBoolean = true "startsWithRaw", expectBoolean = true
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(JAVA_NIO_PATH, "endsWith").parameterTypes(JAVA_NIO_PATH), CallMatcher.instanceCall(JAVA_NIO_PATH, MethodNames.ENDS_WITH).parameterTypes(JAVA_NIO_PATH),
"endsWithRaw", expectBoolean = true "endsWithRaw", expectBoolean = true
), ),
MoveOutMapping( MoveOutMapping(
@@ -22,12 +22,12 @@ class AssertThatStringExpressionInspection : AbstractMoveOutInspection() {
private val MAPPINGS = listOf( private val MAPPINGS = listOf(
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "isEmpty").parameterCount(0), CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, MethodNames.IS_EMPTY).parameterCount(0),
MethodNames.IS_EMPTY, MethodNames.IS_NOT_EMPTY, expectBoolean = true MethodNames.IS_EMPTY, MethodNames.IS_NOT_EMPTY, expectBoolean = true
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.anyOf( CallMatcher.anyOf(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "equals").parameterCount(1), CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, MethodNames.EQUALS).parameterCount(1),
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "contentEquals").parameterCount(1) CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "contentEquals").parameterCount(1)
), ),
MethodNames.IS_EQUAL_TO, MethodNames.IS_NOT_EQUAL_TO, expectBoolean = true MethodNames.IS_EQUAL_TO, MethodNames.IS_NOT_EQUAL_TO, expectBoolean = true
@@ -37,15 +37,15 @@ class AssertThatStringExpressionInspection : AbstractMoveOutInspection() {
MethodNames.IS_EQUAL_TO_IC, MethodNames.IS_NOT_EQUAL_TO_IC, expectBoolean = true MethodNames.IS_EQUAL_TO_IC, MethodNames.IS_NOT_EQUAL_TO_IC, expectBoolean = true
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "contains").parameterCount(1), CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, MethodNames.CONTAINS).parameterCount(1),
MethodNames.CONTAINS, MethodNames.DOES_NOT_CONTAIN, expectBoolean = true MethodNames.CONTAINS, MethodNames.DOES_NOT_CONTAIN, expectBoolean = true
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "startsWith").parameterTypes(CommonClassNames.JAVA_LANG_STRING), CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, MethodNames.STARTS_WITH).parameterTypes(CommonClassNames.JAVA_LANG_STRING),
MethodNames.STARTS_WITH, MethodNames.DOES_NOT_START_WITH, expectBoolean = true MethodNames.STARTS_WITH, MethodNames.DOES_NOT_START_WITH, expectBoolean = true
), ),
MoveOutMapping( MoveOutMapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "endsWith").parameterTypes(CommonClassNames.JAVA_LANG_STRING), CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, MethodNames.ENDS_WITH).parameterTypes(CommonClassNames.JAVA_LANG_STRING),
MethodNames.ENDS_WITH, MethodNames.DOES_NOT_END_WITH, expectBoolean = true MethodNames.ENDS_WITH, MethodNames.DOES_NOT_END_WITH, expectBoolean = true
), ),
MoveOutMapping( MoveOutMapping(
@@ -25,16 +25,16 @@ class BogusAssertionInspection : AbstractAssertJInspection() {
).parameterCount(1) ).parameterCount(1)
private val ARRAY_METHODS = arrayOf( private val ARRAY_METHODS = arrayOf(
"hasSameSizeAs", MethodNames.HAS_SAME_SIZE_AS,
MethodNames.CONTAINS, MethodNames.CONTAINS,
"containsAnyOf", "containsAnyOf",
"containsExactly", MethodNames.CONTAINS_EXACTLY,
"containsExactlyInAnyOrder", "containsExactlyInAnyOrder",
"containsOnly", "containsOnly",
"containsSequence", "containsSequence",
"containsSubsequence", "containsSubsequence",
"startsWith", MethodNames.STARTS_WITH,
"endsWith" MethodNames.ENDS_WITH
) )
private val SAME_BOOLEAN_ARRAY_CONTENTS = private val SAME_BOOLEAN_ARRAY_CONTENTS =
@@ -30,13 +30,13 @@ class ImplicitAssertionInspection : AbstractAssertJInspection() {
private val OBJECT_ENUMERABLE_ANY_CONTENT_ASSERTIONS = CallMatcher.instanceCall( private val OBJECT_ENUMERABLE_ANY_CONTENT_ASSERTIONS = CallMatcher.instanceCall(
AssertJClassNames.OBJECT_ENUMERABLE_ASSERT_INTERFACE, AssertJClassNames.OBJECT_ENUMERABLE_ASSERT_INTERFACE,
MethodNames.CONTAINS, "containsOnly", "containsOnlyNulls", MethodNames.CONTAINS_ONLY_ONCE, MethodNames.CONTAINS, "containsOnly", "containsOnlyNulls", MethodNames.CONTAINS_ONLY_ONCE,
"containsExactly", "containsExactlyInAnyOrder", "containsExactlyInAnyOrderElementsOf", MethodNames.CONTAINS_EXACTLY, "containsExactlyInAnyOrder", "containsExactlyInAnyOrderElementsOf",
"containsAll", "containsAnyOf", MethodNames.CONTAINS_ALL, "containsAnyOf",
"containsAnyElementsOf", "containsExactlyElementsOf", "containsOnlyElementsOf", "containsAnyElementsOf", "containsExactlyElementsOf", "containsOnlyElementsOf",
"isSubsetOf", "containsSequence", "containsSubsequence", "isSubsetOf", "containsSequence", "containsSubsequence",
"doesNotContainSequence", "doesNotContainSubsequence", "doesNotContain", "doesNotContainSequence", "doesNotContainSubsequence", MethodNames.DOES_NOT_CONTAIN,
"doesNotContainAnyElementsOf", "doesNotHaveDuplicates", "doesNotContainAnyElementsOf", "doesNotHaveDuplicates",
"startsWith", "endsWith", "containsNull", "doesNotContainNull", MethodNames.STARTS_WITH, MethodNames.ENDS_WITH, "containsNull", "doesNotContainNull",
"are", "areNot", "have", "doNotHave", "areAtLeastOne", "areAtLeast", "areAtMost", "areExactly", "are", "areNot", "have", "doNotHave", "areAtLeastOne", "areAtLeast", "areAtMost", "areExactly",
"haveAtLeastOne", "haveAtLeast", "haveAtMost", "haveExactly", "haveAtLeastOne", "haveAtLeast", "haveAtMost", "haveExactly",
"hasAtLeastOneElementOfType", "hasOnlyElementsOfType", "hasOnlyElementsOfTypes", "hasAtLeastOneElementOfType", "hasOnlyElementsOfType", "hasOnlyElementsOfTypes",
@@ -49,7 +49,7 @@ class ImplicitAssertionInspection : AbstractAssertJInspection() {
private val OBJECT_ENUMERABLE_AT_LEAST_ONE_CONTENT_ASSERTIONS = CallMatcher.instanceCall( private val OBJECT_ENUMERABLE_AT_LEAST_ONE_CONTENT_ASSERTIONS = CallMatcher.instanceCall(
AssertJClassNames.OBJECT_ENUMERABLE_ASSERT_INTERFACE, AssertJClassNames.OBJECT_ENUMERABLE_ASSERT_INTERFACE,
"containsOnlyNulls", "containsOnlyNulls",
"startsWith", "endsWith", "containsNull", MethodNames.STARTS_WITH, MethodNames.ENDS_WITH, "containsNull",
"areAtLeastOne", "areAtLeastOne",
"haveAtLeastOne", "haveAtLeastOne",
"hasAtLeastOneElementOfType", "hasAtLeastOneElementOfType",
@@ -72,10 +72,10 @@ class ImplicitAssertionInspection : AbstractAssertJInspection() {
private val NON_NULL_CORE_ASSERTIONS = CallMatcher.instanceCall( private val NON_NULL_CORE_ASSERTIONS = CallMatcher.instanceCall(
AssertJClassNames.ASSERT_INTERFACE, AssertJClassNames.ASSERT_INTERFACE,
"isInstanceOf", "isInstanceOfSatisfying", "isInstanceOfAny", "isExactlyInstanceOf", "isOfAnyClassIn", MethodNames.IS_INSTANCE_OF, "isInstanceOfSatisfying", "isInstanceOfAny", "isExactlyInstanceOf", "isOfAnyClassIn",
"isNotInstanceOf", "isNotInstanceOfAny", "isNotExactlyInstanceOf", "isNotOfAnyClassIn", MethodNames.IS_NOT_INSTANCE_OF, "isNotInstanceOfAny", "isNotExactlyInstanceOf", "isNotOfAnyClassIn",
"hasSameClassAs", "doesNotHaveSameClassAs", "hasSameClassAs", "doesNotHaveSameClassAs",
"hasToString", "hasSameHashCodeAs" MethodNames.HAS_TO_STRING, "hasSameHashCodeAs"
)!! )!!
private val GUAVA_IS_PRESENT = CallMatcher.instanceCall(AssertJClassNames.GUAVA_OPTIONAL_ASSERTIONS_CLASSNAME, MethodNames.IS_PRESENT) private val GUAVA_IS_PRESENT = CallMatcher.instanceCall(AssertJClassNames.GUAVA_OPTIONAL_ASSERTIONS_CLASSNAME, MethodNames.IS_PRESENT)
@@ -6,5 +6,5 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Inherited @Inherited
public @interface AddLocalJarToModule { public @interface AddLocalJarToModule {
Class[] value(); Class<?>[] value();
} }
@@ -2,6 +2,7 @@ package de.platon42.intellij.jupiter;
import com.intellij.jarRepository.JarRepositoryManager; import com.intellij.jarRepository.JarRepositoryManager;
import com.intellij.jarRepository.RemoteRepositoryDescription; import com.intellij.jarRepository.RemoteRepositoryDescription;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.module.Module; import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
@@ -133,14 +134,19 @@ public class LightCodeInsightExtension implements ParameterResolver, AfterTestEx
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
Store store = getStore(extensionContext);
store.put("disposable", Disposer.newDisposable("LightCodeInsightFixtureTestCaseWrapper"));
} }
@Override @Override
public void tearDown() throws Exception { public void tearDown() throws Exception {
super.tearDown(); super.tearDown();
Store store = getStore(extensionContext);
Disposable disposable = (Disposable) store.get("disposable");
UsefulTestCase.clearFields(this); UsefulTestCase.clearFields(this);
if (myFixture != null && getProject() != null && !getProject().isDisposed()) { if (myFixture != null && disposable != null) {
Disposer.dispose(getProject()); Disposer.dispose(disposable);
store.remove("disposable");
} }
} }
@@ -172,7 +178,7 @@ public class LightCodeInsightExtension implements ParameterResolver, AfterTestEx
}; };
} }
void addJarContaining(ModifiableRootModel model, Class clazz) { void addJarContaining(ModifiableRootModel model, Class<?> clazz) {
try { try {
Path jarPath = Paths.get(clazz.getProtectionDomain().getCodeSource().getLocation().toURI()); Path jarPath = Paths.get(clazz.getProtectionDomain().getCodeSource().getLocation().toURI());
@@ -43,7 +43,7 @@ abstract class AbstractCajonTest {
.asSequence() .asSequence()
.filter { it.description?.contains(snippet) ?: false } .filter { it.description?.contains(snippet) ?: false }
.toList() .toList()
assertThat(highlights).hasSize(count); assertThat(highlights).hasSize(count)
} }
class CutOffFixtureDisplayNameGenerator : DisplayNameGenerator.ReplaceUnderscores() { class CutOffFixtureDisplayNameGenerator : DisplayNameGenerator.ReplaceUnderscores() {
@@ -13,7 +13,7 @@ internal class TwistedAssertionInspectionTest : AbstractCajonTest() {
internal fun hint_twisted_actual_and_expected_and_provide_quickfix_where_possible(@MyFixture myFixture: JavaCodeInsightTestFixture) { internal fun hint_twisted_actual_and_expected_and_provide_quickfix_where_possible(@MyFixture myFixture: JavaCodeInsightTestFixture) {
myFixture.enableInspections(TwistedAssertionInspection::class.java) myFixture.enableInspections(TwistedAssertionInspection::class.java)
myFixture.configureByFile("TwistedAssertionBefore.java") myFixture.configureByFile("TwistedAssertionBefore.java")
assertHighlightings(myFixture, 5, "Actual expression in assertThat() is a constant") assertHighlightings(myFixture, 9, "Actual expression in assertThat() is a constant")
assertHighlightings(myFixture, 10, "Twisted actual and expected expressions") assertHighlightings(myFixture, 10, "Twisted actual and expected expressions")
executeQuickFixes(myFixture, Regex.fromLiteral("Swap actual and expected expressions in assertion"), 6) executeQuickFixes(myFixture, Regex.fromLiteral("Swap actual and expected expressions in assertion"), 6)
@@ -31,7 +31,11 @@ public class TwistedAssertions {
assertThat(bar).isEqualTo(foo); assertThat(bar).isEqualTo(foo);
assertThat(4).isEqualTo(number).isNotEqualTo(number * 2); assertThat(4).isEqualTo(number).isNotEqualTo(number * 2);
assertThat(4).usingDefaultComparator().isGreaterThanOrEqualTo(number);
assertThat(4).usingRecursiveComparison().isGreaterThanOrEqualTo(number);
assertThat(4).usingComparator(Comparator.reverseOrder()).isGreaterThanOrEqualTo(number); assertThat(4).usingComparator(Comparator.reverseOrder()).isGreaterThanOrEqualTo(number);
assertThat(4).usingComparatorForFields().isGreaterThanOrEqualTo(number);
assertThat(4).usingComparatorForType(Integer::compare).isGreaterThanOrEqualTo(number);
assertThat(String.class).isEqualTo(Class.forName("java.lang.String")); assertThat(String.class).isEqualTo(Class.forName("java.lang.String"));
assertThat("XX").matches(Pattern.compile("..")); assertThat("XX").matches(Pattern.compile(".."));
@@ -31,7 +31,11 @@ public class TwistedAssertions {
assertThat(bar).isEqualTo(foo); assertThat(bar).isEqualTo(foo);
assertThat(4).isEqualTo(number).isNotEqualTo(number * 2); assertThat(4).isEqualTo(number).isNotEqualTo(number * 2);
assertThat(4).usingDefaultComparator().isGreaterThanOrEqualTo(number);
assertThat(4).usingRecursiveComparison().isGreaterThanOrEqualTo(number);
assertThat(4).usingComparator(Comparator.reverseOrder()).isGreaterThanOrEqualTo(number); assertThat(4).usingComparator(Comparator.reverseOrder()).isGreaterThanOrEqualTo(number);
assertThat(4).usingComparatorForFields().isGreaterThanOrEqualTo(number);
assertThat(4).usingComparatorForType(Integer::compare).isGreaterThanOrEqualTo(number);
assertThat(String.class).isEqualTo(Class.forName("java.lang.String")); assertThat(String.class).isEqualTo(Class.forName("java.lang.String"));
assertThat("XX").matches(Pattern.compile("..")); assertThat("XX").matches(Pattern.compile(".."));