Compare commits

...
Author SHA1 Message Date
Niels Ulrik Andersen 49a3b1aada Add support for converting JUnit 5 tests to AssertJ 2022-02-23 18:05:32 +01:00
Niels Ulrik Andersen f8b86ac78f Refactor 2022-02-23 18:03:46 +01:00
chrisly42 2d92d71af0 Travis-CI.com now? Really? 2021-07-16 21:44:04 +02:00
chrisly42 01c6b141ee Updated various dependencies (Kotlin 1.5.21) and AssertJ 3.20.2. Latest Gradle. Migrated to latest intellij-gradle-plugin. Slightly fixed a situation in LightCodeInsightExtension, where the fields were cleared in super-Method before they had been evaluated. 2021-07-16 19:59:38 +02:00
chrisly42 32eb8be1e3 Typofix. 2021-06-14 13:56:27 +02:00
chrisly42 6692ded98a 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. 2021-05-06 12:42:23 +02:00
chrisly42 146465328c Cajon is written in Kotlin 1.4. 2020-10-02 23:14:23 +02:00
chrisly42 47dcc7ec5e Disable TSL 1.3 due to JDK11 bug for sending data to coveralls. 2020-10-02 23:06:38 +02:00
chrisly42 ce0b5ce872 Added inversion of boolean conditions inside isEqualTo() and isNotEqualTo() for InvertedBooleanCondition inspection. 2020-10-02 22:44:08 +02:00
chrisly42 d48c71d4ea Added several cases for hasSizeGreaterThan/LessThan/OrEqualTo() for EnumerablesEmpty inspection. 2020-10-02 19:24:22 +02:00
chrisly42 1340a34782 Fixed ImplicitAssertion crashing the plugin with IntelliJ 2020.3 EAP, added support for singleElement(). Unrelated: Documentation grammar fixes. 2020-10-02 18:54:23 +02:00
chrisly42 fbde6b3387 Upgraded gradle to 6.6.1.
Upgraded kotlin to 1.4.10.
Upgraded assertj to 3.17.2.
Upgraded junit-jupiter to 5.7.0.
Other minor upgrades.
2020-10-02 18:52:50 +02:00
chrisly42 b9110d226e Added a note about the plugin being for Java language projects only. 2020-10-02 16:21:29 +02:00
46 changed files with 701 additions and 204 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>
+1 -1
View File
@@ -1,6 +1,6 @@
language: java language: java
jdk: jdk:
- openjdk8 - openjdk11
before_script: before_script:
- chmod +x gradlew - chmod +x gradlew
+64 -20
View File
@@ -1,4 +1,4 @@
# Cajon - Concise AssertJ Optimizing Nitpicker [![Build Status](https://travis-ci.org/chrisly42/cajon-plugin.svg?branch=master)](https://travis-ci.org/chrisly42/cajon-plugin) [![Coverage Status](https://coveralls.io/repos/github/chrisly42/cajon-plugin/badge.svg?branch=master)](https://coveralls.io/github/chrisly42/cajon-plugin?branch=master) # Cajon - Concise AssertJ Optimizing Nitpicker [![Build Status](https://travis-ci.com/chrisly42/cajon-plugin.svg?branch=master)](https://travis-ci.com/chrisly42/cajon-plugin) [![Coverage Status](https://coveralls.io/repos/github/chrisly42/cajon-plugin/badge.svg?branch=master)](https://coveralls.io/github/chrisly42/cajon-plugin?branch=master)
Cajon is an IntelliJ IDEA Plugin for shortening and optimizing [AssertJ](https://assertj.github.io/doc/) assertions. Cajon is an IntelliJ IDEA Plugin for shortening and optimizing [AssertJ](https://assertj.github.io/doc/) assertions.
@@ -32,7 +32,7 @@ Then AssertJ would tell you the _actual contents_ of the collection on failure.
## Conversion of JUnit assertions to AssertJ ## Conversion of JUnit assertions to AssertJ
The plugin also supports the conversion of the most common JUnit 4 assertions to AssertJ. The plugin also supports the conversion of the most common JUnit 4 and JUnit 5 assertions to AssertJ.
## Wrong use of AssertJ ## Wrong use of AssertJ
@@ -46,12 +46,18 @@ Using strings is not safe for refactoring (and before Java 8 Lambdas were availa
creating extractor functions just for testing purpose was a bit too tedious). creating extractor functions just for testing purpose was a bit too tedious).
This plugin adds support for referencing these fields (so you can ctrl(/cmd)-click on the This plugin adds support for referencing these fields (so you can ctrl(/cmd)-click on the
string to go to the definition) and also allows safe refactoring on the string to go to the definition) and allows safe refactoring on the
fields (refactoring a getter method without a corresponding field will not work fields (refactoring a getter method without a corresponding field will not work
correctly right now). correctly right now) too.
## Usage ## Usage
Cajon (though written in Kotlin) *only works with Java projects*.
There does not seem too much demand for AssertJ within Kotlin projects
and although possible, it would require a complete rewrite as the PSI
stuff in IntelliJ is very Java focused. Almost zero feedback is also not helping.
Enough bickering.
The plugin will report inspections in your opened editor file as warnings. The plugin will report inspections in your opened editor file as warnings.
You can then quick-fix these with your quick-fix hotkey (usually Alt-Return or Opt-Return). You can then quick-fix these with your quick-fix hotkey (usually Alt-Return or Opt-Return).
@@ -87,7 +93,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
.anotherCondition(); .anotherCondition();
``` ```
Joining will work on actual expressions inside ```assertThat()``` that are equivalent expressions, Joining will work on actual expressions inside ```assertThat()``` that are equivalent expressions,
except for method calls with known side-effect methods such as ```Iterator.next()``` and except for method calls with known side effect methods such as ```Iterator.next()``` and
pre/post-increment/decrement operations -- please notify me about others. pre/post-increment/decrement operations -- please notify me about others.
The comments of the statements will be preserved. When using ```extracting()``` or similar, The comments of the statements will be preserved. When using ```extracting()``` or similar,
@@ -136,12 +142,19 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
- AssertThatInvertedBooleanCondition - AssertThatInvertedBooleanCondition
Inverts the boolean condition to make it more readable. Inverts the boolean condition in either ```assertThat()``` or ```isEqualTo()```/```isNotEqualTo()```
to make it more readable.
``` ```
from: assertThat(!booleanValue).isEqualTo(true/false/Boolean.TRUE/Boolean.FALSE); from: assertThat(!booleanValue).isEqualTo(true/false/Boolean.TRUE/Boolean.FALSE);
from: assertThat(!booleanValue).isTrue()/isFalse(); from: assertThat(!booleanValue).isTrue()/isFalse();
to: assertThat(booleanValue).isFalse()/isTrue(); to: assertThat(booleanValue).isFalse()/isTrue();
from: assertThat(booleanValue).isEqualTo(!primitiveBooleanExpression);
to: assertThat(booleanValue).isNotEqualTo(primitiveBooleanExpression);
from: assertThat(booleanValue).isNotEqualTo(!primitiveBooleanExpression);
to: assertThat(booleanValue).isEqualTo(primitiveBooleanExpression);
``` ```
- AssertThatInstanceOf - AssertThatInstanceOf
@@ -308,10 +321,10 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
to: assertThat(map).doesNotContainKey(key); to: assertThat(map).doesNotContainKey(key);
``` ```
The last transformation is the default, but may not be 100% equivalent depending whether the map The last transformation is the default, but may not be 100% equivalent depending upon the map
is a degenerated case with ```null``` values, where ```map.get(key)``` returns ```null```, being a degenerated case with ```null``` values, where ```map.get(key)``` returns ```null```,
but ```containsKey(key)``` is ```true```. but ```containsKey(key)``` is ```true```.
For that special case (which usually is the result of a bad design decision!) For that special case (which is usually the result of a bad design decision!)
the quickfix should rather generate ```assertThat(map).containsEntry(key, null)```. the quickfix should rather generate ```assertThat(map).containsEntry(key, null)```.
Therefore, the behavior can be configured in the settings for this inspection to either Therefore, the behavior can be configured in the settings for this inspection to either
create the default case (```doesNotContainKey```), the degenerated case (```containsEntry```), create the default case (```doesNotContainKey```), the degenerated case (```containsEntry```),
@@ -409,11 +422,21 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
- AssertThatEnumerableIsEmpty - AssertThatEnumerableIsEmpty
Uses ```isEmpty()``` for ```hasSize(0)``` iterable assertions instead. Uses ```isEmpty()``` for ```hasSize(0)```, ```hasSizeLessThanOrEqualTo(0)```, and
```hasSizeLessThan(1)``` iterable (enumerable) assertions instead.
Also suggests ```isNotEmpty()``` for ```hasSizeGreaterThan(0)``` and
```hasSizeGreaterThanOrEqualTo(1)```.
``` ```
from: assertThat(enumerable).hasSize(0); from: assertThat(enumerable).hasSize(0);
from: assertThat(enumerable).hasSizeLessThanOrEqualTo(0);
from: assertThat(enumerable).hasSizeLessThan(1);
to: assertThat(enumerable).isEmpty(); to: assertThat(enumerable).isEmpty();
from: assertThat(enumerable).hasSizeGreaterThan(0);
from: assertThat(enumerable).hasSizeGreaterThanOrEqualTo(1);
to: assertThat(enumerable).isNotEmpty();
``` ```
- AssertThatSize - AssertThatSize
@@ -563,7 +586,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
If the assertions is either ```isEqualTo()``` or ```hasSameHashCodeAs()``` it may be checking custom If the assertions is either ```isEqualTo()``` or ```hasSameHashCodeAs()``` it may be checking custom
```equals()``` or ```hashCode()``` behavior. If the test method name containing the statement has a ```equals()``` or ```hashCode()``` behavior. If the test method name containing the statement has a
name that contains 'equal' or 'hashcode' (case insensitive), the warning will be weakened to information name that contains 'equal' or 'hashcode' (case-insensitive), the warning will be weakened to information
level. level.
- ImplicitAssertion - ImplicitAssertion
@@ -671,7 +694,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
However, this suggests that the test has actually been run and passed instead of showing the test However, this suggests that the test has actually been run and passed instead of showing the test
as being skipped. as being skipped.
Return statements in ```if``` statements in main test methods (must be annotated with JUnit 4 or Return statements in ```if``` statements in main test methods (must be annotated with JUnit 4 or JUnit 5 or
Jupiter ```@Test``` annotations) will be verified to have at least one ```assertThat()``` statement in the code flow. 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. 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. However, at most 50 statements and down to five recursions will be tolerated before giving up.
@@ -708,7 +731,7 @@ You can toggle the various inspections in the Settings/Editor/Inspections in the
- JUnitAssertToAssertJ - JUnitAssertToAssertJ
Tries to convert most of the JUnit 4 assertions and assumptions to AssertJ format. Tries to convert most of the JUnit 4 and JUnit 5 assertions and assumptions to AssertJ format.
Sometimes the expected and actual expressions are specified in wrong order -- Sometimes the expected and actual expressions are specified in wrong order --
Cajon tries to swap these when it detects the supposed actual expression to be a Cajon tries to swap these when it detects the supposed actual expression to be a
constant while the expected one is not. constant while the expected one is not.
@@ -775,15 +798,16 @@ 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 that 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.
Feel free to use the code (in package ```de.platon42.intellij.jupiter```) for your projects (with attribution). Feel free to use the code (in package ```de.platon42.intellij.jupiter```) for your projects (with attribution).
## Planned features ## Planned features
- More Optional fixes such as ```opt1.get() == opt2.get()``` etc. - More Optional fixes such as ```opt1.get() == opt2.get()``` etc.
- More moving out of methods for LocalDate/Time etc. - More moving out of methods for LocalDate/Time etc.
- assertThat(foo.toLowerCase()/toUpperCase()).isEqualTo("foo") -> assertThat(foo).isEqualToIgnoringCase()
- Extraction with property names to lambda/method reference with Java 8 - Extraction with property names to lambda/method reference with Java 8
``` ```
@@ -793,9 +817,29 @@ Feel free to use the code (in package ```de.platon42.intellij.jupiter```) for yo
## Changelog ## Changelog
#### V1.13 (unreleased)
- Added support for converting JUnit 5 tests to AssertJ
### 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
- Now is being built with JDK 11 (with Java 8 target).
- 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!
- Added new singleElement() from AssertJ >= 3.17.0 to ImplicitAssertionInspection.
- Added several cases for ```hasSizeGreaterThan/LessThan/OrEqualTo()``` for EnumerablesEmpty 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).
- Fixed two possible index out of bounds exceptions in ExtractorReferenceContributor and BogusAssertionInspection. - Fixed two possible index out-of-bounds exceptions in ExtractorReferenceContributor and BogusAssertionInspection.
#### V1.9 (25-Feb-20) Mardi Gras Edition #### V1.9 (25-Feb-20) Mardi Gras Edition
- TwistedAssertion inspection will no longer warn for ```.matches()``` and ```doesNotMatch()``` for regular expressions. - TwistedAssertion inspection will no longer warn for ```.matches()``` and ```doesNotMatch()``` for regular expressions.
@@ -831,10 +875,10 @@ Feel free to use the code (in package ```de.platon42.intellij.jupiter```) for yo
Specifically, uses of ```matches()```, ```compareToIgnoreCase()```, ```indexOf()```, and ```trim()```. Specifically, uses of ```matches()```, ```compareToIgnoreCase()```, ```indexOf()```, and ```trim()```.
#### V1.5 (24-Sep-19) #### V1.5 (24-Sep-19)
- Fix for AssertThatCollectionOrMap inspection sometimes causing an index out of bounds exception. - Fix for AssertThatCollectionOrMap inspection sometimes causing an index out-of-bounds exception.
- AssertThatGuavaOptional inspections will now avoid conversions from ```.get()``` to ```.contains()``` - AssertThatGuavaOptional inspections will now avoid conversions from ```.get()``` to ```.contains()```
for array types (currently not correctly supported by ```contains()``` in AssertJ-Guava). for array types (currently not correctly supported by ```contains()``` in AssertJ-Guava).
- Added an settings option for AssertThatCollectionOrMap inspection respecting the degenerated case of maps with ```null``` values. - Added a settings option for AssertThatCollectionOrMap inspection respecting the degenerated case of maps with ```null``` values.
It is now possible to change the behavior for ```map.get(key) == null```, so it can offer either ```.doesNotContainKey()``` (default) It is now possible to change the behavior for ```map.get(key) == null```, so it can offer either ```.doesNotContainKey()``` (default)
or ```.containsEntry(key, null)```, or even both. or ```.containsEntry(key, null)```, or even both.
- Fixes to AssertThatSize inspection after extending it for Maps in previous release as not all - Fixes to AssertThatSize inspection after extending it for Maps in previous release as not all
@@ -920,7 +964,7 @@ Feel free to use the code (in package ```de.platon42.intellij.jupiter```) for yo
#### V0.2 (01-Apr-19) #### V0.2 (01-Apr-19)
- Fixed descriptions and quick fix texts. - Fixed descriptions and quick fix texts.
- Fixed highlighting of found problems and also 'Run inspection by Name' returning nothing. - Fixed highlighting of found problems and 'Run inspection by Name' returning nothing, too.
#### V0.1 (31-Mar-19) #### V0.1 (31-Mar-19)
- Initial release. - Initial release.
+24 -20
View File
@@ -1,13 +1,15 @@
plugins { plugins {
id 'java' id 'java'
id 'org.jetbrains.intellij' version '0.4.21' id 'org.jetbrains.intellij' version '1.1.3'
id 'org.jetbrains.kotlin.jvm' version '1.4.0-rc' id 'org.jetbrains.kotlin.jvm' version '1.5.21'
id 'jacoco' id 'jacoco'
id 'com.github.kt3k.coveralls' version '2.10.1' id 'com.github.kt3k.coveralls' version '2.11.0'
} }
group 'de.platon42' group 'de.platon42'
version '1.10' version '1.12.1'
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
repositories { repositories {
mavenCentral() mavenCentral()
@@ -20,36 +22,38 @@ repositories {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testImplementation "org.assertj:assertj-core:3.16.1" testImplementation "org.assertj:assertj-core:3.20.2"
testImplementation "org.assertj:assertj-guava:3.4.0" testImplementation "org.assertj:assertj-guava:3.4.0"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.0-M1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2' 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-reflect"
// testImplementation "org.jetbrains.kotlin:kotlin-test-junit" // testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
} }
compileKotlin { compileKotlin {
kotlinOptions.jvmTarget = "1.8" kotlinOptions.jvmTarget = "1.8"
} }
compileTestKotlin { compileTestKotlin {
kotlinOptions.jvmTarget = "1.8" kotlinOptions.jvmTarget = "1.8"
} }
intellij { intellij {
version '2020.2' setVersion("2021.1.3") // LATEST-EAP-SNAPSHOT
// pluginName 'Concise AssertJ Optimizing Nitpicker (Cajon)' //pluginName.set(provider { 'Concise AssertJ Optimizing Nitpicker (Cajon)' })
updateSinceUntilBuild false setUpdateSinceUntilBuild(false)
plugins = ['java'] setPlugins(["com.intellij.java"])
} }
patchPluginXml { patchPluginXml {
changeNotes """ setChangeNotes("""
<h4>V1.10 (31-Jul-20) Friday the 31st Edition</h4> <h4>V1.13 (unreleased)</h4>
<ul> <ul>
<li>Updated libraries to the latest versions (including AssertJ 3.16.1 and Kotlin 1.40-rc). <li>Added support for converting JUnit 5 tests to AssertJ
<li>Fixed two possible index out of bounds exceptions in ExtractorReferenceContributor and BogusAssertionInspection.
</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>
""" """)
} }
test { test {
@@ -60,16 +64,16 @@ test {
} }
jacoco { jacoco {
toolVersion = '0.8.5' toolVersion = '0.8.7'
} }
jacocoTestReport { jacocoTestReport {
reports { reports {
xml.enabled true xml.required.set(true)
csv.enabled false csv.required.set(false)
} }
} }
publishPlugin { publishPlugin {
token intellijPublishToken setToken(intellijPublishToken)
} }
+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"
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
Vendored
+1 -1
View File
@@ -72,7 +72,7 @@ case "`uname`" in
Darwin* ) Darwin* )
darwin=true darwin=true
;; ;;
MINGW* ) MSYS* | MINGW* )
msys=true msys=true
;; ;;
NONSTOP* ) NONSTOP* )
Vendored
+3 -18
View File
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,21 +64,6 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
@@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
@@ -21,19 +21,33 @@ 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",
"areAtLeast", "areAtLeastOne", "areAtMost", "areExactly", "areAtLeast", "areAtLeastOne", "areAtMost", "areExactly",
"haveAtLeastOne", "haveAtLeast", "haveAtMost", "haveExactly", "haveAtLeastOne", "haveAtLeast", "haveAtMost", "haveExactly",
"hasOnlyOneElementSatisfying", "anyMatch", "noneMatch", "anySatisfy", "noneSatisfy" "singleElement", "hasOnlyOneElementSatisfying", "anyMatch", "noneMatch", "anySatisfy", "noneSatisfy"
)!! )!!
val COMPLEX_CALLS_THAT_MAKES_STUFF_TRICKY = CallMatcher.anyOf( val COMPLEX_CALLS_THAT_MAKES_STUFF_TRICKY = CallMatcher.anyOf(
@@ -72,6 +72,8 @@ abstract class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool()
val ASSERT_THAT_BOOLEAN = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT) val ASSERT_THAT_BOOLEAN = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
.parameterTypes("boolean")!! .parameterTypes("boolean")!!
val ASSERT_THAT_BOOLEAN_OBJ = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
.parameterTypes(CommonClassNames.JAVA_LANG_BOOLEAN)!!
val ASSERT_THAT_ANY = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT) val ASSERT_THAT_ANY = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
.parameterCount(1)!! .parameterCount(1)!!
@@ -126,6 +128,14 @@ abstract class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool()
.parameterCount(0)!! .parameterCount(0)!!
val HAS_SIZE = CallMatcher.instanceCall(ENUMERABLE_ASSERT_INTERFACE, MethodNames.HAS_SIZE) val HAS_SIZE = CallMatcher.instanceCall(ENUMERABLE_ASSERT_INTERFACE, MethodNames.HAS_SIZE)
.parameterTypes("int")!! .parameterTypes("int")!!
val HAS_SIZE_GREATER_THAN_INT = CallMatcher.instanceCall(ENUMERABLE_ASSERT_INTERFACE, MethodNames.HAS_SIZE_GREATER_THAN)
.parameterTypes("int")!!
val HAS_SIZE_GREATER_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ENUMERABLE_ASSERT_INTERFACE, MethodNames.HAS_SIZE_GREATER_THAN_OR_EQUAL_TO)
.parameterTypes("int")!!
val HAS_SIZE_LESS_THAN_INT = CallMatcher.instanceCall(ENUMERABLE_ASSERT_INTERFACE, MethodNames.HAS_SIZE_LESS_THAN)
.parameterTypes("int")!!
val HAS_SIZE_LESS_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ENUMERABLE_ASSERT_INTERFACE, MethodNames.HAS_SIZE_LESS_THAN_OR_EQUAL_TO)
.parameterTypes("int")!!
val IS_GREATER_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_GREATER_THAN) val IS_GREATER_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_GREATER_THAN)
.parameterTypes("int")!! .parameterTypes("int")!!
@@ -167,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)!!
@@ -186,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,57 @@ 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 JUNIT4_ASSERT_CLASSNAME = "org.junit.Assert"
@NonNls @NonNls
const val JUNIT_ASSUME_CLASSNAME = "org.junit.Assume" const val JUNIT5_ASSERT_CLASSNAME = "org.junit.jupiter.api.Assertions"
@NonNls
const val JUNIT4_ASSUME_CLASSNAME = "org.junit.Assume"
@NonNls
const val JUNIT5_ASSUME_CLASSNAME = "org.junit.jupiter.api.Assumptions"
@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"
@@ -21,18 +21,19 @@ class AssertThatBooleanConditionInspection : AbstractAssertJInspection() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
if (!expression.hasAssertThat()) return if (!expression.hasAssertThat()) return
val matchingCalls = listOf( val isEqualToObject = IS_EQUAL_TO_OBJECT.test(expression)
IS_EQUAL_TO_OBJECT, IS_EQUAL_TO_BOOLEAN, val isEqualToPrimitive = IS_EQUAL_TO_BOOLEAN.test(expression)
IS_NOT_EQUAL_TO_OBJECT, IS_NOT_EQUAL_TO_BOOLEAN val isNotEqualToObject = IS_NOT_EQUAL_TO_OBJECT.test(expression)
).map { it.test(expression) } val isNotEqualToPrimitive = IS_NOT_EQUAL_TO_BOOLEAN.test(expression)
if (matchingCalls.none { it }) return
if (!(isEqualToObject || isEqualToPrimitive || isNotEqualToObject || isNotEqualToPrimitive)) return
if (!checkAssertedType(expression, ABSTRACT_BOOLEAN_ASSERT_CLASSNAME)) return if (!checkAssertedType(expression, ABSTRACT_BOOLEAN_ASSERT_CLASSNAME)) return
val expectedExpression = expression.firstArg val expectedExpression = expression.firstArg
if (!TypeConversionUtil.isBooleanType(expectedExpression.type)) return if (!TypeConversionUtil.isBooleanType(expectedExpression.type)) return
val expectedResult = expression.calculateConstantParameterValue(0) as? Boolean ?: return val expectedResult = expression.calculateConstantParameterValue(0) as? Boolean ?: return
val flippedBooleanTest = matchingCalls.drop(2).any { it } val flippedBooleanTest = isNotEqualToObject || isNotEqualToPrimitive
val replacementMethod = (expectedResult xor flippedBooleanTest).map(MethodNames.IS_TRUE, MethodNames.IS_FALSE) val replacementMethod = (expectedResult xor flippedBooleanTest).map(MethodNames.IS_TRUE, MethodNames.IS_FALSE)
registerSimplifyMethod(holder, expression, replacementMethod) registerSimplifyMethod(holder, expression, replacementMethod)
@@ -5,6 +5,7 @@ import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement import com.intellij.psi.PsiStatement
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.MethodNames import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.calculateConstantParameterValue import de.platon42.intellij.plugins.cajon.calculateConstantParameterValue
import de.platon42.intellij.plugins.cajon.hasAssertThat import de.platon42.intellij.plugins.cajon.hasAssertThat
@@ -12,7 +13,7 @@ import de.platon42.intellij.plugins.cajon.hasAssertThat
class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() { class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() {
companion object { companion object {
private const val DISPLAY_NAME = "Asserting an empty enumerable" private const val DISPLAY_NAME = "Asserting an empty or not empty enumerable"
} }
override fun getDisplayName() = DISPLAY_NAME override fun getDisplayName() = DISPLAY_NAME
@@ -23,11 +24,17 @@ class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() {
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
if (!expression.hasAssertThat()) return if (!expression.hasAssertThat()) return
val isLastExpression = expression.parent is PsiStatement val isLastExpression = expression.parent is PsiStatement
if (!(HAS_SIZE.test(expression) && isLastExpression)) return
val value = expression.calculateConstantParameterValue(0) ?: return val value = expression.calculateConstantParameterValue(0) ?: return
if (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))
val isNotEmpty = (HAS_SIZE_GREATER_THAN_INT.test(expression) && (value == 0)) ||
(HAS_SIZE_GREATER_THAN_OR_EQUAL_TO_INT.test(expression) && (value == 1))
if (isEmpty && isLastExpression) {
registerSimplifyMethod(holder, expression, MethodNames.IS_EMPTY) registerSimplifyMethod(holder, expression, MethodNames.IS_EMPTY)
} else if (isNotEmpty) {
registerSimplifyMethod(holder, expression, MethodNames.IS_NOT_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
) )
) )
@@ -1,8 +1,13 @@
package de.platon42.intellij.plugins.cajon.inspections package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.util.TextRange
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.util.PsiUtil
import com.intellij.psi.util.TypeConversionUtil
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.quickfixes.InvertUnaryExpressionQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.InvertUnaryStatementQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.InvertUnaryStatementQuickFix
class AssertThatInvertedBooleanConditionInspection : AbstractAssertJInspection() { class AssertThatInvertedBooleanConditionInspection : AbstractAssertJInspection() {
@@ -10,6 +15,8 @@ class AssertThatInvertedBooleanConditionInspection : AbstractAssertJInspection()
companion object { companion object {
private const val DISPLAY_NAME = "Asserting an inverted boolean condition" private const val DISPLAY_NAME = "Asserting an inverted boolean condition"
private const val INVERT_CONDITION_MESSAGE = "Condition inside assertThat() could be inverted" private const val INVERT_CONDITION_MESSAGE = "Condition inside assertThat() could be inverted"
private const val REMOVE_INSTANCEOF_DESCRIPTION_TEMPLATE = "Invert condition in %s() and use %s() instead"
private const val INVERT_OUTSIDE_CONDITION_MESSAGE = "Condition outside assertThat() could be inverted"
} }
override fun getDisplayName() = DISPLAY_NAME override fun getDisplayName() = DISPLAY_NAME
@@ -20,13 +27,27 @@ class AssertThatInvertedBooleanConditionInspection : AbstractAssertJInspection()
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
if (!expression.hasAssertThat()) return if (!expression.hasAssertThat()) return
val staticMethodCall = expression.findStaticMethodCall() ?: return val staticMethodCall = expression.findStaticMethodCall() ?: return
if (!ASSERT_THAT_BOOLEAN.test(staticMethodCall)) return if (expression.getExpectedBooleanResult() != null) {
expression.getExpectedBooleanResult() ?: return if (!ASSERT_THAT_BOOLEAN.test(staticMethodCall)) return
val prefixExpression = staticMethodCall.firstArg as? PsiPrefixExpression ?: return
if (prefixExpression.operationTokenType == JavaTokenType.EXCL) {
val outmostMethodCall = expression.findOutmostMethodCall() ?: return
holder.registerProblem(outmostMethodCall, INVERT_CONDITION_MESSAGE, InvertUnaryStatementQuickFix())
}
} else {
if (!CallMatcher.anyOf(ASSERT_THAT_BOOLEAN, ASSERT_THAT_BOOLEAN_OBJ).test(staticMethodCall)) return
val isEqualTo = CallMatcher.anyOf(IS_EQUAL_TO_BOOLEAN, IS_EQUAL_TO_OBJECT).test(expression)
val isNotEqualTo = CallMatcher.anyOf(IS_NOT_EQUAL_TO_BOOLEAN, IS_NOT_EQUAL_TO_OBJECT).test(expression)
if (!(isEqualTo || isNotEqualTo)) return
val prefixExpression = expression.firstArg as? PsiPrefixExpression ?: return
val operand = PsiUtil.skipParenthesizedExprDown(prefixExpression.operand) ?: return
if (!TypeConversionUtil.isPrimitiveAndNotNull(operand.type)) return
val originalMethod = getOriginalMethodName(expression) ?: return
val prefixExpression = staticMethodCall.firstArg as? PsiPrefixExpression ?: return val replacementMethod = isEqualTo.map(MethodNames.IS_NOT_EQUAL_TO, MethodNames.IS_EQUAL_TO)
if (prefixExpression.operationTokenType == JavaTokenType.EXCL) { val description = REMOVE_INSTANCEOF_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val outmostMethodCall = expression.findOutmostMethodCall() ?: return val textRange = TextRange(staticMethodCall.textLength, expression.textLength)
holder.registerProblem(outmostMethodCall, INVERT_CONDITION_MESSAGE, InvertUnaryStatementQuickFix()) holder.registerProblem(expression, textRange, INVERT_OUTSIDE_CONDITION_MESSAGE, InvertUnaryExpressionQuickFix(description, replacementMethod))
} }
} }
} }
@@ -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,27 +30,26 @@ 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",
"doesNotHave", "doesNotHaveSameClassAs",
"hasAtLeastOneElementOfType", "hasOnlyElementsOfType", "hasOnlyElementsOfTypes", "hasAtLeastOneElementOfType", "hasOnlyElementsOfType", "hasOnlyElementsOfTypes",
"doesNotHaveAnyElementsOfTypes", "doesNotHaveAnyElementsOfTypes",
"has", "doesNotHave", "has", "doesNotHave",
"hasOnlyOneElementSatisfying", "hasSameElementsAs", "singleElement", "hasOnlyOneElementSatisfying", "hasSameElementsAs",
"allMatch", "allSatisfy", "anyMatch", "anySatisfy", "noneMatch", "noneSatisfy" "allMatch", "allSatisfy", "anyMatch", "anySatisfy", "noneMatch", "noneSatisfy"
)!! )!!
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",
@@ -73,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)
@@ -3,6 +3,8 @@ package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.CommonClassNames.*
import com.intellij.psi.PsiKeyword.*
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.siyeh.ig.callMatcher.CallMatcher import com.siyeh.ig.callMatcher.CallMatcher
import com.siyeh.ig.callMatcher.CallMatcher.anyOf import com.siyeh.ig.callMatcher.CallMatcher.anyOf
@@ -20,94 +22,127 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
private const val CONVERT_MESSAGE_TEMPLATE = "%s can be converted to AssertJ style" private const val CONVERT_MESSAGE_TEMPLATE = "%s can be converted to AssertJ style"
private const val CONVERT_DESCRIPTION_TEMPLATE = "Convert %s() to %s().%s()" private const val CONVERT_DESCRIPTION_TEMPLATE = "Convert %s() to %s().%s()"
private const val DOUBLE_ARR = "$DOUBLE[]"
private const val FLOAT_ARR = "$FLOAT[]"
private val ASSERT_MAPPINGS = listOf( private val ASSERT_MAPPINGS = listOf(
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes("boolean") staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(BOOLEAN),
), ),
MethodNames.IS_TRUE, hasExpected = false MethodNames.IS_TRUE, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes("boolean") staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(BOOLEAN),
), ),
MethodNames.IS_FALSE, hasExpected = false MethodNames.IS_FALSE, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_OBJECT),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT) staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT),
), ),
MethodNames.IS_NULL, hasExpected = false MethodNames.IS_NULL, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_OBJECT),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT) staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(JAVA_LANG_OBJECT),
), ),
MethodNames.IS_NOT_NULL, hasExpected = false MethodNames.IS_NOT_NULL, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE, DOUBLE, DOUBLE),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("double", "double", "double"), staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE, JAVA_LANG_STRING),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("float", "float", "float") staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, FLOAT, FLOAT, FLOAT),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT),
), ),
MethodNames.IS_CLOSE_TO, hasDelta = true MethodNames.IS_CLOSE_TO, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2) staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2),
), ),
MethodNames.IS_EQUAL_TO MethodNames.IS_EQUAL_TO
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE, DOUBLE, DOUBLE),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("double", "double", "double"), staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE, JAVA_LANG_STRING),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("float", "float", "float") staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(DOUBLE, DOUBLE, DOUBLE),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, FLOAT, FLOAT, FLOAT),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(FLOAT, FLOAT, FLOAT),
), ),
MethodNames.IS_NOT_CLOSE_TO, hasDelta = true MethodNames.IS_NOT_CLOSE_TO, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2) staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2),
), ),
MethodNames.IS_NOT_EQUAL_TO MethodNames.IS_NOT_EQUAL_TO
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2) staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2),
), ),
MethodNames.IS_SAME_AS MethodNames.IS_SAME_AS
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2) staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2),
), ),
MethodNames.IS_NOT_SAME_AS MethodNames.IS_NOT_SAME_AS
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double[]", "double[]", "double"), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, DOUBLE_ARR, DOUBLE_ARR, DOUBLE),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("double[]", "double[]", "double"), staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(DOUBLE_ARR, DOUBLE_ARR, DOUBLE, JAVA_LANG_STRING),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float[]", "float[]", "float"), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(DOUBLE_ARR, DOUBLE_ARR, DOUBLE),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("float[]", "float[]", "float") staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(DOUBLE_ARR, DOUBLE_ARR, DOUBLE),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(JAVA_LANG_STRING, FLOAT_ARR, FLOAT_ARR, FLOAT),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(FLOAT_ARR, FLOAT_ARR, FLOAT, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(FLOAT_ARR, FLOAT_ARR, FLOAT),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(FLOAT_ARR, FLOAT_ARR, FLOAT),
), ),
MethodNames.CONTAINS_EXACTLY, hasDelta = true MethodNames.CONTAINS_EXACTLY, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2), staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2),
staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3) staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2),
staticCall(JUNIT4_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3),
staticCall(JUNIT5_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3),
), ),
MethodNames.CONTAINS_EXACTLY MethodNames.CONTAINS_EXACTLY
) )
@@ -116,26 +151,35 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
private val ASSUME_MAPPINGS = listOf( private val ASSUME_MAPPINGS = listOf(
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"), staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN),
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes("boolean") staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN),
staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_TRUE_METHOD).parameterTypes(BOOLEAN),
), ),
MethodNames.IS_TRUE, hasExpected = false MethodNames.IS_TRUE, hasExpected = false
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"), staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(JAVA_LANG_STRING, BOOLEAN),
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes("boolean") staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN),
staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_FALSE_METHOD).parameterTypes(BOOLEAN),
), ),
MethodNames.IS_FALSE, hasExpected = false MethodNames.IS_FALSE, hasExpected = false
), ),
Mapping( Mapping(
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_NOT_NULL_METHOD).parameterCount(1), anyOf(
staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_NOT_NULL_METHOD).parameterCount(1),
staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_NOT_NULL_METHOD).parameterCount(1),
),
MethodNames.IS_NOT_NULL, hasExpected = false, singleArgument = true MethodNames.IS_NOT_NULL, hasExpected = false, singleArgument = true
), ),
Mapping( Mapping(
anyOf( anyOf(
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_THROWABLE), staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_STRING, JAVA_LANG_THROWABLE),
staticCall(JUNIT_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(CommonClassNames.JAVA_LANG_THROWABLE) staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE, JAVA_LANG_STRING),
staticCall(JUNIT4_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE),
staticCall(JUNIT5_ASSUME_CLASSNAME, ASSUME_NO_EXCEPTION).parameterTypes(JAVA_LANG_THROWABLE),
), ),
"doesNotThrowAnyException", hasExpected = false "doesNotThrowAnyException", hasExpected = false
) )
@@ -149,33 +193,41 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
when (expression.resolveMethod()?.containingClass?.qualifiedName) { when (expression.resolveMethod()?.containingClass?.qualifiedName) {
JUNIT_ASSERT_CLASSNAME -> { JUNIT4_ASSERT_CLASSNAME -> visitMethodCallExpressionAssert(holder, expression, false)
JavaPsiFacade.getInstance(expression.project) JUNIT5_ASSERT_CLASSNAME -> visitMethodCallExpressionAssert(holder, expression, true)
.findClass(AssertJClassNames.ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return JUNIT4_ASSUME_CLASSNAME -> visitMethodCallExpressionAssume(holder, expression, false)
val mapping = ASSERT_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return JUNIT5_ASSUME_CLASSNAME -> visitMethodCallExpressionAssume(holder, expression, true)
if (mapping.hasDelta) {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT, ::ReplaceJUnitDeltaAssertMethodCallQuickFix)
} else {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method ->
ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected)
}
}
}
JUNIT_ASSUME_CLASSNAME -> {
JavaPsiFacade.getInstance(expression.project)
.findClass(AssertJClassNames.ASSUMPTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
val mapping = ASSUME_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return
if (!mapping.singleArgument || expression.argumentList.expressions.size == 1) {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSUME_THAT) { desc, method ->
ReplaceJUnitAssumeMethodCallQuickFix(desc, method)
}
}
}
} }
} }
} }
} }
private fun visitMethodCallExpressionAssert(holder: ProblemsHolder, expression: PsiMethodCallExpression, junit5: Boolean) {
JavaPsiFacade.getInstance(expression.project)
.findClass(AssertJClassNames.ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
val mapping = ASSERT_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return
if (mapping.hasDelta) {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method ->
ReplaceJUnitDeltaAssertMethodCallQuickFix(desc, method, junit5)
}
} else {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSERT_THAT) { desc, method ->
ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected, junit5)
}
}
}
private fun visitMethodCallExpressionAssume(holder: ProblemsHolder, expression: PsiMethodCallExpression, junit5: Boolean) {
JavaPsiFacade.getInstance(expression.project)
.findClass(AssertJClassNames.ASSUMPTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
val mapping = ASSUME_MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return
if (!mapping.singleArgument || expression.argumentList.expressions.size == 1) {
registerConvertMethod(holder, expression, mapping.replacement, MethodNames.ASSUME_THAT) { desc, method ->
ReplaceJUnitAssumeMethodCallQuickFix(desc, method, junit5)
}
}
}
private fun registerConvertMethod( private fun registerConvertMethod(
holder: ProblemsHolder, holder: ProblemsHolder,
expression: PsiMethodCallExpression, expression: PsiMethodCallExpression,
@@ -0,0 +1,31 @@
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.intellij.psi.PsiUnaryExpression
import com.intellij.psi.util.PsiUtil
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class InvertUnaryExpressionQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
companion object {
private const val INVERT_CONDITION_DESCRIPTION = "Invert condition in isEqualTo()/isNotEqualTo() expressions"
}
override fun getFamilyName(): String {
return INVERT_CONDITION_DESCRIPTION
}
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val methodCall = descriptor.startElement as? PsiMethodCallExpression ?: return
val assertExpression = methodCall.firstArg as? PsiUnaryExpression ?: return
val operand = PsiUtil.skipParenthesizedExprDown(assertExpression.operand) ?: return
val expectedExpression = createExpectedMethodCall(assertExpression, replacementMethod, operand)
expectedExpression.replaceQualifierFromMethodCall(methodCall)
methodCall.replace(expectedExpression)
}
}
@@ -7,7 +7,7 @@ import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME
class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val noExpectedExpression: Boolean) : class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val noExpectedExpression: Boolean, private val junit5: Boolean) :
AbstractCommonQuickFix(description) { AbstractCommonQuickFix(description) {
companion object { companion object {
@@ -23,14 +23,20 @@ class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val repl
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList val args = methodCallExpression.argumentList
val count = args.expressions.size val count = args.expressions.size
val actualExpression = args.expressions[count - 1] ?: return val hasMessage = if (noExpectedExpression) count == 1 else count == 2;
val (expectedExpressions, messageExpression) = if (noExpectedExpression) {
val message = args.expressions.getOrNull(count - 2) val actualExpression: PsiExpression
emptyArray<PsiExpression>() to message val expectedExpressions: Array<PsiExpression>
val messageExpression: PsiExpression?
if (junit5) {
actualExpression = args.expressions[if (noExpectedExpression) 0 else 1] ?: return
messageExpression = if (hasMessage) null else args.expressions[count - 1]
expectedExpressions = if (noExpectedExpression) emptyArray() else arrayOf(args.expressions[0])
} else { } else {
val expected = args.expressions[count - 2] ?: return actualExpression = args.expressions[count - 1] ?: return
val message = args.expressions.getOrNull(count - 3) messageExpression = if (hasMessage) null else args.expressions[0]
arrayOf(expected) to message expectedExpressions = if (noExpectedExpression) emptyArray() else arrayOf(args.expressions[count - 2])
} }
val swapActualAndExpected = ((expectedExpressions.getOrNull(0)?.calculateConstantValue() == null) val swapActualAndExpected = ((expectedExpressions.getOrNull(0)?.calculateConstantValue() == null)
@@ -5,7 +5,7 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.*
class ReplaceJUnitAssumeMethodCallQuickFix(description: String, private val replacementMethod: String) : class ReplaceJUnitAssumeMethodCallQuickFix(description: String, private val replacementMethod: String, private val junit5: Boolean) :
AbstractCommonQuickFix(description) { AbstractCommonQuickFix(description) {
companion object { companion object {
@@ -21,8 +21,8 @@ class ReplaceJUnitAssumeMethodCallQuickFix(description: String, private val repl
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList val args = methodCallExpression.argumentList
val count = args.expressions.size val count = args.expressions.size
val actualExpression = args.expressions[count - 1] ?: return val actualExpression = args.expressions[if (junit5) 0 else count - 1] ?: return
val messageExpression = args.expressions.getOrNull(count - 2) val messageExpression = args.expressions.getOrNull(if (junit5) 1 else count - 2)
val expectedMethodCall = createExpectedMethodCall(element, replacementMethod) val expectedMethodCall = createExpectedMethodCall(element, replacementMethod)
val newMethodCall = createAssumeThat(element, actualExpression) val newMethodCall = createAssumeThat(element, actualExpression)
@@ -6,7 +6,7 @@ import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.* import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME
class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) { class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val junit5: Boolean) : AbstractCommonQuickFix(description) {
companion object { companion object {
private const val CONVERT_DESCRIPTION = "Convert JUnit assertions with delta to assertJ" private const val CONVERT_DESCRIPTION = "Convert JUnit assertions with delta to assertJ"
@@ -21,10 +21,10 @@ class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList val args = methodCallExpression.argumentList
val count = args.expressions.size val count = args.expressions.size
val messageExpression = args.expressions.getOrNull(count - 4) val messageExpression = args.expressions.getOrNull(if (junit5) 3 else count - 4)
val expectedExpression = args.expressions[count - 3] ?: return val expectedExpression = args.expressions[if (junit5) 0 else count - 3] ?: return
val actualExpression = args.expressions[count - 2] ?: return val actualExpression = args.expressions[if (junit5) 1 else count - 2] ?: return
val deltaExpression = args.expressions[count - 1] ?: return val deltaExpression = args.expressions[if (junit5) 2 else count - 1] ?: return
val offsetMethodCall = createMethodCall(element, "org.assertj.core.data.Offset.offset", deltaExpression) val offsetMethodCall = createMethodCall(element, "org.assertj.core.data.Offset.offset", deltaExpression)
@@ -70,7 +70,7 @@ class ExtractorReferenceContributor : PsiReferenceContributor() {
class ExtractorReference(literal: PsiLiteralExpression, range: TextRange, private val targets: List<PsiElement>) : class ExtractorReference(literal: PsiLiteralExpression, range: TextRange, private val targets: List<PsiElement>) :
PsiPolyVariantReferenceBase<PsiLiteralExpression>(literal, range, true) { PsiPolyVariantReferenceBase<PsiLiteralExpression>(literal, range, true) {
// Do not remove due to compatiblity issue with IDEA <= 2018.2 // Do not remove due to compatibility issue with IDEA <= 2018.2
override fun getVariants(): Array<Any> { override fun getVariants(): Array<Any> {
return ArrayUtil.EMPTY_OBJECT_ARRAY return ArrayUtil.EMPTY_OBJECT_ARRAY
} }
@@ -1,6 +1,6 @@
<html> <html>
<body> <body>
Turns assertThat(enumerable).hasSize(0) into assertThat(enumerable).isEmpty(). Turns assertThat(enumerable).hasSize(0) and similar into assertThat(enumerable).isEmpty() or .isNotEmpty().
<!-- tooltip end --> <!-- tooltip end -->
<br>Works with anything that is enumerable such as arrays, iterables, collections, etc. <br>Works with anything that is enumerable such as arrays, iterables, collections, etc.
</body> </body>
@@ -1,6 +1,6 @@
<html> <html>
<body> <body>
Turns assertThat(!condition).isEqualTo(true/false) into assertThat(condition).isFalse()/isTrue(). Turns assertThat(!condition).isEqualTo(true/false) into assertThat(condition).isFalse()/isTrue() and negates .is(Not)EqualTo(!var).
<!-- tooltip end --> <!-- tooltip end -->
<br>Also works with constant expressions and Boolean.TRUE/FALSE. <br>Also works with constant expressions and Boolean.TRUE/FALSE.
</body> </body>
@@ -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;
@@ -15,7 +16,10 @@ import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.*; import com.intellij.testFramework.EdtTestUtilKt;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.TestLoggerFactory;
import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy; import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy;
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture; import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
@@ -133,15 +137,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(); Store store = getStore(extensionContext);
UsefulTestCase.clearFields(this); Disposable disposable = (Disposable) store.get("disposable");
if (myFixture != null && getProject() != null && !getProject().isDisposed()) { if (myFixture != null && disposable != null) {
Disposer.dispose(getProject()); Disposer.dispose(disposable);
store.remove("disposable");
} }
super.tearDown();
} }
@NotNull @NotNull
@@ -172,7 +180,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() {
@@ -10,10 +10,14 @@ internal class AssertThatEnumerableIsEmptyInspectionTest : AbstractCajonTest() {
@Test @Test
@TestDataSubPath("inspections/EnumerableIsEmpty") @TestDataSubPath("inspections/EnumerableIsEmpty")
internal fun assertThat_with_hasSize_zero_can_use_isEmpty(@MyFixture myFixture: JavaCodeInsightTestFixture) { internal fun assertThat_with_hasSize_zero_and_similar_can_use_isEmpty(@MyFixture myFixture: JavaCodeInsightTestFixture) {
myFixture.enableInspections(AssertThatEnumerableIsEmptyInspection::class.java) myFixture.enableInspections(AssertThatEnumerableIsEmptyInspection::class.java)
myFixture.configureByFile("EnumerableIsEmptyBefore.java") myFixture.configureByFile("EnumerableIsEmptyBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Replace hasSize() with isEmpty()"), 5) executeQuickFixes(myFixture, Regex.fromLiteral("Replace hasSize() with isEmpty()"), 5)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace hasSizeLessThan() with isEmpty()"), 5)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace hasSizeLessThanOrEqualTo() with isEmpty()"), 5)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace hasSizeGreaterThan() with isNotEmpty()"), 6)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace hasSizeGreaterThanOrEqualTo() with isNotEmpty()"), 6)
myFixture.checkResultByFile("EnumerableIsEmptyAfter.java") myFixture.checkResultByFile("EnumerableIsEmptyAfter.java")
} }
} }
@@ -14,6 +14,8 @@ internal class AssertThatInvertedBooleanConditionInspectionTest : AbstractCajonT
myFixture.enableInspections(AssertThatInvertedBooleanConditionInspection::class.java) myFixture.enableInspections(AssertThatInvertedBooleanConditionInspection::class.java)
myFixture.configureByFile("InvertedBooleanConditionBefore.java") myFixture.configureByFile("InvertedBooleanConditionBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Invert condition in assertThat()"), 25) executeQuickFixes(myFixture, Regex.fromLiteral("Invert condition in assertThat()"), 25)
executeQuickFixes(myFixture, Regex.fromLiteral("Invert condition in isEqualTo() and use isNotEqualTo() instead"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Invert condition in isNotEqualTo() and use isEqualTo() instead"), 2)
myFixture.checkResultByFile("InvertedBooleanConditionAfter.java") myFixture.checkResultByFile("InvertedBooleanConditionAfter.java")
} }
} }
@@ -16,7 +16,7 @@ internal class ImplicitAssertionInspectionTest : AbstractCajonTest() {
internal fun implicit_assertions_can_be_removed(@MyFixture myFixture: JavaCodeInsightTestFixture) { internal fun implicit_assertions_can_be_removed(@MyFixture myFixture: JavaCodeInsightTestFixture) {
myFixture.enableInspections(ImplicitAssertionInspection::class.java) myFixture.enableInspections(ImplicitAssertionInspection::class.java)
myFixture.configureByFile("ImplicitAssertionBefore.java") myFixture.configureByFile("ImplicitAssertionBefore.java")
executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Delete implicit isNotNull\\(\\) covered by .*"), 101) executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Delete implicit isNotNull\\(\\) covered by .*"), 102)
executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Delete implicit isNotEmpty\\(\\) covered by .*"), 17) executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Delete implicit isNotEmpty\\(\\) covered by .*"), 17)
executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Delete implicit isPresent\\(\\) covered by .*"), 8) executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Delete implicit isPresent\\(\\) covered by .*"), 8)
myFixture.checkResultByFile("ImplicitAssertionAfter.java") myFixture.checkResultByFile("ImplicitAssertionAfter.java")
@@ -0,0 +1,23 @@
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(org.junit.jupiter.api.Assertions::class, Assertions::class)
internal class JUnit5AssertToAssertJInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/JUnit5AssertToAssertJ")
internal fun junit5_Assertions_can_be_converted_into_AssertJ(@MyFixture myFixture: JavaCodeInsightTestFixture) {
myFixture.enableInspections(JUnitAssertToAssertJInspection::class.java)
myFixture.configureByFile("JUnit5AssertToAssertJInspectionBefore.java")
executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Convert assert.*\\(\\) to assertThat\\(\\).*"), 48)
executeQuickFixesNoFamilyNameCheck(myFixture, Regex("Convert assume.*\\(\\) to assumeThat\\(\\).*"), 4)
myFixture.checkResultByFile("JUnit5AssertToAssertJInspectionAfter.java")
}
}
@@ -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)
@@ -16,7 +16,32 @@ public class EnumerableIsEmpty {
assertThat(new ArrayList<Long>()).as("etc").hasSize(1); assertThat(new ArrayList<Long>()).as("etc").hasSize(1);
assertThat(new Long[1]).as("etc").hasSize(1); assertThat(new Long[1]).as("etc").hasSize(1);
assertThat("string").as("foo").isEmpty();
assertThat(new StringBuilder()).as("bar").isEmpty();
assertThat(new ArrayList<Long>()).as("etc").isEmpty();
assertThat(new Long[1]).as("etc").isEmpty();
assertThat("string").as("foo").isEmpty();
assertThat(new StringBuilder()).as("bar").isEmpty();
assertThat(new ArrayList<Long>()).as("etc").isEmpty();
assertThat(new Long[1]).as("etc").isEmpty();
assertThat("string").as("foo").isNotEmpty();
assertThat(new StringBuilder()).as("bar").isNotEmpty();
assertThat(new ArrayList<Long>()).as("etc").isNotEmpty();
assertThat(new Long[1]).as("etc").isNotEmpty();
assertThat("string").as("foo").isNotEmpty();
assertThat(new StringBuilder()).as("bar").isNotEmpty();
assertThat(new ArrayList<Long>()).as("etc").isNotEmpty();
assertThat(new Long[1]).as("etc").isNotEmpty();
assertThat("string").as("foo").hasSize(0).hasSameSizeAs("foo").isEmpty(); assertThat("string").as("foo").hasSize(0).hasSameSizeAs("foo").isEmpty();
assertThat("string").as("foo").hasSizeLessThanOrEqualTo(0).hasSameSizeAs("foo").isEmpty();
assertThat("string").as("foo").hasSizeLessThan(1).hasSameSizeAs("foo").isEmpty();
assertThat("string").as("foo").isNotEmpty().hasSameSizeAs("foo").isNotEmpty();
assertThat("string").as("foo").isNotEmpty().hasSameSizeAs("foo").isNotEmpty();
org.junit.Assert.assertThat("foo", null); org.junit.Assert.assertThat("foo", null);
fail("oh no!"); fail("oh no!");
@@ -16,7 +16,32 @@ public class EnumerableIsEmpty {
assertThat(new ArrayList<Long>()).as("etc").hasSize(1); assertThat(new ArrayList<Long>()).as("etc").hasSize(1);
assertThat(new Long[1]).as("etc").hasSize(1); assertThat(new Long[1]).as("etc").hasSize(1);
assertThat("string").as("foo").hasSizeLessThanOrEqualTo(0);
assertThat(new StringBuilder()).as("bar").hasSizeLessThanOrEqualTo(0 + 0);
assertThat(new ArrayList<Long>()).as("etc").hasSizeLessThanOrEqualTo(10 / 100);
assertThat(new Long[1]).as("etc").hasSizeLessThanOrEqualTo(1 - 1);
assertThat("string").as("foo").hasSizeLessThan(1);
assertThat(new StringBuilder()).as("bar").hasSizeLessThan(0 + 1);
assertThat(new ArrayList<Long>()).as("etc").hasSizeLessThan(10 / 10);
assertThat(new Long[1]).as("etc").hasSizeLessThan(1 - 0);
assertThat("string").as("foo").hasSizeGreaterThan(0);
assertThat(new StringBuilder()).as("bar").hasSizeGreaterThan(0 + 0);
assertThat(new ArrayList<Long>()).as("etc").hasSizeGreaterThan(10 / 100);
assertThat(new Long[1]).as("etc").hasSizeGreaterThan(1 - 1);
assertThat("string").as("foo").hasSizeGreaterThanOrEqualTo(1);
assertThat(new StringBuilder()).as("bar").hasSizeGreaterThanOrEqualTo(0 + 1);
assertThat(new ArrayList<Long>()).as("etc").hasSizeGreaterThanOrEqualTo(10 / 10);
assertThat(new Long[1]).as("etc").hasSizeGreaterThanOrEqualTo(1 - 0);
assertThat("string").as("foo").hasSize(0).hasSameSizeAs("foo").hasSize(0); assertThat("string").as("foo").hasSize(0).hasSameSizeAs("foo").hasSize(0);
assertThat("string").as("foo").hasSizeLessThanOrEqualTo(0).hasSameSizeAs("foo").hasSizeLessThanOrEqualTo(0);
assertThat("string").as("foo").hasSizeLessThan(1).hasSameSizeAs("foo").hasSizeLessThan(1);
assertThat("string").as("foo").hasSizeGreaterThan(0).hasSameSizeAs("foo").hasSizeGreaterThan(0);
assertThat("string").as("foo").hasSizeGreaterThanOrEqualTo(1).hasSameSizeAs("foo").hasSizeGreaterThanOrEqualTo(1);
org.junit.Assert.assertThat("foo", null); org.junit.Assert.assertThat("foo", null);
fail("oh no!"); fail("oh no!");
@@ -153,6 +153,7 @@ public class ImplicitAssertion {
assertThat(list).areAtMost(1, stringCondition); assertThat(list).areAtMost(1, stringCondition);
assertThat(list).areExactly(1, stringCondition); assertThat(list).areExactly(1, stringCondition);
assertThat(list).hasOnlyOneElementSatisfying(stringConsumer); assertThat(list).hasOnlyOneElementSatisfying(stringConsumer);
assertThat(list).singleElement(as(STRING)).isEqualTo(stringConsumer);
assertThat(list).haveAtLeastOne(stringCondition); assertThat(list).haveAtLeastOne(stringCondition);
assertThat(list).haveAtLeast(1, stringCondition); assertThat(list).haveAtLeast(1, stringCondition);
assertThat(list).haveAtMost(1, stringCondition); assertThat(list).haveAtMost(1, stringCondition);
@@ -229,6 +230,7 @@ public class ImplicitAssertion {
assertThat(list).isNotEmpty().areAtMost(1, stringCondition); assertThat(list).isNotEmpty().areAtMost(1, stringCondition);
assertThat(list).isNotEmpty().areExactly(1, stringCondition); assertThat(list).isNotEmpty().areExactly(1, stringCondition);
assertThat(list).isNotEmpty().hasOnlyOneElementSatisfying(stringConsumer); assertThat(list).isNotEmpty().hasOnlyOneElementSatisfying(stringConsumer);
assertThat(list).isNotEmpty().singleElement(as(STRING)).isEqualTo(stringConsumer);
assertThat(list).haveAtLeastOne(stringCondition); assertThat(list).haveAtLeastOne(stringCondition);
assertThat(list).isNotEmpty().haveAtLeast(1, stringCondition); assertThat(list).isNotEmpty().haveAtLeast(1, stringCondition);
assertThat(list).isNotEmpty().haveAtMost(1, stringCondition); assertThat(list).isNotEmpty().haveAtMost(1, stringCondition);
@@ -153,6 +153,7 @@ public class ImplicitAssertion {
assertThat(list).isNotNull().areAtMost(1, stringCondition); assertThat(list).isNotNull().areAtMost(1, stringCondition);
assertThat(list).isNotNull().areExactly(1, stringCondition); assertThat(list).isNotNull().areExactly(1, stringCondition);
assertThat(list).isNotNull().hasOnlyOneElementSatisfying(stringConsumer); assertThat(list).isNotNull().hasOnlyOneElementSatisfying(stringConsumer);
assertThat(list).isNotNull().singleElement(as(STRING)).isEqualTo(stringConsumer);
assertThat(list).isNotNull().haveAtLeastOne(stringCondition); assertThat(list).isNotNull().haveAtLeastOne(stringCondition);
assertThat(list).isNotNull().haveAtLeast(1, stringCondition); assertThat(list).isNotNull().haveAtLeast(1, stringCondition);
assertThat(list).isNotNull().haveAtMost(1, stringCondition); assertThat(list).isNotNull().haveAtMost(1, stringCondition);
@@ -229,6 +230,7 @@ public class ImplicitAssertion {
assertThat(list).isNotEmpty().areAtMost(1, stringCondition); assertThat(list).isNotEmpty().areAtMost(1, stringCondition);
assertThat(list).isNotEmpty().areExactly(1, stringCondition); assertThat(list).isNotEmpty().areExactly(1, stringCondition);
assertThat(list).isNotEmpty().hasOnlyOneElementSatisfying(stringConsumer); assertThat(list).isNotEmpty().hasOnlyOneElementSatisfying(stringConsumer);
assertThat(list).isNotEmpty().singleElement(as(STRING)).isEqualTo(stringConsumer);
assertThat(list).isNotEmpty().haveAtLeastOne(stringCondition); assertThat(list).isNotEmpty().haveAtLeastOne(stringCondition);
assertThat(list).isNotEmpty().haveAtLeast(1, stringCondition); assertThat(list).isNotEmpty().haveAtLeast(1, stringCondition);
assertThat(list).isNotEmpty().haveAtMost(1, stringCondition); assertThat(list).isNotEmpty().haveAtMost(1, stringCondition);
@@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.fail;
public class InvertedBooleanCondition { public class InvertedBooleanCondition {
private void invertedBooleanCondition() { private void invertedBooleanCondition(boolean primitiveVariable, Boolean objectVariable) {
boolean primitive = false; boolean primitive = false;
Boolean object = Boolean.TRUE; Boolean object = Boolean.TRUE;
@@ -37,6 +37,23 @@ public class InvertedBooleanCondition {
assertThat(primitive).as("foo").isFalse().as("bar").isFalse(); assertThat(primitive).as("foo").isFalse().as("bar").isFalse();
assertThat(primitive).as("foo").isFalse().as("bar").isTrue(); assertThat(primitive).as("foo").isFalse().as("bar").isTrue();
assertThat(primitive).isNotEqualTo(primitiveVariable);
assertThat(primitive).isEqualTo(primitiveVariable);
assertThat(object).isNotEqualTo(primitiveVariable);
assertThat(object).isEqualTo(primitiveVariable);
assertThat(primitive).isEqualTo(!objectVariable); // not safe for null value
assertThat(primitive).isNotEqualTo(!objectVariable); // not safe for null value
assertThat(object).isEqualTo(!objectVariable); // not safe for null value
assertThat(object).isNotEqualTo(!objectVariable); // not safe for null value
assertThat(primitive).isNotEqualTo(primitiveVariable);
assertThat(primitive).isNotEqualTo(primitiveVariable);
assertThat(primitive).isEqualTo(!primitiveVariable && objectVariable);
org.junit.Assert.assertThat(object, null); org.junit.Assert.assertThat(object, null);
fail("oh no!"); fail("oh no!");
} }
@@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.fail;
public class InvertedBooleanCondition { public class InvertedBooleanCondition {
private void invertedBooleanCondition() { private void invertedBooleanCondition(boolean primitiveVariable, Boolean objectVariable) {
boolean primitive = false; boolean primitive = false;
Boolean object = Boolean.TRUE; Boolean object = Boolean.TRUE;
@@ -37,6 +37,23 @@ public class InvertedBooleanCondition {
assertThat(!primitive).as("foo").isEqualTo(Boolean.TRUE).as("bar").isNotEqualTo(false); assertThat(!primitive).as("foo").isEqualTo(Boolean.TRUE).as("bar").isNotEqualTo(false);
assertThat(!primitive).as("foo").isEqualTo(Boolean.TRUE).as("bar").isNotEqualTo(true); assertThat(!primitive).as("foo").isEqualTo(Boolean.TRUE).as("bar").isNotEqualTo(true);
assertThat(primitive).isEqualTo(!primitiveVariable);
assertThat(primitive).isNotEqualTo(!primitiveVariable);
assertThat(object).isEqualTo(!primitiveVariable);
assertThat(object).isNotEqualTo(!primitiveVariable);
assertThat(primitive).isEqualTo(!objectVariable); // not safe for null value
assertThat(primitive).isNotEqualTo(!objectVariable); // not safe for null value
assertThat(object).isEqualTo(!objectVariable); // not safe for null value
assertThat(object).isNotEqualTo(!objectVariable); // not safe for null value
assertThat(primitive).isEqualTo((!primitiveVariable));
assertThat(primitive).isEqualTo(!(primitiveVariable));
assertThat(primitive).isEqualTo(!primitiveVariable && objectVariable);
org.junit.Assert.assertThat(object, null); org.junit.Assert.assertThat(object, null);
fail("oh no!"); fail("oh no!");
} }
@@ -0,0 +1,86 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
import static org.assertj.core.data.Offset.offset;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
public class JUnit5AssertToAssertJ {
private void jUnit5AssertToAssertJ() {
String foo = "foo";
String bar = "bar";
int someInt = 1;
double someDouble = 1.0;
float someFloat = 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]).containsExactly(new int[2]);
assertThat(new int[1]).as("array equals").containsExactly(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(foo).isEqualTo("bar");
assertThat(bar).as("equals").isEqualTo("foo");
assertThat(bar).isNotEqualTo("foo");
assertThat(foo).as("equals").isNotEqualTo("bar");
assertThat(someInt).isEqualTo(2);
assertThat(someDouble).isCloseTo(2.0, offset(0.1));
assertThat(someDouble).as("equals").isEqualTo(1.0);
assertThat(someDouble).as("equals").isCloseTo(1.0, offset(0.1));
assertThat(someFloat).isEqualTo(1.0f);
assertThat(someFloat).isCloseTo(2.0f, offset(0.1f));
fail();
fail("oh no!")
}
private void jUnit5AssumeToAssertJ() {
String foo = "foo";
String bar = "bar";
assumeThat(foo == "foo").isTrue();
assumeThat(foo == "foo").as("oh no!").isTrue();
assumeThat(foo == "bar").isFalse();
assumeThat(foo == "bar").as("boom!").isFalse();
}
}
@@ -0,0 +1,83 @@
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
public class JUnit5AssertToAssertJ {
private void jUnit5AssertToAssertJ() {
String foo = "foo";
String bar = "bar";
int someInt = 1;
double someDouble = 1.0;
float someFloat = 1.0f;
assertTrue(foo == "foo");
assertTrue(foo == "foo", "oh no!");
assertFalse(foo == "bar");
assertFalse(foo == "bar", "boom!");
assertNull(foo);
assertNull(foo, "oh no!");
assertNotNull(foo);
assertNotNull(foo, "oh no!");
assertEquals(bar, foo);
assertEquals(bar, foo, "equals");
assertNotEquals(bar, foo);
assertNotEquals(bar, foo, "equals");
assertSame(bar, foo);
assertSame(bar, foo, "same");
assertNotSame(bar, foo);
assertNotSame(bar, foo, "same");
assertEquals(1.0, 2.0);
assertEquals(1.0, 2.0, 0.1);
assertEquals(1.0, 2.0, "equals");
assertEquals(1.0, 2.0, 0.1, "equals");
assertEquals(1.0f, 2.0f);
assertEquals(1.0f, 2.0f, 0.1f);
assertEquals(1.0f, 2.0f, "equals");
assertEquals(1.0f, 2.0f, 0.1f, "equals");
assertNotEquals(1.0, 2.0);
assertNotEquals(1.0, 2.0, 0.1);
assertNotEquals(1.0, 2.0, "equals");
assertNotEquals(1.0, 2.0, 0.1, "equals");
assertNotEquals(1.0f, 2.0f);
assertNotEquals(1.0f, 2.0f, 0.1f);
assertNotEquals(1.0f, 2.0f, "equals");
assertNotEquals(1.0f, 2.0f, 0.1f, "equals");
assertArrayEquals(new int[2], new int[1]);
assertArrayEquals(new int[2], new int[1], "array equals");
assertArrayEquals(new double[2], new double[1], 1.0);
assertArrayEquals(new double[2], new double[1], 1.0, "array equals");
assertArrayEquals(new float[2], new float[1], 1.0f);
assertArrayEquals(new float[2], new float[1], 1.0f, "array equals");
assertEquals("bar", foo);
assertEquals(bar, "foo", "equals");
assertNotEquals(bar, "foo");
assertNotEquals("bar", foo, "equals");
assertEquals(someInt, 2);
assertEquals(someDouble, 2.0, 0.1);
assertEquals(1.0, someDouble, "equals");
assertEquals(1.0, someDouble, 0.1, "equals");
assertEquals(1.0f, someFloat);
assertEquals(someFloat, 2.0f, 0.1f);
fail();
fail("oh no!")
}
private void jUnit5AssumeToAssertJ() {
String foo = "foo";
String bar = "bar";
assumeTrue(foo == "foo");
assumeTrue(foo == "foo", "oh no!");
assumeFalse(foo == "bar");
assumeFalse(foo == "bar", "boom!");
}
}
@@ -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(".."));