Compare commits

...
20 Commits
Author SHA1 Message Date
chrisly42 941ddfdb5e Implemented first version of JoinAssertThatStatements inspection that will try to merge assertThat() statements with the same actual object together, preserving comments. 2019-04-28 20:43:42 +02:00
chrisly42 666e373405 Extended AssertThatSize inspection to transform hasSize() into hasSameSizeAs(), if possible. 2019-04-23 20:16:43 +02:00
chrisly42 8b0da63f86 Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions (really, Jetbrains, this sucks for no reason). Consolidated location of methods. 2019-04-23 18:19:47 +02:00
chrisly42 66508ceb2c New AssertThatInstanceOf inspection that moves instanceof expressions out of assertThat(). Fixes to documentation. 2019-04-22 19:03:59 +02:00
chrisly42 db02f7fb93 New AssertThatInvertedBooleanCondition inspection that will remove inverted boolean expressions inside assertThat().
Renamed a few inspections to better/shorter names (and fixed file and directory names accordingly).
2019-04-20 18:40:38 +02:00
chrisly42 a707eee9ad Extended AssertThatSize intention to take strings and CharSequences into account, too. 2019-04-20 09:04:38 +02:00
chrisly42 533c20906a Added a note on referencing. Moved AssertThatStringExpression to a more appropriate place in documentation. 2019-04-19 19:44:40 +02:00
chrisly42 da83f7f101 New AssertThatStringExpression that will move isEmpty(), equals(), equalsIgnoreCase(), contains(), startsWith(), and endsWith() out of actual expression. Bumped intellij-plugin to latest version. 2019-04-19 19:33:14 +02:00
chrisly42 faeb509797 Fixed default method not available in IDEA <2018.3. Sigh :-( 2019-04-18 22:29:30 +02:00
chrisly42 9f91fb3ccf Added support for referencing and refactoring inside ``.extracting()`` methods with fields, properties and methods (though getter renaming does not work that perfect, but I'm giving up for now as the IntelliJ SDK docs are seriously lacking).
Fixed an exception in batch mode if the description string was the same but for different fixes. Now descriptions are different for quick fixes triggered by AssertThatJava8OptionalInspection and AssertThatGuavaOptionalInspection. Minor refactorings. Extended documentation.
2019-04-18 22:12:48 +02:00
chrisly42 b58d8cfd2f Fix for incompatible method call regarding IDEA <2018.2.
Heavy refactoring regarding quick fixes (using more extensions).
Even more refactoring.
Fixed/extended AssertThatGuavaOptionalInspection regarding static.
imports and wrong reference to core assertThat() where Guava assertThat() actually was necessary.
2019-04-13 18:35:49 +02:00
chrisly42 4e6d53b3dc Reduced minimal supported IDEA version from 2018.2 to 2017.2.
Added AssertThatGuavaOptional inspection. Prepared next release.
Bumped to Kotlin 1.3.30.
2019-04-11 23:55:35 +02:00
chrisly42 2cdc242125 Refactored Code to avoid string duplications... added Boolean.map() extension. 2019-04-11 21:09:10 +02:00
chrisly42 d49b7bf17b Optimized even more code. Fixed BinaryExpression for Boolean.TRUE/FALSE. Added new AssertThatJava8Optional inspection. Added changelog to README. 2019-04-11 16:26:11 +02:00
chrisly42 c1d8ade7b1 Optimized code. More kotlin-style stuff. Made detecting of Boolean.TRUE/FALSE available to all constant evaluations. 2019-04-08 11:56:13 +02:00
chrisly42 bdabcc7255 Removed TODO about AssertThatBinaryExpressionIsTrueOrFalse. 2019-04-07 11:37:10 +02:00
chrisly42 5812e72227 New inspection AssertThatBinaryExpressionIsTrueOrFalse that will find and fix common binary expressions and equals() statements (more than 150 combinations) inside assertThat(). 2019-04-07 11:29:07 +02:00
chrisly42 6a44237ca0 Added tacky icon. 2019-04-06 21:29:18 +02:00
chrisly42 51703e8499 Merged AssertThatObjectIsNull and AssertThatObjectIsNotNull to AssertThatObjectIsNullOrNotNull.
Extended tests to be more explicit regarding the expected quick fix messages.
2019-04-06 21:29:18 +02:00
chrisly42 ba56325299 Internally: Upgraded to AssertJ 13.2.2.
Support for hasSizeLessThan(), hasSizeLessThanOrEqualTo(), hasSizeGreaterThanOrEqualTo(), and hasSizeGreaterThan() for AssertThatSizeInspection (with AssertJ >=13.2.0).
Really fixed highlighting for JUnit conversion. Sorry.
Fixed testing code to work against IDEA 2019.1.
2019-04-06 21:29:13 +02:00
108 changed files with 4068 additions and 633 deletions
+291 -15
View File
@@ -1,15 +1,17 @@
# Cajon - Concise AssertJ Optimizing Nitpicker # Cajon - Concise AssertJ Optimizing Nitpicker
Cajon is an IntelliJ IDEA Plugin for shortening and optimizing AssertJ assertions. Cajon is an IntelliJ IDEA Plugin for shortening and optimizing [AssertJ](https://assertj.github.io/doc/) assertions.
## Why? ## Purpose
First, code is easier to read, when it is concise and reflects the intention clearly. First, code is easier to read, when it is concise and reflects the intention clearly.
AssertJ has plenty of different convenience methods that describing various intentions precisely. AssertJ has plenty of different convenience methods that describing various intentions precisely.
Why write longer, more complex code that can be expressed in brevity? Why write longer, more complex code that can be expressed in brevity?
Second, AssertJ is able to output more meaningful descriptions when an assertion fails. Second, when using the available special assertion methods of AssertJ, a failure of a condition
can be expressed in better detail and with more meaningful descriptions.
This makes finding bugs and fixing failed tests more efficient. This makes finding bugs and fixing failed tests more efficient.
Nobody likes to read failures of the kind "failed because true is not false".
For example: For example:
@@ -17,7 +19,7 @@ For example:
assertThat(collection.size()).isEqualTo(5); assertThat(collection.size()).isEqualTo(5);
``` ```
If the collection has more or less than 5 elements, the assertion will fail, but will not If the collection has more or less than five elements, the assertion will fail, but will not
tell you about the contents, making it hard to guess what went wrong. tell you about the contents, making it hard to guess what went wrong.
Instead, if you wrote the same assertion the following way: Instead, if you wrote the same assertion the following way:
@@ -26,40 +28,132 @@ Instead, if you wrote the same assertion the following way:
assertThat(collection).hasSize(5); assertThat(collection).hasSize(5);
``` ```
Then AssertJ would tell you the contents of the collection on failure. 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 assertions to AssertJ.
## Implemented inspections ## Lookup and refactoring of string-based extracting()
- AssertThatObjectIsNull AssertJ allows [extracting POJO fields/properties on iterables/arrays](http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#extracted-properties-assertion).
Using strings is not safe for refactoring (and before Java 8 Lambdas were available,
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
string to go to the definition) and also allows safe refactoring on the
fields (refactoring a getter method without a corresponding field will not work
correctly right now).
## Usage
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).
Or, you can use the "Run Inspection by Name..." action to run one inspection on a bigger scope (e.g. the whole project).
Applying a quick fix might result in further optimization possibilities, so
you might need to perform a couple of fixes before you get to the final result.
Check out this example where every line represents the result after a Cajon quickfix:
```
assertFalse(!(array.length == collection.size()));
assertThat(!(array.length == collection.size())).isFalse();
assertThat(array.length == collection.size()).isTrue();
assertThat(array.length).isEqualTo(collection.size());
assertThat(array).hasSameSizeAs(collection);
```
You can toggle the various inspections in the Settings/Editor/Inspections in the AssertJ group.
## Implemented inspections and quickfixes
- JoinAssertThatStatements
```
from: assertThat(expected).someCondition();
assertThat(expected).anotherCondition();
to: assertThat(expected).someCondition().anotherCondition();
```
Joining will work on actual expressions inside assertThat() that are
- the same variable reference
- textually equal binary expressions
- the same method calls (except for known side-effect methods such as ```Iterator.next()``` -- please notify me about others)
The comments of the statements will be preserved. When using ```.extracting()``` or similar, the statements will not be merged.
- AssertThatObjectIsNullOrNotNull
``` ```
from: assertThat(object).isEqualTo(null); from: assertThat(object).isEqualTo(null);
to: assertThat(object).isNull(); to: assertThat(object).isNull();
```
- AssertThatObjectIsNotNull
```
from: assertThat(object).isNotEqualTo(null); from: assertThat(object).isNotEqualTo(null);
to: assertThat(object).isNotNull(); to: assertThat(object).isNotNull();
``` ```
- AssertThatBooleanIsTrueOrFalse
- AssertThatBooleanCondition
``` ```
from: assertThat(booleanValue).isEqualTo(true/false/Boolean.TRUE/Boolean.FALSE); from: assertThat(booleanValue).isEqualTo(true/false/Boolean.TRUE/Boolean.FALSE);
to: assertThat(booleanValue).isTrue()/isFalse(); to: assertThat(booleanValue).isTrue()/isFalse();
``` ```
- AssertThatInvertedBooleanCondition
```
from: assertThat(!booleanValue).isEqualTo(true/false/Boolean.TRUE/Boolean.FALSE);
from: assertThat(!booleanValue).isTrue()/isFalse();
to: assertThat(booleanValue).isFalse()/isTrue();
```
- AssertThatInstanceOf
```
from: assertThat(object instanceof classname).isEqualTo(true);
from: assertThat(object instanceof classname).isTrue();
to: assertThat(object).isInstanceOf(classname.class);
from: assertThat(object instanceof classname).isEqualTo(false);
from: assertThat(object instanceof classname).isFalse();
to: assertThat(object).isNotInstanceOf(classname.class);
```
- AssertThatStringIsEmpty - AssertThatStringIsEmpty
``` ```
from: assertThat(charSequence/string).isEqualTo(""); from: assertThat(charSequence/string).isEqualTo("");
from: assertThat(charSequence/string).hasSize(0); from: assertThat(charSequence/string).hasSize(0);
to: assertThat(charSequence/string).isEmpty(); to: assertThat(charSequence/string).isEmpty();
``` ```
- AssertThatStringExpression
```
from: assertThat(stringActual.isEmpty()).isTrue();
to: assertThat(stringActual).isEmpty();
from: assertThat(stringActual.equals(stringExpected)).isTrue();
from: assertThat(stringActual.contentEquals(charSeqExpected)).isTrue();
to: assertThat(stringActual).isEqualTo(stringExpected);
from: assertThat(stringActual.equalsIgnoreCase(stringExpected)).isTrue();
to: assertThat(stringActual).isEqualToIgnoringCase(stringExpected);
from: assertThat(stringActual.contains(stringExpected)).isTrue();
to: assertThat(stringActual).contains(stringExpected);
from: assertThat(stringActual.startsWith(stringExpected)).isTrue();
to: assertThat(stringActual).startsWith(stringExpected);
from: assertThat(stringActual.endsWith(stringExpected)).isTrue();
to: assertThat(stringActual).endsWith(stringExpected);
```
Analogously with ```isFalse()```.
- AssertThatEnumerableIsEmpty - AssertThatEnumerableIsEmpty
``` ```
from: assertThat(enumerable).hasSize(0); from: assertThat(enumerable).hasSize(0);
to: assertThat(enumerable).isEmpty(); to: assertThat(enumerable).isEmpty();
``` ```
- AssertThatSize - AssertThatSize
``` ```
from: assertThat(array.length).isEqualTo(0); from: assertThat(array.length).isEqualTo(0);
@@ -75,9 +169,114 @@ The plugin also supports the conversion of the most common JUnit 4 assertions to
from: assertThat(array.length).isEqualTo(anotherArray.length); from: assertThat(array.length).isEqualTo(anotherArray.length);
to: assertThat(array).hasSameSizeAs(anotherArray); to: assertThat(array).hasSameSizeAs(anotherArray);
from: assertThat(array).hasSize(anotherArray.length);
to: assertThat(array).hasSameSizeAs(anotherArray);
``` ```
and analogously for collections... and additionally with AssertJ 13.2.0 or later
```
from: assertThat(array.length).isLessThanOrEqualTo(expression);
to: assertThat(array).hasSizeLessThanOrEqualTo(expression);
from: assertThat(array.length).isLessThan(expression);
to: assertThat(array).hasSizeLessThan(expression);
from: assertThat(array.length).isGreaterThan(expression);
to: assertThat(array).hasSizeGreaterThan(expression);
from: assertThat(array.length).isGreaterThanOrEqualTo(expression);
to: assertThat(array).hasSizeGreaterThanOrEqualTo(expression);
```
and analogously for collections, strings and CharSequences, e.g:
```
from: assertThat("string".length()).isLessThan(1);
to: assertThat("string").isEmpty();
from: assertThat("string".length()).isEqualTo(collection.size())
to: assertThat("string").hasSameSizeAs(collection);
from: assertThat("string".length()).hasSize("strong".length())
to: assertThat("string").hasSameSizeAs("strong");
```
- AssertThatBinaryExpression
```
from: assertThat(primActual == primExpected).isTrue();
to: assertThat(primActual).isEqualTo(primExpected);
from: assertThat(10 < primActual).isNotEqualTo(false);
to: assertThat(primActual).isGreaterThan(primExpected);
from: assertThat(objActual != objExpected).isEqualTo(true);
to: assertThat(objActual).isNotSameAs(objExpected);
from: assertThat(null == objActual).isFalse();
to: assertThat(objActual).isNotNull();
from: assertThat(objActual.equals(objExpected).isTrue();
to: assertThat(objActual).isEqualTo(objExpected);
```
...and many, many more combinations (more than 150).
- AssertThatJava8Optional
```
from: assertThat(opt.isPresent()).isEqualTo(true);
from: assertThat(opt.isPresent()).isNotEqualTo(false);
from: assertThat(opt.isPresent()).isTrue();
to: assertThat(opt).isPresent();
from: assertThat(opt.isPresent()).isEqualTo(false);
from: assertThat(opt.isPresent()).isNotEqualTo(true);
from: assertThat(opt.isPresent()).isFalse();
to: assertThat(opt).isNotPresent();
from: assertThat(opt.get()).isEqualTo("foo");
to: assertThat(opt).contains("foo");
from: assertThat(opt.get()).isSameAs("foo");
to: assertThat(opt).containsSame("foo");
from: assertThat(opt).isEqualTo(Optional.of("foo"));
from: assertThat(opt).isEqualTo(Optional.ofNullable("foo"));
to: assertThat(opt).contains("foo");
from: assertThat(opt).isEqualTo(Optional.empty());
to: assertThat(opt).isNotPresent();
from: assertThat(opt).isNotEqualTo(Optional.empty());
to: assertThat(opt).isPresent();
```
- AssertThatGuavaOptional
```
from: assertThat(opt.isPresent()).isEqualTo(true);
from: assertThat(opt.isPresent()).isNotEqualTo(false);
from: assertThat(opt.isPresent()).isTrue();
to: assertThat(opt).isPresent();
from: assertThat(opt.isPresent()).isEqualTo(false);
from: assertThat(opt.isPresent()).isNotEqualTo(true);
from: assertThat(opt.isPresent()).isFalse();
to: assertThat(opt).isAbsent();
from: assertThat(opt.get()).isEqualTo("foo");
to: assertThat(opt).contains("foo");
from: assertThat(opt).isEqualTo(Optional.of("foo"));
from: assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
to: assertThat(opt).contains("foo");
from: assertThat(opt).isEqualTo(Optional.absent());
to: assertThat(opt).isAbsent();
from: assertThat(opt).isNotEqualTo(Optional.absent());
to: assertThat(opt).isPresent();
```
AssertJ for Guava needs to be available in the classpath.
- JUnitAssertToAssertJ - JUnitAssertToAssertJ
``` ```
@@ -107,6 +306,83 @@ The plugin also supports the conversion of the most common JUnit 4 assertions to
assertArrayEquals(message, expectedDoubleOrFloatArray, actualDoubleOrFloatArray, delta); assertArrayEquals(message, expectedDoubleOrFloatArray, actualDoubleOrFloatArray, delta);
``` ```
## TODO ### Implemented referencing
- AssertThatGuavaOptionalContains
- extraction with property names to lambda with Java 8 ```
.extracting("field")
.extracting("outerField.fieldInsideObjectTypeOfOuterField.andSoOn")
.extracting("property") // where the class has a getProperty() (or isProperty() for boolean) method
.extracting("bareMethod") // supported with AssertJ 13.12.0
.extracting(Extractors.byName("fieldOrPropertyOrBareMethod")
.extracting(Extractors.byName("fieldOrPropertyOrBareMethod.orAPathLikeAbove")
.extracting(Extractors.resultOf("bareMethod")
.extractingResultOf("bareMethod")
.flatExtracting("fieldOrPropertyOrBareMethod.orAPathLikeAbove")
.flatExtracting(Extractors.byName("fieldOrPropertyOrBareMethod.orAPathLikeAbove")
.flatExtracting(Extractors.resultOf("bareMethod")
```
Works on both POJOs and ```Iterable```s/```Array```s.
Implementation is very basic though and does not work with fancy cascaded .extracting() sequences.
If there's demand, I will add it.
## Development notice
Cajon is written in Kotlin 1.3.
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 ;) ).
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).
## Planned features
- AssumeThatInsteadOfReturn
- Extraction with property names to lambda with Java 8
```
from: assertThat(object).extracting("propOne", "propNoGetter", "propTwo.innerProp")...
to: assertThat(object).extracting(type::getPropOne, it -> it.propNoGetter, it -> it.getPropTwo().getInnerProp())...
```
- Kotlin support (right now, however, with less than 100 downloads after a month, this is unlikely to happen)
## Changelog
#### V0.7 (28-Apr-19)
- Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions
(really, Jetbrains, this sucks for no reason).
- Extended AssertThatSize inspection to transform ```hasSize()``` into ```hasSameSizeAs()```, if possible.
- Implemented first version of JoinAssertThatStatements inspection that will try to merge ```assertThat()``` statements with the same
actual object together, preserving comments.
#### V0.6 (22-Apr-19)
- New AssertThatStringExpression inspection that will move ```isEmpty()```, ```equals()```, ```equalsIgnoreCase()```, ```contains()```,
```startsWith()```, and ```endsWith()``` out of actual expression.
- Extended AssertThatSize inspection to take ```String```s and ```CharSequences``` into account, too.
- New AssertThatInvertedBooleanCondition inspection that will remove inverted boolean expressions inside ```assertThat()```.
- Renamed a few inspections to better/shorter names.
- New AssertThatInstanceOf inspection that moves instanceof expressions out of ```assertThat()```.
#### V0.5 (18-Apr-19)
- Fixed incompatibility with IDEA versions < 2018.2 (affected AssertThatSizeInspection). Minimal version is now 2017.3.
- Fixed missing Guava imports (if not already present) for AssertThatGuavaInspection. This was a major PITA to get right.
- Added support for referencing and refactoring inside ```.extracting()``` methods with fields, properties and methods (though
getter renaming does not work that perfect, but I'm giving up for now as the IntelliJ SDK docs are seriously lacking).
- Fixed an exception in batch mode if the description string was the same but for different fixes.
Now descriptions are different for quick fixes triggered by AssertThatJava8OptionalInspection and AssertThatGuavaOptionalInspection.
#### V0.4 (11-Apr-19)
- Reduced minimal supported IDEA version from 2018.2 to 2017.2.
- New inspection AssertThatJava8Optional that operates on Java 8 ```Optional``` objects and tries to use ```contains()```, ```containsSame()```, ```isPresent()```, and ```isNotPresent()``` instead.
- New inspection AssertThatGuavaOptional that operates on Guava ```Optional``` objects and tries to use ```contains()```, ```isPresent()```, and ```isAbsent()``` instead.
- Added support in AssertThatBinaryExpressionIsTrueOrFalse for ```is(Not)EqualTo(Boolean.TRUE/FALSE)```.
#### V0.3 (07-Apr-19)
- New inspection AssertThatBinaryExpressionIsTrueOrFalse that will find and fix common binary expressions and ```equals()``` statements (more than 150 combinations) inside ```assertThat()```.
- Merged AssertThatObjectIsNull and AssertThatObjectIsNotNull to AssertThatObjectIsNullOrNotNull.
- Support for ```hasSizeLessThan()```, ```hasSizeLessThanOrEqualTo()```, ```hasSizeGreaterThanOrEqualTo()```, and ```hasSizeGreaterThan()``` for AssertThatSizeInspection (with AssertJ >=13.2.0).
- Really fixed highlighting for JUnit conversion. Sorry.
#### V0.2 (01-Apr-19)
- Fixed descriptions and quick fix texts.
- Fixed highlighting of found problems and also 'Run inspection by Name' returning nothing.
#### V0.1 (31-Mar-19)
- Initial release.
+22 -13
View File
@@ -1,11 +1,11 @@
plugins { plugins {
id 'java' id 'java'
id 'org.jetbrains.intellij' version '0.4.3' id 'org.jetbrains.intellij' version '0.4.8'
id 'org.jetbrains.kotlin.jvm' version '1.3.21' id 'org.jetbrains.kotlin.jvm' version '1.3.31'
} }
group 'de.platon42' group 'de.platon42'
version '0.2' version '0.7'
repositories { repositories {
mavenCentral() mavenCentral()
@@ -18,12 +18,12 @@ repositories {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testCompile "org.assertj:assertj-core:3.11.1" testCompile "org.assertj:assertj-core:3.12.2"
testCompile "org.assertj:assertj-guava:3.2.1"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.4.0'
testImplementation "org.jetbrains.kotlin:kotlin-test" testImplementation "org.jetbrains.kotlin:kotlin-test"
testImplementation "org.jetbrains.kotlin:kotlin-test-junit" // testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
} }
compileKotlin { compileKotlin {
@@ -33,23 +33,32 @@ compileTestKotlin {
kotlinOptions.jvmTarget = "1.8" kotlinOptions.jvmTarget = "1.8"
} }
intellij { intellij {
version '2018.3.4' version '2019.1.1'
// pluginName 'Concise AssertJ Optimizing Nitpicker (Cajon)' // pluginName 'Concise AssertJ Optimizing Nitpicker (Cajon)'
updateSinceUntilBuild false updateSinceUntilBuild false
} }
patchPluginXml { patchPluginXml {
changeNotes """ changeNotes """
<h4>V0.2 (01-Apr-19)</h4> <h4>V0.7 (28-Apr-19)</h4>
<ul> <ul>
<li>Fixed descriptions and quick fix texts. <li>Another fix for AssertThatGuavaOptional inspection regarding using the same family name for slightly different quick fix executions
<li>Fixed highlighting of found problems and also 'Run inspection by Name' returning nothing. (really, Jetbrains, this sucks for no reason).
<li>Extended AssertThatSize inspection to transform hasSize() into hasSameSizeAs(), if possible.
<li>Implemented first version of JoinAssertThatStatements inspection that will try to merge assertThat() statements with the same
actual object together, preserving comments.
</ul> </ul>
<h4>V0.1 (31-Mar-19)</h4> <h4>V0.6 (22-Apr-19)</h4>
<ul> <ul>
<li>Initial release. <li>New AssertThatStringExpression inspection that will move isEmpty(), equals(), equalsIgnoreCase(), contains(),
startsWith(), and endsWith() out of actual expression.
<li>Extended AssertThatSize inspection to take strings and CharSequences into account, too.
<li>New AssertThatInvertedBooleanCondition inspection that will remove inverted boolean expressions inside assertThat().
<li>Renamed a few inspections to better/shorter names.
<li>New AssertThatInstanceOf inspection that moves instanceof expressions out of assertThat().
</ul> </ul>
""" <p>Full changelog available at <a href="https://github.com/chrisly42/cajon-plugin#changelog">Github project site</a>.</p>
"""
} }
test { test {
@@ -0,0 +1,38 @@
package de.platon42.intellij.plugins.cajon
import org.jetbrains.annotations.NonNls
class AssertJClassNames {
companion object {
@NonNls
const val ASSERTIONS_CLASSNAME = "org.assertj.core.api.Assertions"
@NonNls
const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert"
@NonNls
const val ABSTRACT_OBJECT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractObjectAssert"
@NonNls
const val ABSTRACT_BOOLEAN_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractBooleanAssert"
@NonNls
const val ABSTRACT_INTEGER_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIntegerAssert"
@NonNls
const val ABSTRACT_COMPARABLE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractComparableAssert"
@NonNls
const val ABSTRACT_STRING_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractStringAssert"
@NonNls
const val ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractCharSequenceAssert"
@NonNls
const val ABSTRACT_ITERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIterableAssert"
@NonNls
const val ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.EnumerableAssert"
@NonNls
const val EXTRACTORS_CLASSNAME = "org.assertj.core.extractor.Extractors"
@NonNls
const val GUAVA_OPTIONAL_CLASSNAME = "com.google.common.base.Optional"
@NonNls
const val GUAVA_ASSERTIONS_CLASSNAME = "org.assertj.guava.api.Assertions"
@NonNls
const val GUAVA_OPTIONAL_ASSERT_CLASSNAME = "org.assertj.guava.api.OptionalAssert"
}
}
@@ -0,0 +1,23 @@
package de.platon42.intellij.plugins.cajon
import com.intellij.psi.CommonClassNames
import com.siyeh.ig.callMatcher.CallMatcher
val CORE_ASSERT_THAT_MATCHER = CallMatcher.staticCall(AssertJClassNames.ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)!!
val GUAVA_ASSERT_THAT_MATCHER = CallMatcher.staticCall(AssertJClassNames.GUAVA_ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)!!
val ALL_ASSERT_THAT_MATCHERS = CallMatcher.anyOf(CORE_ASSERT_THAT_MATCHER, GUAVA_ASSERT_THAT_MATCHER)!!
val EXTRACTING_FROM_OBJECT = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_OBJECT_ASSERT_CLASSNAME, "extracting")!!
val EXTRACTING_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "extracting")!!
val FLAT_EXTRACTING_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "flatExtracting")!!
val EXTRACTING_RESULT_OF_FROM_ITERABLE = CallMatcher.instanceCall(AssertJClassNames.ABSTRACT_ITERABLE_ASSERT_CLASSNAME, "extractingResultOf")!!
val EXTRACTING_CALL_MATCHERS = CallMatcher.anyOf(
EXTRACTING_FROM_OBJECT,
EXTRACTING_FROM_ITERABLE,
FLAT_EXTRACTING_FROM_ITERABLE,
EXTRACTING_RESULT_OF_FROM_ITERABLE
)!!
val KNOWN_METHODS_WITH_SIDE_EFFECTS = CallMatcher.anyOf(
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_ITERATOR, "next")
)!!
@@ -0,0 +1,59 @@
package de.platon42.intellij.plugins.cajon
import com.intellij.psi.*
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.util.PsiTreeUtil
import com.siyeh.ig.callMatcher.CallMatcher
val PsiMethodCallExpression.qualifierExpression: PsiExpression get() = this.methodExpression.qualifierExpression!!
val PsiMethodCallExpression.firstArg: PsiExpression get() = this.argumentList.expressions[0]!!
fun PsiMethodCallExpression.replaceQualifier(qualifier: PsiElement) {
this.qualifierExpression.replace(qualifier)
}
fun PsiMethodCallExpression.replaceQualifierFromMethodCall(oldMethodCall: PsiMethodCallExpression) {
this.qualifierExpression.replace(oldMethodCall.qualifierExpression)
}
fun PsiElement.findOutmostMethodCall(): PsiMethodCallExpression? {
val statement = PsiTreeUtil.getParentOfType(this, PsiStatement::class.java) ?: return null
return PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java)
}
fun PsiMethodCallExpression.findFluentCallTo(matcher: CallMatcher): PsiMethodCallExpression? {
var currentMethodCall: PsiMethodCallExpression? = this
while (currentMethodCall != null) {
if (matcher.test(currentMethodCall)) {
return currentMethodCall
}
currentMethodCall = PsiTreeUtil.getParentOfType(currentMethodCall, PsiMethodCallExpression::class.java, true, PsiStatement::class.java)
}
return null
}
fun PsiMethodCallExpression.getArg(n: Int): PsiExpression = this.argumentList.expressions[n]
fun <T> Boolean.map(forTrue: T, forFalse: T) = if (this) forTrue else forFalse
fun PsiMethod.addAsStaticImport(context: PsiElement, vararg allowedClashes: String) {
val factory = JavaPsiFacade.getElementFactory(context.project)
val methodName = this.name
val containingClass = this.containingClass ?: return
val importList = (context.containingFile as PsiJavaFile).importList ?: return
val notImportedStatically = importList.importStaticStatements.none {
val targetClass = it.resolveTargetClass() ?: return@none false
((it.referenceName == methodName) && !allowedClashes.contains(targetClass.qualifiedName))
|| (it.isOnDemand && (targetClass == this.containingClass))
}
if (notImportedStatically) {
importList.add(factory.createImportStaticStatement(containingClass, methodName))
}
}
fun PsiElement.shortenAndReformat() {
val codeStyleManager = JavaCodeStyleManager.getInstance(project)
codeStyleManager.shortenClassReferences(this)
CodeStyleManager.getInstance(project).reformat(this)
}
@@ -0,0 +1,32 @@
package de.platon42.intellij.plugins.cajon
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethodCallExpression
fun createAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
return createAssertThat(context, AssertJClassNames.ASSERTIONS_CLASSNAME, actualExpression)
}
fun createGuavaAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
return createAssertThat(context, AssertJClassNames.GUAVA_ASSERTIONS_CLASSNAME, actualExpression)
}
fun createAssertThat(context: PsiElement, baseclass: String, actualExpression: PsiExpression): PsiMethodCallExpression {
return createMethodCall(context, "$baseclass.${MethodNames.ASSERT_THAT}", actualExpression)
}
fun createExpectedMethodCall(context: PsiElement, methodName: String, vararg arguments: PsiElement): PsiMethodCallExpression {
return createMethodCall(context, "a.$methodName", *arguments)
}
fun createMethodCall(context: PsiElement, fullQualifiedMethodName: String, vararg arguments: PsiElement): PsiMethodCallExpression {
val factory = JavaPsiFacade.getElementFactory(context.project)
val argString = generateSequence('b') { it + 1 }.take(arguments.size).joinToString(", ")
val expectedExpression = factory.createExpressionFromText(
"$fullQualifiedMethodName($argString)", context
) as PsiMethodCallExpression
arguments.forEachIndexed { index, newArg -> expectedExpression.getArg(index).replace(newArg) }
return expectedExpression
}
@@ -0,0 +1,97 @@
package de.platon42.intellij.plugins.cajon
import org.jetbrains.annotations.NonNls
class MethodNames {
companion object {
@NonNls
const val EQUALS = "equals"
@NonNls
const val ASSERT_THAT = "assertThat"
@NonNls
const val AS = "as"
@NonNls
const val IS_EQUAL_TO = "isEqualTo"
@NonNls
const val IS_NOT_EQUAL_TO = "isNotEqualTo"
@NonNls
const val IS_SAME_AS = "isSameAs"
@NonNls
const val IS_NOT_SAME_AS = "isNotSameAs"
@NonNls
const val IS_GREATER_THAN = "isGreaterThan"
@NonNls
const val IS_GREATER_THAN_OR_EQUAL_TO = "isGreaterThanOrEqualTo"
@NonNls
const val IS_LESS_THAN = "isLessThan"
@NonNls
const val IS_LESS_THAN_OR_EQUAL_TO = "isLessThanOrEqualTo"
@NonNls
const val IS_ZERO = "isZero"
@NonNls
const val IS_NOT_ZERO = "isNotZero"
@NonNls
const val IS_TRUE = "isTrue"
@NonNls
const val IS_FALSE = "isFalse"
@NonNls
const val IS_NULL = "isNull"
@NonNls
const val IS_NOT_NULL = "isNotNull"
@NonNls
const val IS_CLOSE_TO = "isCloseTo"
@NonNls
const val IS_NOT_CLOSE_TO = "isNotCloseTo"
@NonNls
const val IS_INSTANCE_OF = "isInstanceOf"
@NonNls
const val IS_NOT_INSTANCE_OF = "isNotInstanceOf"
@NonNls
const val IS_EMPTY = "isEmpty"
@NonNls
const val IS_NOT_EMPTY = "isNotEmpty"
@NonNls
const val HAS_SIZE = "hasSize"
@NonNls
const val HAS_SIZE_LESS_THAN = "hasSizeLessThan"
@NonNls
const val HAS_SIZE_LESS_THAN_OR_EQUAL_TO = "hasSizeLessThanOrEqualTo"
@NonNls
const val HAS_SIZE_GREATER_THAN = "hasSizeGreaterThan"
@NonNls
const val HAS_SIZE_GREATER_THAN_OR_EQUAL_TO = "hasSizeGreaterThanOrEqualTo"
@NonNls
const val HAS_SAME_SIZE_AS = "hasSameSizeAs"
@NonNls
const val CONTAINS = "contains"
@NonNls
const val DOES_NOT_CONTAIN = "doesNotContain"
@NonNls
const val CONTAINS_EXACTLY = "containsExactly"
@NonNls
const val IS_EQUAL_TO_IC = "isEqualToIgnoringCase"
@NonNls
const val IS_NOT_EQUAL_TO_IC = "isNotEqualToIgnoringCase"
@NonNls
const val STARTS_WITH = "startsWith"
@NonNls
const val ENDS_WITH = "endsWith"
@NonNls
const val DOES_NOT_START_WITH = "doesNotStartWith"
@NonNls
const val DOES_NOT_END_WITH = "doesNotEndWith"
@NonNls
const val CONTAINS_SAME = "containsSame"
@NonNls
const val IS_PRESENT = "isPresent"
@NonNls
const val IS_NOT_PRESENT = "isNotPresent"
@NonNls
const val IS_ABSENT = "isAbsent"
}
}
@@ -1,97 +1,151 @@
package de.platon42.intellij.plugins.cajon.inspections package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.CommonClassNames import com.intellij.psi.*
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiCapturedWildcardType
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.tree.IElementType
import com.intellij.psi.util.PsiTypesUtil import com.intellij.psi.util.PsiTypesUtil
import com.siyeh.ig.callMatcher.CallMatcher import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_BOOLEAN_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_COMPARABLE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_INTEGER_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ASSERTIONS_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_OPTIONAL_CLASSNAME
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.getArg
import de.platon42.intellij.plugins.cajon.qualifierExpression
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSimpleMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSimpleMethodCallQuickFix
import org.jetbrains.annotations.NonNls
open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
companion object { companion object {
const val SIMPLIFY_MESSAGE_TEMPLATE = "%s can be simplified to %s" const val SIMPLIFY_MESSAGE_TEMPLATE = "%s() can be simplified to %s()"
const val MORE_CONCISE_MESSAGE_TEMPLATE = "%s() would be more concise than %s()"
const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s with %s" const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with %s()"
const val REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE = "Remove unwrapping of expected expression and replace %s() with %s()"
const val UNWRAP_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with %s()"
@NonNls val TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP = mapOf<IElementType, String>(
const val ASSERTIONS_CLASSNAME = "org.assertj.core.api.Assertions" JavaTokenType.EQEQ to MethodNames.IS_EQUAL_TO,
JavaTokenType.NE to MethodNames.IS_NOT_EQUAL_TO,
JavaTokenType.GT to MethodNames.IS_GREATER_THAN,
JavaTokenType.GE to MethodNames.IS_GREATER_THAN_OR_EQUAL_TO,
JavaTokenType.LT to MethodNames.IS_LESS_THAN,
JavaTokenType.LE to MethodNames.IS_LESS_THAN_OR_EQUAL_TO
)
@NonNls val TOKEN_TO_ASSERTJ_FOR_OBJECT_MAPPINGS = mapOf<IElementType, String>(
const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert" JavaTokenType.EQEQ to MethodNames.IS_SAME_AS,
@NonNls JavaTokenType.NE to MethodNames.IS_NOT_SAME_AS
const val ABSTRACT_BOOLEAN_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractBooleanAssert" )
@NonNls
const val ABSTRACT_INTEGER_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIntegerAssert"
@NonNls
const val ABSTRACT_COMPARABLE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractComparableAssert"
@NonNls
const val ABSTRACT_STRING_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractStringAssert"
@NonNls
const val ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractCharSequenceAssert"
@NonNls
const val ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.EnumerableAssert"
@NonNls val SWAP_SIDE_OF_BINARY_OPERATOR = mapOf<IElementType, IElementType>(
const val ASSERT_THAT_METHOD = "assertThat" JavaTokenType.GT to JavaTokenType.LT,
@NonNls JavaTokenType.GE to JavaTokenType.LE,
const val IS_EQUAL_TO_METHOD = "isEqualTo" JavaTokenType.LT to JavaTokenType.GT,
@NonNls JavaTokenType.LE to JavaTokenType.GE
const val IS_NOT_EQUAL_TO_METHOD = "isNotEqualTo" )
@NonNls
const val IS_GREATER_THAN_METHOD = "isGreaterThan"
@NonNls
const val IS_GREATER_THAN_OR_EQUAL_TO_METHOD = "isGreaterThanOrEqualTo"
@NonNls
const val IS_LESS_THAN_METHOD = "isLessThan"
@NonNls
const val IS_LESS_THAN_OR_EQUAL_TO_METHOD = "isLessThanOrEqualTo"
@NonNls
const val IS_ZERO_METHOD = "isZero"
@NonNls
const val IS_NOT_ZERO_METHOD = "isNotZero"
@NonNls
const val HAS_SIZE_METHOD = "hasSize"
val ASSERT_THAT_INT = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, ASSERT_THAT_METHOD) val INVERT_BINARY_OPERATOR = mapOf<IElementType, IElementType>(
JavaTokenType.EQEQ to JavaTokenType.NE,
JavaTokenType.NE to JavaTokenType.EQEQ,
JavaTokenType.GT to JavaTokenType.LE,
JavaTokenType.GE to JavaTokenType.LT,
JavaTokenType.LT to JavaTokenType.GE,
JavaTokenType.LE to JavaTokenType.GT
)
val ASSERT_THAT_INT = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
.parameterTypes("int")!! .parameterTypes("int")!!
val IS_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_EQUAL_TO_METHOD) val ASSERT_THAT_BOOLEAN = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
.parameterTypes("boolean")!!
val ASSERT_THAT_ANY = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
.parameterCount(1)!!
val ASSERT_THAT_JAVA8_OPTIONAL = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
.parameterTypes(CommonClassNames.JAVA_UTIL_OPTIONAL)!!
val ASSERT_THAT_GUAVA_OPTIONAL = CallMatcher.staticCall(GUAVA_ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
.parameterTypes(GUAVA_OPTIONAL_CLASSNAME)!!
val IS_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!! .parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val IS_NOT_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_NOT_EQUAL_TO_METHOD) val IS_NOT_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_NOT_EQUAL_TO)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!! .parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val IS_EQUAL_TO_BOOLEAN = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, IS_EQUAL_TO_METHOD) val IS_EQUAL_TO_BOOLEAN = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO)
.parameterTypes("boolean")!! .parameterTypes("boolean")!!
val IS_NOT_EQUAL_TO_BOOLEAN = val IS_NOT_EQUAL_TO_BOOLEAN =
CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, IS_NOT_EQUAL_TO_METHOD) CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_NOT_EQUAL_TO)
.parameterTypes("boolean")!! .parameterTypes("boolean")!!
val HAS_SIZE = CallMatcher.instanceCall(ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME, HAS_SIZE_METHOD) val IS_SAME_AS_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_SAME_AS)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val IS_NOT_SAME_AS_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_NOT_SAME_AS)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val HAS_SIZE = CallMatcher.instanceCall(ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME, MethodNames.HAS_SIZE)
.parameterTypes("int")!! .parameterTypes("int")!!
val IS_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_EQUAL_TO_METHOD) val IS_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO)
.parameterTypes("int")!! .parameterTypes("int")!!
val IS_GREATER_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, IS_GREATER_THAN_METHOD) val IS_GREATER_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_GREATER_THAN)
.parameterTypes("int")!! .parameterTypes("int")!!
val IS_GREATER_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, IS_GREATER_THAN_OR_EQUAL_TO_METHOD) val IS_GREATER_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_GREATER_THAN_OR_EQUAL_TO)
.parameterTypes("int")!! .parameterTypes("int")!!
val IS_LESS_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, IS_LESS_THAN_METHOD) val IS_LESS_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_LESS_THAN)
.parameterTypes("int")!! .parameterTypes("int")!!
val IS_LESS_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, IS_LESS_THAN_OR_EQUAL_TO_METHOD) val IS_LESS_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_LESS_THAN_OR_EQUAL_TO)
.parameterTypes("int")!! .parameterTypes("int")!!
val IS_ZERO = CallMatcher.instanceCall(ABSTRACT_INTEGER_ASSERT_CLASSNAME, IS_ZERO_METHOD) val IS_ZERO = CallMatcher.instanceCall(ABSTRACT_INTEGER_ASSERT_CLASSNAME, MethodNames.IS_ZERO)
.parameterCount(0)!! .parameterCount(0)!!
val IS_NOT_ZERO = CallMatcher.instanceCall(ABSTRACT_INTEGER_ASSERT_CLASSNAME, IS_NOT_ZERO_METHOD) val IS_NOT_ZERO = CallMatcher.instanceCall(ABSTRACT_INTEGER_ASSERT_CLASSNAME, MethodNames.IS_NOT_ZERO)
.parameterCount(0)!!
val IS_TRUE = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_TRUE)
.parameterCount(0)!!
val IS_FALSE = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_FALSE)
.parameterCount(0)!! .parameterCount(0)!!
val COLLECTION_SIZE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "size") val COLLECTION_SIZE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "size")
.parameterCount(0)!! .parameterCount(0)!!
val CHAR_SEQUENCE_LENGTH = CallMatcher.instanceCall("java.lang.CharSequence", "length")
.parameterCount(0)!!
val OBJECT_EQUALS = CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_OBJECT, "equals")
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val OPTIONAL_GET = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "get")
.parameterCount(0)!!
val OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "isPresent")
.parameterCount(0)!!
val OPTIONAL_OF = CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "of")
.parameterCount(1)!!
val OPTIONAL_OF_NULLABLE = CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "ofNullable")
.parameterCount(1)!!
val OPTIONAL_EMPTY = CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "empty")
.parameterCount(0)!!
val GUAVA_OPTIONAL_GET = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "get")
.parameterCount(0)!!
val GUAVA_OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "isPresent")
.parameterCount(0)!!
val GUAVA_OPTIONAL_OF = CallMatcher.staticCall(GUAVA_OPTIONAL_CLASSNAME, "of")
.parameterCount(1)!!
val GUAVA_OPTIONAL_FROM_NULLABLE = CallMatcher.staticCall(GUAVA_OPTIONAL_CLASSNAME, "fromNullable")
.parameterCount(1)!!
val GUAVA_OPTIONAL_ABSENT = CallMatcher.staticCall(GUAVA_OPTIONAL_CLASSNAME, "absent")
.parameterCount(0)!!
} }
override fun getGroupDisplayName(): String { override fun getGroupDisplayName(): String {
@@ -99,8 +153,8 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
} }
protected fun checkAssertedType(expression: PsiMethodCallExpression, classname: String): Boolean { protected fun checkAssertedType(expression: PsiMethodCallExpression, classname: String): Boolean {
var assertedType = expression.methodExpression.qualifierExpression?.type ?: return false var assertedType = expression.qualifierExpression.type ?: return false
if (assertedType is PsiCapturedWildcardType) { while (assertedType is PsiCapturedWildcardType) {
assertedType = assertedType.upperBound assertedType = assertedType.upperBound
} }
val assertedClass = PsiTypesUtil.getPsiClass(assertedType) ?: return false val assertedClass = PsiTypesUtil.getPsiClass(assertedType) ?: return false
@@ -109,8 +163,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
return assertedClass.isEquivalentTo(expectedClass) || assertedClass.isInheritor(expectedClass, true) return assertedClass.isEquivalentTo(expectedClass) || assertedClass.isInheritor(expectedClass, true)
} }
protected fun getOriginalMethodName(expression: PsiMethodCallExpression) = protected fun getOriginalMethodName(expression: PsiMethodCallExpression) = expression.resolveMethod()?.name
expression.resolveMethod()?.name?.plus("()")
protected fun registerSimplifyMethod( protected fun registerSimplifyMethod(
holder: ProblemsHolder, holder: ProblemsHolder,
@@ -120,17 +173,93 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
val originalMethod = getOriginalMethodName(expression) ?: return val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod) val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = SIMPLIFY_MESSAGE_TEMPLATE.format(originalMethod, replacementMethod) val message = SIMPLIFY_MESSAGE_TEMPLATE.format(originalMethod, replacementMethod)
holder.registerProblem( val quickFix = ReplaceSimpleMethodCallQuickFix(description, replacementMethod)
expression, holder.registerProblem(expression, message, quickFix)
message, }
ReplaceSimpleMethodCallQuickFix(description, replacementMethod)
) protected fun registerReplaceMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
registerConciseMethod(REPLACE_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier)
}
protected fun registerConciseMethod(
descriptionTemplate: String,
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
val originalMethod = getOriginalMethodName(oldExpectedCallExpression) ?: return
val description = descriptionTemplate.format(originalMethod, replacementMethod)
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickfix)
}
protected fun registerRemoveExpectedOutmostMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
registerConciseMethod(REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier)
}
protected fun registerRemoveActualOutmostMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
registerConciseMethod(UNWRAP_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier)
} }
protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? { protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? {
if (argIndex >= expression.argumentList.expressionCount) return null if (argIndex >= expression.argumentList.expressions.size) return null
val valueExpression = expression.argumentList.expressions[argIndex] ?: return null val valueExpression = expression.getArg(argIndex)
val constantEvaluationHelper = JavaPsiFacade.getInstance(expression.project).constantEvaluationHelper val constantEvaluationHelper = JavaPsiFacade.getInstance(expression.project).constantEvaluationHelper
return constantEvaluationHelper.computeConstantExpression(valueExpression) val value = constantEvaluationHelper.computeConstantExpression(valueExpression)
if (value == null) {
val field = (valueExpression as? PsiReferenceExpression)?.resolve() as? PsiField
if (field?.containingClass?.qualifiedName == CommonClassNames.JAVA_LANG_BOOLEAN) {
return when (field.name) {
"TRUE" -> true
"FALSE" -> false
else -> null
}
}
}
return value
}
protected fun getExpectedBooleanResult(expectedCallExpression: PsiMethodCallExpression): Boolean? {
val isTrue = IS_TRUE.test(expectedCallExpression)
val isFalse = IS_FALSE.test(expectedCallExpression)
if (isTrue || isFalse) {
return isTrue
} else {
val isEqualTo = IS_EQUAL_TO_BOOLEAN.test(expectedCallExpression) || IS_EQUAL_TO_OBJECT.test(expectedCallExpression)
val isNotEqualTo = IS_NOT_EQUAL_TO_BOOLEAN.test(expectedCallExpression) || IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)
if (isEqualTo || isNotEqualTo) {
val constValue = calculateConstantParameterValue(expectedCallExpression, 0) as? Boolean ?: return null
return isNotEqualTo xor constValue
}
}
return null
}
protected fun hasAssertJMethod(element: PsiElement, classname: String, methodname: String): Boolean {
val findClass =
JavaPsiFacade.getInstance(element.project).findClass(classname, GlobalSearchScope.allScope(element.project))
?: return false
return findClass.allMethods.any { it.name == methodname }
} }
} }
@@ -9,7 +9,7 @@ open class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTool()
companion object { companion object {
const val CONVERT_MESSAGE_TEMPLATE = "%s can be converted to AssertJ style" const val CONVERT_MESSAGE_TEMPLATE = "%s can be converted to AssertJ style"
const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s with assertThat().%s" const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with assertThat().%s()"
@NonNls @NonNls
const val JUNIT_ASSERT_CLASSNAME = "org.junit.Assert" const val JUNIT_ASSERT_CLASSNAME = "org.junit.Assert"
@@ -38,6 +38,5 @@ open class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTool()
return "AssertJ" return "AssertJ"
} }
protected fun getOriginalMethodName(expression: PsiMethodCallExpression) = protected fun getOriginalMethodName(expression: PsiMethodCallExpression) = expression.resolveMethod()?.name
expression.resolveMethod()?.name?.plus("()")
} }
@@ -0,0 +1,94 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.intellij.psi.util.TypeConversionUtil
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.MoveActualOuterExpressionMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.SplitBinaryExpressionMethodCallQuickFix
class AssertThatBinaryExpressionInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting a binary expression"
private const val SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE = "Split %s expression out of assertThat()"
private const val MORE_MEANINGFUL_MESSAGE_TEMPLATE = "Moving %s expression out of assertThat() would be more meaningful"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
if (!ASSERT_THAT_BOOLEAN.test(expression)) {
return
}
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedResult = getExpectedBooleanResult(expectedCallExpression) ?: return
val assertThatArgument = expression.firstArg
if (assertThatArgument is PsiMethodCallExpression && OBJECT_EQUALS.test(assertThatArgument)) {
val replacementMethod = expectedResult.map(MethodNames.IS_EQUAL_TO, MethodNames.IS_NOT_EQUAL_TO)
registerSplitMethod(holder, expression, "${MethodNames.EQUALS}()", replacementMethod, ::MoveActualOuterExpressionMethodCallQuickFix)
return
}
val binaryExpression = assertThatArgument as? PsiBinaryExpression ?: return
val leftType = binaryExpression.lOperand.type ?: return
val rightType = binaryExpression.rOperand?.type ?: return
val bothTypes = listOf(leftType, rightType)
val (isLeftNull, isRightNull) = bothTypes.map(TypeConversionUtil::isNullType)
if (isLeftNull && isRightNull) {
return
} else if (isLeftNull || isRightNull) {
val replacementMethod = expectedResult.map(MethodNames.IS_NULL, MethodNames.IS_NOT_NULL)
registerSplitMethod(holder, expression, "binary", replacementMethod) { desc, method ->
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = isLeftNull, noExpectedExpression = true)
}
return
}
val isPrimitive = bothTypes.all(TypeConversionUtil::isPrimitiveAndNotNull)
val isNumericType = bothTypes.all(TypeConversionUtil::isNumericType)
val constantEvaluationHelper = JavaPsiFacade.getInstance(expression.project).constantEvaluationHelper
val swapExpectedAndActual = constantEvaluationHelper.computeConstantExpression(binaryExpression.lOperand) != null
val tokenType = binaryExpression.operationTokenType
.let {
if (swapExpectedAndActual) SWAP_SIDE_OF_BINARY_OPERATOR.getOrDefault(it, it) else it
}
.let {
if (expectedResult) it else INVERT_BINARY_OPERATOR.getOrDefault(it, it)
}
val mappingToUse =
(isPrimitive || isNumericType).map(TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP, TOKEN_TO_ASSERTJ_FOR_OBJECT_MAPPINGS)
val replacementMethod = mappingToUse[tokenType] ?: return
registerSplitMethod(holder, expression, "binary", replacementMethod) { desc, method ->
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = swapExpectedAndActual)
}
}
}
}
private fun registerSplitMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
type: String,
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
val description = SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE.format(type)
val message = MORE_MEANINGFUL_MESSAGE_TEMPLATE.format(type)
val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickfix)
}
}
@@ -0,0 +1,48 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.util.TypeConversionUtil
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_BOOLEAN_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
class AssertThatBooleanConditionInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting a boolean condition"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
val matchingCalls = listOf(
IS_EQUAL_TO_OBJECT, IS_EQUAL_TO_BOOLEAN,
IS_NOT_EQUAL_TO_OBJECT, IS_NOT_EQUAL_TO_BOOLEAN
).map { it.test(expression) }
if (matchingCalls.none { it }) {
return
}
if (!checkAssertedType(expression, ABSTRACT_BOOLEAN_ASSERT_CLASSNAME)) {
return
}
val expectedExpression = expression.firstArg
if (!TypeConversionUtil.isBooleanType(expectedExpression.type)) {
return
}
val expectedResult = calculateConstantParameterValue(expression, 0) as? Boolean ?: return
val flippedBooleanTest = matchingCalls.drop(2).any { it }
val replacementMethod = (expectedResult xor flippedBooleanTest).map(MethodNames.IS_TRUE, MethodNames.IS_FALSE)
registerSimplifyMethod(holder, expression, replacementMethod)
}
}
}
}
@@ -1,53 +0,0 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.intellij.psi.util.TypeConversionUtil
class AssertThatBooleanIsTrueOrFalseInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting true or false"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
val isEqualToObject = IS_EQUAL_TO_OBJECT.test(expression)
val isEqualToBoolean = IS_EQUAL_TO_BOOLEAN.test(expression)
val isNotEqualToObject = IS_NOT_EQUAL_TO_OBJECT.test(expression)
val isNotEqualToBoolean = IS_NOT_EQUAL_TO_BOOLEAN.test(expression)
val normalBooleanTest = isEqualToObject || isEqualToBoolean
val flippedBooleanTest = isNotEqualToObject || isNotEqualToBoolean
if (!(normalBooleanTest || flippedBooleanTest)) {
return
}
if (!checkAssertedType(expression, ABSTRACT_BOOLEAN_ASSERT_CLASSNAME)) {
return
}
val equalToExpression = expression.argumentList.expressions[0] ?: return
if (!TypeConversionUtil.isBooleanType(equalToExpression.type)) {
return
}
var value = calculateConstantParameterValue(expression, 0)
if (value == null) {
val field = (equalToExpression as? PsiReferenceExpression)?.resolve() as? PsiField
if (field?.containingClass?.qualifiedName == CommonClassNames.JAVA_LANG_BOOLEAN) {
when {
field.name == "TRUE" -> value = true
field.name == "FALSE" -> value = false
}
}
}
val expectedResult = value as? Boolean ?: return
val replacementMethod = if (expectedResult xor flippedBooleanTest) "isTrue()" else "isFalse()"
registerSimplifyMethod(holder, expression, replacementMethod)
}
}
}
}
@@ -4,6 +4,7 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor 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 de.platon42.intellij.plugins.cajon.MethodNames
class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() { class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() {
@@ -17,14 +18,13 @@ class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() {
return object : JavaElementVisitor() { return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
val hasSize = HAS_SIZE.test(expression) if (!HAS_SIZE.test(expression)) {
if (!hasSize) {
return return
} }
val value = calculateConstantParameterValue(expression, 0) ?: return val value = calculateConstantParameterValue(expression, 0) ?: return
if (value == 0) { if (value == 0) {
registerSimplifyMethod(holder, expression, "isEmpty()") registerSimplifyMethod(holder, expression, MethodNames.IS_EMPTY)
} }
} }
} }
@@ -0,0 +1,122 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.search.GlobalSearchScope
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.quickfixes.*
class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting an Optional (Guava)"
private const val REPLACE_GUAVA_DESCRIPTION_TEMPLATE = "Replace %s() with Guava assertThat().%s()"
private const val REMOVE_EXPECTED_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE = "Remove unwrapping of expected expression and replace %s() with Guava assertThat().%s()"
private const val REMOVE_ACTUAL_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with Guava assertThat().%s()"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
JavaPsiFacade.getInstance(expression.project)
.findClass(AssertJClassNames.GUAVA_ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
val assertThatGuava = ASSERT_THAT_GUAVA_OPTIONAL.test(expression)
if (!(ASSERT_THAT_ANY.test(expression) || assertThatGuava)) {
return
}
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val isEqualTo = IS_EQUAL_TO_OBJECT.test(expectedCallExpression)
val isNotEqualTo = IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)
if (assertThatGuava) {
if (isEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix)
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
}
} else if (isNotEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT)
}
}
} else {
// we're not calling an assertThat() from Guava, but a core-AssertJ one!
// We need to replace that by the Guava one, if we want to apply a formally correct fix.
val actualExpression = expression.firstArg as? PsiMethodCallExpression
if (actualExpression != null) {
if (GUAVA_OPTIONAL_GET.test(actualExpression) && isEqualTo) {
registerRemoveActualOutmostForGuavaMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
} else if (GUAVA_OPTIONAL_IS_PRESENT.test(actualExpression)) {
val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_ABSENT)
registerRemoveActualOutmostForGuavaMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true)
}
}
if (isEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
registerRemoveExpectedOutmostGuavaMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyForGuavaMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
}
} else if (isNotEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyForGuavaMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT)
}
}
}
}
}
}
private fun registerRemoveExpectedOutmostGuavaMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String
) {
registerConciseMethod(REMOVE_EXPECTED_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method ->
QuickFixWithPostfixDelegate(
UnwrapExpectedStaticMethodCallQuickFix(desc, method),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
}
}
private fun registerRemoveActualOutmostForGuavaMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
noExpectedExpression: Boolean = false
) {
registerConciseMethod(REMOVE_ACTUAL_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method ->
QuickFixWithPostfixDelegate(
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
}
}
private fun registerSimplifyForGuavaMethod(holder: ProblemsHolder, expression: PsiMethodCallExpression, replacementMethod: String) {
val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_GUAVA_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = SIMPLIFY_MESSAGE_TEMPLATE.format(originalMethod, replacementMethod)
val quickFix = QuickFixWithPostfixDelegate(
ReplaceSimpleMethodCallQuickFix(description, replacementMethod),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
holder.registerProblem(expression, message, quickFix)
}
}
@@ -0,0 +1,54 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiInstanceOfExpression
import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveInstanceOfExpressionQuickFix
class AssertThatInstanceOfInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting a class instance"
private const val REPLACE_INSTANCEOF_DESCRIPTION_TEMPLATE = "Replace instanceof expression by assertThat().%s()"
private const val MOVE_OUT_INSTANCEOF_MESSAGE = "instanceof expression could be moved out of assertThat()"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
if (!ASSERT_THAT_BOOLEAN.test(expression)) {
return
}
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedResult = getExpectedBooleanResult(expectedCallExpression) ?: return
if (expression.firstArg is PsiInstanceOfExpression) {
val replacementMethod = expectedResult.map(MethodNames.IS_INSTANCE_OF, MethodNames.IS_NOT_INSTANCE_OF)
registerRemoveInstanceOfMethod(holder, expression, replacementMethod, ::RemoveInstanceOfExpressionQuickFix)
}
}
}
}
private fun registerRemoveInstanceOfMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
val description = REPLACE_INSTANCEOF_DESCRIPTION_TEMPLATE.format(replacementMethod)
val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, MOVE_OUT_INSTANCEOF_MESSAGE, quickfix)
}
}
@@ -0,0 +1,51 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveUnaryExpressionQuickFix
class AssertThatInvertedBooleanConditionInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting an inverted boolean condition"
private const val INVERT_CONDITION_DESCRIPTION = "Invert condition in assertThat()"
private const val INVERT_CONDITION_MESSAGE = "Condition inside assertThat() could be inverted"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
if (!ASSERT_THAT_BOOLEAN.test(expression)) {
return
}
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedResult = getExpectedBooleanResult(expectedCallExpression) ?: return
val prefixExpression = expression.firstArg as? PsiPrefixExpression ?: return
if (prefixExpression.operationTokenType == JavaTokenType.EXCL) {
val replacementMethod = expectedResult.map(MethodNames.IS_FALSE, MethodNames.IS_TRUE)
registerInvertMethod(holder, expression, replacementMethod, ::RemoveUnaryExpressionQuickFix)
}
}
}
}
private fun registerInvertMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
val quickfix = quickFixSupplier(INVERT_CONDITION_DESCRIPTION, replacementMethod)
holder.registerProblem(expression, INVERT_CONDITION_MESSAGE, quickfix)
}
}
@@ -0,0 +1,70 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveActualOutmostMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.UnwrapExpectedStaticMethodCallQuickFix
class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting an Optional (Java 8)"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
if (!ASSERT_THAT_ANY.test(expression)) {
return
}
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
if (ASSERT_THAT_JAVA8_OPTIONAL.test(expression)) {
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (CallMatcher.anyOf(OPTIONAL_OF, OPTIONAL_OF_NULLABLE).test(innerExpectedCall)) {
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix)
} else if (OPTIONAL_EMPTY.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_NOT_PRESENT)
}
} else if (IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (OPTIONAL_EMPTY.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT)
}
}
} else {
val actualExpression = expression.firstArg as? PsiMethodCallExpression ?: return
if (OPTIONAL_GET.test(actualExpression)) {
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method)
}
} else if (IS_SAME_AS_OBJECT.test(expectedCallExpression)) {
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS_SAME) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method)
}
}
} else if (OPTIONAL_IS_PRESENT.test(actualExpression)) {
val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_NOT_PRESENT)
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, replacementMethod) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
}
}
}
}
}
}
@@ -1,31 +0,0 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiType
class AssertThatObjectIsNullInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting null"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
if (!IS_EQUAL_TO_OBJECT.test(expression)) {
return
}
if (expression.argumentList.expressions[0].type == PsiType.NULL) {
registerSimplifyMethod(holder, expression, "isNull()")
}
}
}
}
}
@@ -5,11 +5,14 @@ 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.PsiType import com.intellij.psi.PsiType
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
class AssertThatObjectIsNotNullInspection : AbstractAssertJInspection() { class AssertThatObjectIsNullOrNotNullInspection : AbstractAssertJInspection() {
companion object { companion object {
private const val DISPLAY_NAME = "Asserting non-null" private const val DISPLAY_NAME = "Asserting null or not-null"
} }
override fun getDisplayName() = DISPLAY_NAME override fun getDisplayName() = DISPLAY_NAME
@@ -18,12 +21,14 @@ class AssertThatObjectIsNotNullInspection : AbstractAssertJInspection() {
return object : JavaElementVisitor() { return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
if (!IS_NOT_EQUAL_TO_OBJECT.test(expression)) { val isNotEqualTo = IS_NOT_EQUAL_TO_OBJECT.test(expression)
val isEqualTo = IS_EQUAL_TO_OBJECT.test(expression)
if (!(isEqualTo || isNotEqualTo)) {
return return
} }
if (expression.argumentList.expressions[0].type == PsiType.NULL) { if (expression.firstArg.type == PsiType.NULL) {
registerSimplifyMethod(holder, expression, "isNotNull()") registerSimplifyMethod(holder, expression, isEqualTo.map(MethodNames.IS_NULL, MethodNames.IS_NOT_NULL))
} }
} }
} }
@@ -3,13 +3,23 @@ package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ITERABLE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix
class AssertThatSizeInspection : AbstractAssertJInspection() { class AssertThatSizeInspection : AbstractAssertJInspection() {
companion object { companion object {
private const val DISPLAY_NAME = "Asserting the size of an collection or array" private const val DISPLAY_NAME = "Asserting the size of an collection, array or string"
private const val MORE_CONCISE_MESSAGE_TEMPLATE = "%s would be more concise than %s" private const val REMOVE_SIZE_DESCRIPTION_TEMPLATE = "Remove size determination of expected expression and replace %s() with %s()"
private val BONUS_EXPRESSIONS_CALL_MATCHER_MAP = listOf(
IS_LESS_THAN_INT to MethodNames.HAS_SIZE_LESS_THAN,
IS_LESS_THAN_OR_EQUAL_TO_INT to MethodNames.HAS_SIZE_LESS_THAN_OR_EQUAL_TO,
IS_GREATER_THAN_INT to MethodNames.HAS_SIZE_GREATER_THAN,
IS_GREATER_THAN_OR_EQUAL_TO_INT to MethodNames.HAS_SIZE_GREATER_THAN_OR_EQUAL_TO
)
} }
override fun getDisplayName() = DISPLAY_NAME override fun getDisplayName() = DISPLAY_NAME
@@ -18,44 +28,74 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
return object : JavaElementVisitor() { return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
if (!ASSERT_THAT_INT.test(expression)) { val isAssertThatWithInt = ASSERT_THAT_INT.test(expression)
val isHasSize = HAS_SIZE.test(expression)
if (!(isAssertThatWithInt || isHasSize)) {
return return
} }
val actualExpression = expression.argumentList.expressions[0] ?: return val actualExpression = expression.firstArg
if (isArrayLength(actualExpression) || isCollectionSize(actualExpression)) { val isForArrayOrCollection = isArrayLength(actualExpression) || isCollectionSize(actualExpression)
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return val isForString = isCharSequenceLength(actualExpression)
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return if (isHasSize && (isForArrayOrCollection
|| (isForString && checkAssertedType(expression, ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME)))
) {
val assertThatCall = PsiTreeUtil.findChildrenOfType(expression, PsiMethodCallExpression::class.java).find { CORE_ASSERT_THAT_MATCHER.test(it) } ?: return
registerConciseMethod(
REMOVE_SIZE_DESCRIPTION_TEMPLATE,
holder,
assertThatCall,
expression,
MethodNames.HAS_SAME_SIZE_AS
) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, expectedIsCollection = true, keepActualAsIs = true)
}
} else if (isForArrayOrCollection || isForString) {
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val constValue = calculateConstantParameterValue(expectedCallExpression, 0) val constValue = calculateConstantParameterValue(expectedCallExpression, 0)
if (IS_EQUAL_TO_INT.test(expectedCallExpression)) { if (IS_EQUAL_TO_INT.test(expectedCallExpression)) {
if (constValue == 0) { if (constValue == 0) {
registerSizeMethod(holder, expression, expectedCallExpression, "isEmpty()", noExpectedExpression = true) registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.IS_EMPTY) { desc, method ->
return ReplaceSizeMethodCallQuickFix(desc, method, noExpectedExpression = true)
} }
val equalToExpression = expectedCallExpression.argumentList.expressions[0]
if (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression)) {
registerSizeMethod(holder, expression, expectedCallExpression, "hasSameSizeAs()", expectedIsCollection = true)
return
}
registerSizeMethod(holder, expression, expectedCallExpression, "hasSize()")
} else { } else {
if ((IS_LESS_THAN_OR_EQUAL_TO_INT.test(expectedCallExpression) && (constValue == 0)) val equalToExpression = expectedCallExpression.firstArg
if (isForArrayOrCollection && (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression)) ||
isForString && (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression) || isCharSequenceLength(equalToExpression))
) {
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SAME_SIZE_AS) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, expectedIsCollection = true)
}
} else {
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SIZE) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method)
}
}
}
} else {
val isTestForEmpty = ((IS_LESS_THAN_OR_EQUAL_TO_INT.test(expectedCallExpression) && (constValue == 0))
|| (IS_LESS_THAN_INT.test(expectedCallExpression) && (constValue == 1)) || (IS_LESS_THAN_INT.test(expectedCallExpression) && (constValue == 1))
|| IS_ZERO.test(expectedCallExpression) || IS_ZERO.test(expectedCallExpression))
) { val isTestForNotEmpty = ((IS_GREATER_THAN_INT.test(expectedCallExpression) && (constValue == 0))
registerSizeMethod(holder, expression, expectedCallExpression, "isEmpty()", noExpectedExpression = true)
return
}
if ((IS_GREATER_THAN_INT.test(expectedCallExpression) && (constValue == 0))
|| (IS_GREATER_THAN_OR_EQUAL_TO_INT.test(expectedCallExpression) && (constValue == 1)) || (IS_GREATER_THAN_OR_EQUAL_TO_INT.test(expectedCallExpression) && (constValue == 1))
|| IS_NOT_ZERO.test(expectedCallExpression) || IS_NOT_ZERO.test(expectedCallExpression))
) { if (isTestForEmpty || isTestForNotEmpty) {
registerSizeMethod(holder, expression, expectedCallExpression, "isNotEmpty()", noExpectedExpression = true) val replacementMethod = isTestForEmpty.map(MethodNames.IS_EMPTY, MethodNames.IS_NOT_EMPTY)
return registerReplaceMethod(holder, expression, expectedCallExpression, replacementMethod) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
} else if (hasAssertJMethod(expression, ABSTRACT_ITERABLE_ASSERT_CLASSNAME, MethodNames.HAS_SIZE_LESS_THAN)) {
// new stuff in AssertJ 13.2.0
val matchedMethod = BONUS_EXPRESSIONS_CALL_MATCHER_MAP.find { it.first.test(expectedCallExpression) }?.second ?: return
registerReplaceMethod(holder, expression, expectedCallExpression, matchedMethod) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method)
} }
} }
} }
} }
}
private fun isCharSequenceLength(expression: PsiExpression) = (expression is PsiMethodCallExpression) && CHAR_SEQUENCE_LENGTH.test(expression)
private fun isCollectionSize(expression: PsiExpression) = (expression is PsiMethodCallExpression) && COLLECTION_SIZE.test(expression) private fun isCollectionSize(expression: PsiExpression) = (expression is PsiMethodCallExpression) && COLLECTION_SIZE.test(expression)
@@ -64,24 +104,6 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
return ((psiReferenceExpression.qualifierExpression?.type is PsiArrayType) return ((psiReferenceExpression.qualifierExpression?.type is PsiArrayType)
&& ((psiReferenceExpression.resolve() as? PsiField)?.name == "length")) && ((psiReferenceExpression.resolve() as? PsiField)?.name == "length"))
} }
private fun registerSizeMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
expectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
noExpectedExpression: Boolean = false,
expectedIsCollection: Boolean = false
) {
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
holder.registerProblem(
expression,
message,
ReplaceSizeMethodCallQuickFix(description, replacementMethod, noExpectedExpression, expectedIsCollection)
)
}
} }
} }
} }
@@ -0,0 +1,102 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.CommonClassNames
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.quickfixes.MoveActualOuterExpressionMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveActualOutmostMethodCallQuickFix
class AssertThatStringExpressionInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting a string specific expression"
private const val MOVE_EXPECTED_EXPRESSION_DESCRIPTION_TEMPLATE = "Remove %s() of expected expression and use assertThat().%s() instead"
private const val MOVING_OUT_MESSAGE_TEMPLATE = "Moving %s() expression out of assertThat() would be more concise"
private val MAPPINGS = listOf(
Mapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "isEmpty").parameterCount(0)!!,
MethodNames.IS_EMPTY, MethodNames.IS_NOT_EMPTY, hasExpected = false
),
Mapping(
CallMatcher.anyOf(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "equals").parameterCount(1)!!,
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "contentEquals").parameterCount(1)!!
),
MethodNames.IS_EQUAL_TO, MethodNames.IS_NOT_EQUAL_TO
),
Mapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "equalsIgnoreCase").parameterTypes(CommonClassNames.JAVA_LANG_STRING)!!,
MethodNames.IS_EQUAL_TO_IC, MethodNames.IS_NOT_EQUAL_TO_IC
),
Mapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "contains").parameterCount(1)!!,
MethodNames.CONTAINS, MethodNames.DOES_NOT_CONTAIN
),
Mapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "startsWith").parameterTypes(CommonClassNames.JAVA_LANG_STRING)!!,
MethodNames.STARTS_WITH, MethodNames.DOES_NOT_START_WITH
),
Mapping(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING, "endsWith").parameterTypes(CommonClassNames.JAVA_LANG_STRING)!!,
MethodNames.ENDS_WITH, MethodNames.DOES_NOT_END_WITH
)
)
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
if (!ASSERT_THAT_BOOLEAN.test(expression)) {
return
}
val assertThatArgument = expression.firstArg as? PsiMethodCallExpression ?: return
val mapping = MAPPINGS.firstOrNull { it.callMatcher.test(assertThatArgument) } ?: return
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedResult = getExpectedBooleanResult(expectedCallExpression) ?: return
val replacementMethod = if (expectedResult) mapping.replacementForTrue else mapping.replacementForFalse
if (mapping.hasExpected) {
registerMoveOutMethod(holder, expression, assertThatArgument, replacementMethod, ::MoveActualOuterExpressionMethodCallQuickFix)
} else {
registerMoveOutMethod(holder, expression, assertThatArgument, replacementMethod) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
}
}
}
}
private fun registerMoveOutMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldActualExpression: PsiMethodCallExpression,
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
val originalMethod = getOriginalMethodName(oldActualExpression) ?: return
val description = MOVE_EXPECTED_EXPRESSION_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = MOVING_OUT_MESSAGE_TEMPLATE.format(originalMethod)
val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickfix)
}
private class Mapping(
val callMatcher: CallMatcher,
val replacementForTrue: String,
val replacementForFalse: String,
val hasExpected: Boolean = true
)
}
@@ -4,6 +4,8 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor 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 de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.MethodNames
class AssertThatStringIsEmptyInspection : AbstractAssertJInspection() { class AssertThatStringIsEmptyInspection : AbstractAssertJInspection() {
@@ -29,7 +31,7 @@ class AssertThatStringIsEmptyInspection : AbstractAssertJInspection() {
val value = calculateConstantParameterValue(expression, 0) ?: return val value = calculateConstantParameterValue(expression, 0) ?: return
if ((isEqual && (value == "")) || (hasSize && (value == 0))) { if ((isEqual && (value == "")) || (hasSize && (value == 0))) {
registerSimplifyMethod(holder, expression, "isEmpty()") registerSimplifyMethod(holder, expression, MethodNames.IS_EMPTY)
} }
} }
} }
@@ -1,14 +1,14 @@
package de.platon42.intellij.plugins.cajon.inspections package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.util.TextRange import com.intellij.psi.*
import com.intellij.psi.CommonClassNames import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
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
import com.siyeh.ig.callMatcher.CallMatcher.staticCall
import de.platon42.intellij.plugins.cajon.AssertJClassNames
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitAssertMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitAssertMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitDeltaAssertMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitDeltaAssertMethodCallQuickFix
@@ -20,93 +20,93 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
private val MAPPINGS = listOf( private val MAPPINGS = listOf(
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes("boolean") staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes("boolean")
), ),
"isTrue()", false MethodNames.IS_TRUE, false
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes("boolean") staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes("boolean")
), ),
"isFalse()", false MethodNames.IS_FALSE, false
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT) staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)
), ),
"isNull()", false MethodNames.IS_NULL, false
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT) staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)
), ),
"isNotNull()", false MethodNames.IS_NOT_NULL, false
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("double", "double", "double"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("double", "double", "double"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("float", "float", "float") staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("float", "float", "float")
), ),
"isCloseTo()", hasDelta = true MethodNames.IS_CLOSE_TO, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2) staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2)
), ),
"isEqualTo()" MethodNames.IS_EQUAL_TO
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double", "double", "double"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("double", "double", "double"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("double", "double", "double"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("float", "float", "float") staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("float", "float", "float")
), ),
"isNotCloseTo()", hasDelta = true MethodNames.IS_NOT_CLOSE_TO, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2) staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2)
), ),
"isNotEqualTo()" MethodNames.IS_NOT_EQUAL_TO
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2) staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2)
), ),
"isSameAs()" MethodNames.IS_SAME_AS
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2) staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2)
), ),
"isNotSameAs()" MethodNames.IS_NOT_SAME_AS
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double[]", "double[]", "double"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "double[]", "double[]", "double"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("double[]", "double[]", "double"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("double[]", "double[]", "double"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float[]", "float[]", "float"), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float[]", "float[]", "float"),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("float[]", "float[]", "float") staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("float[]", "float[]", "float")
), ),
"containsExactly()", hasDelta = true MethodNames.CONTAINS_EXACTLY, hasDelta = true
), ),
Mapping( Mapping(
anyOf( anyOf(
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2), staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2),
CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3) staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3)
), ),
"containsExactly()" MethodNames.CONTAINS_EXACTLY
) )
) )
} }
@@ -121,53 +121,31 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
if (!isJUnitAssertCall) { if (!isJUnitAssertCall) {
return // early exit return // early exit
} }
for (mapping in MAPPINGS) { JavaPsiFacade.getInstance(expression.project)
if (mapping.callMatcher.test(expression)) { .findClass(AssertJClassNames.ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
val mapping = MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return
if (mapping.hasDelta) { if (mapping.hasDelta) {
registerDeltaReplacementMethod(holder, expression, mapping.replacement) registerConvertMethod(holder, expression, mapping.replacement, ::ReplaceJUnitDeltaAssertMethodCallQuickFix)
} else { } else {
registerSimpleReplacementMethod(holder, expression, mapping.hasExpected, mapping.replacement) registerConvertMethod(holder, expression, mapping.replacement) { desc, method ->
} ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected)
return
} }
} }
} }
} }
} }
private fun registerSimpleReplacementMethod( private fun registerConvertMethod(
holder: ProblemsHolder, holder: ProblemsHolder,
expression: PsiMethodCallExpression, expression: PsiMethodCallExpression,
hasExpected: Boolean, replacementMethod: String,
replacementMethod: String quickFixSupplier: (String, String) -> LocalQuickFix
) { ) {
val originalMethod = getOriginalMethodName(expression) ?: return val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod) val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = CONVERT_MESSAGE_TEMPLATE.format(originalMethod) val message = CONVERT_MESSAGE_TEMPLATE.format(originalMethod)
holder.registerProblem( val quickfix = quickFixSupplier(description, replacementMethod)
expression, holder.registerProblem(expression, message, quickfix)
message,
ProblemHighlightType.INFORMATION,
null as TextRange?,
ReplaceJUnitAssertMethodCallQuickFix(description, hasExpected, replacementMethod)
)
}
private fun registerDeltaReplacementMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
replacementMethod: String
) {
val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = CONVERT_MESSAGE_TEMPLATE.format(originalMethod)
holder.registerProblem(
expression,
message,
ProblemHighlightType.INFORMATION,
null as TextRange?,
ReplaceJUnitDeltaAssertMethodCallQuickFix(description, replacementMethod)
)
} }
private class Mapping( private class Mapping(
@@ -0,0 +1,87 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.quickfixes.JoinStatementsQuickFix
class JoinAssertThatStatementsInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Joining multiple assertThat() statements with same actual expression"
private const val CAN_BE_JOINED_DESCRIPTION = "Multiple assertThat() statements can be joined together"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitCodeBlock(block: PsiCodeBlock?) {
super.visitCodeBlock(block)
val statements = block?.statements ?: return
var lastActualExpression: PsiExpression? = null
var sameCount = 0
var firstStatement: PsiStatement? = null
var lastStatement: PsiStatement? = null
for (statement in statements) {
val assertThatCall = isLegitAssertThatCall(statement)
var reset = true
var actualExpression: PsiExpression? = null
if (assertThatCall != null) {
reset = (lastActualExpression == null)
actualExpression = assertThatCall.firstArg
if (!reset) {
val isSame = when (actualExpression) {
is PsiReferenceExpression -> (actualExpression.qualifierExpression == (lastActualExpression as? PsiReferenceExpression)?.qualifierExpression)
is PsiMethodCallExpression -> (actualExpression.text == (lastActualExpression as? PsiMethodCallExpression)?.text)
&& !KNOWN_METHODS_WITH_SIDE_EFFECTS.test(actualExpression)
is PsiPolyadicExpression -> (actualExpression.text == (lastActualExpression as? PsiPolyadicExpression)?.text)
else -> false
}
if (isSame) {
sameCount++
lastStatement = statement
} else {
reset = true
}
}
}
if (reset) {
if (sameCount > 1) {
registerProblem(firstStatement, lastStatement)
}
firstStatement = statement
lastStatement = null
lastActualExpression = actualExpression
sameCount = 1
}
}
if (sameCount > 1) {
registerProblem(firstStatement, lastStatement)
}
}
private fun registerProblem(firstStatement: PsiStatement?, lastStatement: PsiStatement?) {
val problemDescriptor = holder.manager.createProblemDescriptor(
firstStatement!!,
lastStatement!!,
CAN_BE_JOINED_DESCRIPTION,
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly,
JoinStatementsQuickFix()
)
holder.registerProblem(problemDescriptor)
}
private fun isLegitAssertThatCall(statement: PsiStatement?): PsiMethodCallExpression? {
if ((statement is PsiExpressionStatement) && (statement.expression is PsiMethodCallExpression)) {
val assertThatCall = PsiTreeUtil.findChildrenOfType(statement, PsiMethodCallExpression::class.java).find { ALL_ASSERT_THAT_MATCHERS.test(it) }
return assertThatCall?.takeIf { it.findFluentCallTo(EXTRACTING_CALL_MATCHERS) == null }
}
return null
}
}
}
}
@@ -1,32 +1,9 @@
package de.platon42.intellij.plugins.cajon.quickfixes package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.LocalQuickFix
import com.intellij.psi.PsiElementFactory
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiMethodCallExpression
import org.jetbrains.annotations.NonNls
abstract class AbstractCommonQuickFix(private val description: String) : LocalQuickFix { abstract class AbstractCommonQuickFix(private val description: String) : LocalQuickFix {
override fun getFamilyName() = description override fun getFamilyName() = description
companion object {
@NonNls
const val GUAVA_ASSERTIONS_CLASSNAME = "org.assertj.guava.api.Assertions"
}
protected fun addStaticImport(method: PsiMethod, element: PsiMethodCallExpression, factory: PsiElementFactory, vararg allowedClashes: String) {
val methodName = method.name
val containingClass = method.containingClass ?: return
val importList = (element.containingFile as PsiJavaFile).importList ?: return
val notImportedStatically = importList.importStaticStatements.none {
val targetClass = it.resolveTargetClass() ?: return@none false
((it.referenceName == methodName) && !allowedClashes.contains(targetClass.qualifiedName))
|| (it.isOnDemand && (targetClass == method.containingClass))
}
if (notImportedStatically) {
importList.add(factory.createImportStaticStatement(containingClass, methodName))
}
}
} }
@@ -0,0 +1,25 @@
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.PsiStatement
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.*
class ForGuavaPostFix {
companion object {
val REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT: (Project, ProblemDescriptor) -> Unit = exit@
{ _, descriptor ->
val element = descriptor.startElement
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return@exit
val assertThatCall = PsiTreeUtil.findChildrenOfType(statement, PsiMethodCallExpression::class.java).find { CORE_ASSERT_THAT_MATCHER.test(it) } ?: return@exit
val newMethodCall = createGuavaAssertThat(element, assertThatCall.firstArg)
newMethodCall.resolveMethod()?.addAsStaticImport(element, AssertJClassNames.ASSERTIONS_CLASSNAME)
val parentCall = PsiTreeUtil.getParentOfType(assertThatCall, PsiMethodCallExpression::class.java) ?: return@exit
parentCall.replaceQualifier(newMethodCall)
parentCall.shortenAndReformat()
}
}
}
@@ -0,0 +1,54 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.*
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.ALL_ASSERT_THAT_MATCHERS
class JoinStatementsQuickFix : AbstractCommonQuickFix(JOIN_STATEMENTS_MESSAGE) {
companion object {
private const val JOIN_STATEMENTS_MESSAGE = "Join assertThat() statements"
}
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val firstStatement = descriptor.startElement as PsiExpressionStatement
val lastStatement = descriptor.endElement as PsiExpressionStatement
do {
val commentsToKeep = ArrayList<PsiComment>()
val stuffToDelete = ArrayList<PsiElement>()
var previousStatement = lastStatement.prevSibling ?: throw IllegalStateException("Internal error")
while (previousStatement !is PsiExpressionStatement) {
if (previousStatement is PsiComment) {
commentsToKeep.add(previousStatement.copy() as PsiComment)
}
stuffToDelete.add(previousStatement)
previousStatement = previousStatement.prevSibling ?: throw IllegalStateException("Internal error")
}
stuffToDelete.forEach { if (it.isValid) it.delete() }
val statementComments = PsiTreeUtil.getChildrenOfAnyType(previousStatement, PsiComment::class.java)
commentsToKeep.addAll(statementComments)
val assertThatCallOfCursorStatement =
PsiTreeUtil.findChildrenOfType(lastStatement, PsiMethodCallExpression::class.java).find { ALL_ASSERT_THAT_MATCHERS.test(it) }
?: throw IllegalStateException("Internal error")
val lastElementBeforeConcat = assertThatCallOfCursorStatement.parent
commentsToKeep.forEach {
lastElementBeforeConcat.addAfter(it, lastElementBeforeConcat.firstChild)
val newLineNode =
PsiParserFacade.SERVICE.getInstance(project).createWhiteSpaceFromText("\n\t")
lastElementBeforeConcat.addAfter(newLineNode, lastElementBeforeConcat.firstChild)
}
val newLeaf = previousStatement.firstChild
assertThatCallOfCursorStatement.replace(newLeaf)
previousStatement.delete()
} while (previousStatement !== firstStatement)
val codeBlock = PsiTreeUtil.getParentOfType(lastStatement, PsiCodeBlock::class.java) ?: return
CodeStyleManager.getInstance(project).reformat(codeBlock)
}
}
@@ -0,0 +1,22 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.*
class MoveActualOuterExpressionMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.firstArg as? PsiMethodCallExpression ?: return
val assertExpressionArg = assertExpression.firstArg.copy()
assertExpression.replace(assertExpression.qualifierExpression)
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val expectedExpression = createExpectedMethodCall(element, replacementMethod, assertExpressionArg)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
}
@@ -0,0 +1,16 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
class QuickFixWithPostfixDelegate(
private val mainFix: LocalQuickFix,
private val postfix: (Project, ProblemDescriptor) -> Unit
) : LocalQuickFix by mainFix {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
mainFix.applyFix(project, descriptor)
postfix(project, descriptor)
}
}
@@ -0,0 +1,26 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.*
class RemoveActualOutmostMethodCallQuickFix(
description: String,
private val replacementMethod: String,
private val noExpectedExpression: Boolean = false
) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.firstArg as? PsiMethodCallExpression ?: return
assertExpression.replace(assertExpression.qualifierExpression)
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val args = if (noExpectedExpression) emptyArray() else oldExpectedExpression.argumentList.expressions
val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
}
@@ -0,0 +1,32 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiInstanceOfExpression
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.util.PsiUtil
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class RemoveInstanceOfExpressionQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.firstArg as? PsiInstanceOfExpression ?: return
val expectedClass = assertExpression.checkType ?: return
val factory = JavaPsiFacade.getElementFactory(project)
val classObjectAccess = factory.createExpressionFromText("${expectedClass.type.canonicalText}.class", null)
val operand = PsiUtil.deparenthesizeExpression(assertExpression.operand) ?: return
assertExpression.replace(operand)
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val expectedExpression = createExpectedMethodCall(element, replacementMethod, classObjectAccess)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
}
@@ -0,0 +1,27 @@
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.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class RemoveUnaryExpressionQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.firstArg as? PsiUnaryExpression ?: return
val operand = PsiUtil.skipParenthesizedExprDown(assertExpression.operand) ?: return
assertExpression.replace(operand)
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val expectedExpression = createExpectedMethodCall(element, replacementMethod)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
}
@@ -2,57 +2,41 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.codeStyle.CodeStyleManager import de.platon42.intellij.plugins.cajon.*
import com.intellij.psi.codeStyle.JavaCodeStyleManager import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME
class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val hasExpected: Boolean, private val replacementMethod: String) : class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val noExpectedExpression: Boolean) :
AbstractCommonQuickFix(description) { AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement val element = descriptor.startElement
val factory = JavaPsiFacade.getElementFactory(element.project)
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList val args = methodCallExpression.argumentList
val count = args.expressionCount val count = args.expressions.size
val actualExpression = args.expressions[count - 1] ?: return val actualExpression = args.expressions[count - 1] ?: return
val (expectedExpression, messageExpression) = if (hasExpected) { val (expectedExpression, messageExpression) = if (noExpectedExpression) {
val expected = args.expressions[count - 2] ?: return val message = args.expressions.getOrNull(count - 2)
val message = if (count > 2) args.expressions[0] else null emptyArray<PsiExpression>() to message
Pair(expected, message)
} else { } else {
val message = if (count > 1) args.expressions[0] else null val expected = args.expressions[count - 2] ?: return
Pair(null, message) val message = args.expressions.getOrNull(count - 3)
arrayOf(expected) to message
} }
val expectedMethodCall = factory.createExpressionFromText( val expectedMethodCall = createExpectedMethodCall(element, replacementMethod, *expectedExpression)
"a.${if (hasExpected) replacementMethod.replace("()", "(e)") else replacementMethod}", element val newMethodCall = createAssertThat(element, actualExpression)
) as PsiMethodCallExpression
if (hasExpected) {
expectedMethodCall.argumentList.expressions[0].replace(expectedExpression!!)
}
val newMethodCall = factory.createExpressionFromText(
"org.assertj.core.api.Assertions.assertThat(a)", element
) as PsiMethodCallExpression
newMethodCall.argumentList.expressions[0].replace(actualExpression)
if (messageExpression != null) { if (messageExpression != null) {
val asExpression = factory.createExpressionFromText("a.as(desc)", element) as PsiMethodCallExpression val asExpression = createExpectedMethodCall(element, MethodNames.AS, messageExpression)
asExpression.argumentList.expressions[0].replace(messageExpression) asExpression.replaceQualifier(newMethodCall)
asExpression.methodExpression.qualifierExpression!!.replace(newMethodCall) expectedMethodCall.replaceQualifier(asExpression)
expectedMethodCall.methodExpression.qualifierExpression!!.replace(asExpression)
} else { } else {
expectedMethodCall.methodExpression.qualifierExpression!!.replace(newMethodCall) expectedMethodCall.replaceQualifier(newMethodCall)
} }
val assertThatMethod = newMethodCall.resolveMethod() ?: return newMethodCall.resolveMethod()?.addAsStaticImport(element, GUAVA_ASSERTIONS_CLASSNAME)
addStaticImport(assertThatMethod, element, factory, GUAVA_ASSERTIONS_CLASSNAME) element.replace(expectedMethodCall).shortenAndReformat()
val codeStyleManager = JavaCodeStyleManager.getInstance(element.project)
val newElement = element.replace(expectedMethodCall)
val shortened = codeStyleManager.shortenClassReferences(newElement)
CodeStyleManager.getInstance(element.project).reformat(shortened)
} }
} }
@@ -2,59 +2,36 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.codeStyle.CodeStyleManager import de.platon42.intellij.plugins.cajon.*
import com.intellij.psi.codeStyle.JavaCodeStyleManager 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) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement val element = descriptor.startElement
val factory = JavaPsiFacade.getElementFactory(element.project)
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList val args = methodCallExpression.argumentList
val count = args.expressionCount val count = args.expressions.size
val actualExpression = args.expressions[count - 2] ?: return val messageExpression = args.expressions.getOrNull(count - 4)
val messageExpression = if (count > 3) args.expressions[0] else null
val expectedExpression = args.expressions[count - 3] ?: return val expectedExpression = args.expressions[count - 3] ?: return
val actualExpression = args.expressions[count - 2] ?: return
val deltaExpression = args.expressions[count - 1] ?: return val deltaExpression = args.expressions[count - 1] ?: return
val offsetMethodCall = factory.createExpressionFromText( val offsetMethodCall = createMethodCall(element, "org.assertj.core.data.Offset.offset", deltaExpression)
"org.assertj.core.data.Offset.offset(c)", element val expectedMethodCall = createExpectedMethodCall(element, replacementMethod, expectedExpression, offsetMethodCall)
) as PsiMethodCallExpression val newMethodCall = createAssertThat(element, actualExpression)
offsetMethodCall.argumentList.expressions[0].replace(deltaExpression)
val expectedMethodCall = factory.createExpressionFromText(
"a.${replacementMethod.removeSuffix("()")}(e, offs)", element
) as PsiMethodCallExpression
expectedMethodCall.argumentList.expressions[0].replace(expectedExpression)
expectedMethodCall.argumentList.expressions[1].replace(offsetMethodCall)
val newMethodCall = factory.createExpressionFromText(
"org.assertj.core.api.Assertions.assertThat(a)", element
) as PsiMethodCallExpression
newMethodCall.argumentList.expressions[0].replace(actualExpression)
if (messageExpression != null) { if (messageExpression != null) {
val asExpression = factory.createExpressionFromText("a.as(desc)", element) as PsiMethodCallExpression val asExpression = createExpectedMethodCall(element, MethodNames.AS, messageExpression)
asExpression.argumentList.expressions[0].replace(messageExpression) asExpression.replaceQualifier(newMethodCall)
asExpression.methodExpression.qualifierExpression!!.replace(newMethodCall) expectedMethodCall.replaceQualifier(asExpression)
expectedMethodCall.methodExpression.qualifierExpression!!.replace(asExpression)
} else { } else {
expectedMethodCall.methodExpression.qualifierExpression!!.replace(newMethodCall) expectedMethodCall.replaceQualifier(newMethodCall)
} }
val assertThatMethod = newMethodCall.resolveMethod() ?: return newMethodCall.resolveMethod()?.addAsStaticImport(element, GUAVA_ASSERTIONS_CLASSNAME)
addStaticImport(assertThatMethod, element, factory, GUAVA_ASSERTIONS_CLASSNAME) offsetMethodCall.resolveMethod()?.addAsStaticImport(element)
val offsetMethod = offsetMethodCall.resolveMethod() ?: return element.replace(expectedMethodCall).shortenAndReformat()
addStaticImport(offsetMethod, element, factory)
val codeStyleManager = JavaCodeStyleManager.getInstance(element.project)
val newElement = element.replace(expectedMethodCall)
val shortened = codeStyleManager.shortenClassReferences(newElement)
CodeStyleManager.getInstance(element.project).reformat(shortened)
} }
} }
@@ -2,19 +2,17 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class ReplaceSimpleMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) { class ReplaceSimpleMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement val element = descriptor.startElement
val factory = JavaPsiFacade.getElementFactory(element.project)
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val oldQualifier = methodCallExpression.methodExpression.qualifierExpression ?: return val expectedExpression = createExpectedMethodCall(element, replacementMethod)
val expectedExpression = expectedExpression.replaceQualifierFromMethodCall(methodCallExpression)
factory.createExpressionFromText("a.$replacementMethod", element) as PsiMethodCallExpression
expectedExpression.methodExpression.qualifierExpression!!.replace(oldQualifier)
element.replace(expectedExpression) element.replace(expectedExpression)
} }
} }
@@ -2,33 +2,36 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.* import com.intellij.psi.PsiExpression
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiReferenceExpression
import de.platon42.intellij.plugins.cajon.*
class ReplaceSizeMethodCallQuickFix( class ReplaceSizeMethodCallQuickFix(
description: String, description: String,
private val replacementMethod: String, private val replacementMethod: String,
private val noExpectedExpression: Boolean, private val noExpectedExpression: Boolean = false,
private val expectedIsCollection: Boolean private val expectedIsCollection: Boolean = false,
private val keepActualAsIs: Boolean = false
) : AbstractCommonQuickFix(description) { ) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement val element = descriptor.startElement
val factory = JavaPsiFacade.getElementFactory(element.project)
val methodCallExpression = element as? PsiMethodCallExpression ?: return val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.argumentList.expressions[0] ?: return if (!keepActualAsIs) {
val assertExpression = methodCallExpression.firstArg
replaceCollectionSizeOrArrayLength(assertExpression) replaceCollectionSizeOrArrayLength(assertExpression)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return }
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val expectedExpression =
factory.createExpressionFromText("a.${if (noExpectedExpression) replacementMethod else replacementMethod.replace("()", "(e)")}", element) as PsiMethodCallExpression
if (!noExpectedExpression) {
if (expectedIsCollection) { if (expectedIsCollection) {
replaceCollectionSizeOrArrayLength(oldExpectedExpression.argumentList.expressions[0]) replaceCollectionSizeOrArrayLength(oldExpectedExpression.firstArg)
} }
expectedExpression.argumentList.expressions[0].replace(oldExpectedExpression.argumentList.expressions[0])
} val args = if (noExpectedExpression) emptyArray() else arrayOf(oldExpectedExpression.firstArg)
expectedExpression.methodExpression.qualifierExpression!!.replace(oldExpectedExpression.methodExpression.qualifierExpression!!) val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression) oldExpectedExpression.replace(expectedExpression)
} }
@@ -36,7 +39,7 @@ class ReplaceSizeMethodCallQuickFix(
assertExpression.replace( assertExpression.replace(
when (assertExpression) { when (assertExpression) {
is PsiReferenceExpression -> assertExpression.qualifierExpression!! is PsiReferenceExpression -> assertExpression.qualifierExpression!!
is PsiMethodCallExpression -> assertExpression.methodExpression.qualifierExpression!! is PsiMethodCallExpression -> assertExpression.qualifierExpression
else -> return else -> return
} }
) )
@@ -0,0 +1,32 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiBinaryExpression
import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class SplitBinaryExpressionMethodCallQuickFix(
description: String,
private val replacementMethod: String,
private val pickRightOperand: Boolean = false,
private val noExpectedExpression: Boolean = false
) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val binaryExpression = methodCallExpression.firstArg as? PsiBinaryExpression ?: return
val expectedArgument = (if (pickRightOperand) binaryExpression.lOperand else binaryExpression.rOperand)?.copy() ?: return
binaryExpression.replace(if (pickRightOperand) binaryExpression.rOperand!! else binaryExpression.lOperand)
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val args = if (noExpectedExpression) emptyArray() else arrayOf(expectedArgument)
val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
}
@@ -0,0 +1,21 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class UnwrapExpectedStaticMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val expectedMethodCallExpression = oldExpectedExpression.firstArg as? PsiMethodCallExpression ?: return
val expectedExpression = createExpectedMethodCall(element, replacementMethod, expectedMethodCallExpression.firstArg)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
}
@@ -0,0 +1,159 @@
package de.platon42.intellij.plugins.cajon.references
import com.intellij.lang.jvm.JvmModifier
import com.intellij.openapi.util.TextRange
import com.intellij.patterns.PlatformPatterns
import com.intellij.psi.*
import com.intellij.psi.util.PropertyUtilBase
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.PsiTypesUtil
import com.intellij.util.ArrayUtil
import com.intellij.util.ProcessingContext
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.*
class ExtractorReferenceContributor : PsiReferenceContributor() {
companion object {
private val BY_NAME = CallMatcher.staticCall(AssertJClassNames.EXTRACTORS_CLASSNAME, "byName")
private val RESULT_OF = CallMatcher.staticCall(AssertJClassNames.EXTRACTORS_CLASSNAME, "resultOf")
.parameterTypes(CommonClassNames.JAVA_LANG_STRING)!!
private val propertyOrFieldReferenceProvider = PropertyOrFieldReferenceProvider()
private val iterablePropertyOrFieldReferenceProvider = IterablePropertyOrFieldReferenceProvider()
private val iterableResultOfReferenceProvider = IterableResultOfReferenceProvider()
private fun lookupFieldOrProperty(containingClass: PsiClass, path: String, startOffset: Int): List<Pair<TextRange, List<PsiElement>>> {
val partName = path.substring(startOffset).substringBefore(".")
val nextOffset = startOffset + partName.length + 1
val matchedGetter = PropertyUtilBase.findPropertyGetter(containingClass, partName, false, true)
val fieldResult = PropertyUtilBase.findPropertyField(containingClass, partName, false)
val textRange = TextRange(startOffset + 1, nextOffset)
val matchedBareMethod = containingClass.allMethods.find { (it.name == partName) && !it.hasModifier(JvmModifier.STATIC) }
val targets = listOfNotNull<PsiElement>(fieldResult, matchedGetter, matchedBareMethod)
if (targets.isNotEmpty()) {
val results = listOf(textRange to targets)
if (nextOffset >= path.length) {
return results
}
val nextClass = PsiTypesUtil.getPsiClass(matchedGetter?.returnType ?: fieldResult?.type) ?: return results
return listOf(results, lookupFieldOrProperty(nextClass, path, nextOffset)).flatten()
}
return emptyList()
}
private fun lookupMethod(containingClass: PsiClass, methodName: String): List<Pair<TextRange, List<PsiElement>>>? {
val matchedMethod = containingClass.allMethods.find { (it.name == methodName) && !it.hasModifier(JvmModifier.STATIC) } ?: return null
val textRange = TextRange(1, methodName.length + 1)
return listOf(textRange to listOf(matchedMethod))
}
private fun findActualType(element: PsiElement): PsiClassType? {
val assertThatCall = PsiTreeUtil.findChildrenOfType(element, PsiMethodCallExpression::class.java)
.find { CORE_ASSERT_THAT_MATCHER.test(it) } ?: return null
return assertThatCall.firstArg.type as? PsiClassType
}
private fun findAndCreateReferences(element: PsiElement, finder: (PsiLiteralExpression) -> List<Pair<TextRange, List<PsiElement>>>?): Array<PsiReference> {
val literal = element as PsiLiteralExpression
val results = finder(literal)
if (results != null) {
return results.map { ExtractorReference(literal, it.first, it.second) }.toTypedArray()
}
return PsiReference.EMPTY_ARRAY
}
}
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression::class.java), propertyOrFieldReferenceProvider)
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression::class.java), iterablePropertyOrFieldReferenceProvider)
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression::class.java), iterableResultOfReferenceProvider)
}
class ExtractorReference(literal: PsiLiteralExpression, range: TextRange, private val targets: List<PsiElement>) :
PsiPolyVariantReferenceBase<PsiLiteralExpression>(literal, range, true) {
override fun getVariants(): Array<Any> {
return ArrayUtil.EMPTY_OBJECT_ARRAY
}
override fun resolve(): PsiElement? {
return multiResolve(false).map(ResolveResult::getElement).firstOrNull()
}
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> {
return PsiElementResolveResult.createResults(targets)
}
}
class PropertyOrFieldReferenceProvider : PsiReferenceProvider() {
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
return findAndCreateReferences(element, ::findReferences)
}
fun findReferences(element: PsiLiteralExpression): List<Pair<TextRange, List<PsiElement>>>? {
val literal = element.value as? String ?: return null
var methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression::class.java) ?: return null
var isResultOf = false
if (BY_NAME.test(methodCallExpression)) {
methodCallExpression = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return null
} else if (RESULT_OF.test(methodCallExpression)) {
methodCallExpression = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return null
isResultOf = true
}
if (!EXTRACTING_FROM_OBJECT.test(methodCallExpression)) {
return emptyList()
}
val containingClass = PsiTypesUtil.getPsiClass(findActualType(methodCallExpression)) ?: return null
return if (isResultOf) lookupMethod(containingClass, literal) else lookupFieldOrProperty(containingClass, literal, 0)
}
}
class IterablePropertyOrFieldReferenceProvider : PsiReferenceProvider() {
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
return findAndCreateReferences(element, ::findReferences)
}
fun findReferences(element: PsiLiteralExpression): List<Pair<TextRange, List<PsiElement>>>? {
val literal = element.value as? String ?: return null
var methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression::class.java) ?: return null
var isResultOf = false
if (BY_NAME.test(methodCallExpression)) {
methodCallExpression = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return null
} else if (RESULT_OF.test(methodCallExpression)) {
methodCallExpression = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return null
isResultOf = true
}
if (!CallMatcher.anyOf(EXTRACTING_FROM_ITERABLE, FLAT_EXTRACTING_FROM_ITERABLE).test(methodCallExpression)) {
return null
}
val iterableType = findActualType(methodCallExpression) ?: return null
val innerType = iterableType.resolveGenerics().substitutor.substitute(iterableType.parameters[0])
val containingClass = PsiTypesUtil.getPsiClass(innerType) ?: return null
return if (isResultOf) lookupMethod(containingClass, literal) else lookupFieldOrProperty(containingClass, literal, 0)
}
}
class IterableResultOfReferenceProvider : PsiReferenceProvider() {
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
return findAndCreateReferences(element, ::findReferences)
}
fun findReferences(element: PsiLiteralExpression): List<Pair<TextRange, List<PsiElement>>>? {
val literal = element.value as? String ?: return null
val methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression::class.java) ?: return null
if (!EXTRACTING_RESULT_OF_FROM_ITERABLE.test(methodCallExpression)) {
return null
}
val iterableType = findActualType(methodCallExpression) ?: return null
val innerType = iterableType.resolveGenerics().substitutor.substitute(iterableType.parameters[0])
val containingClass = PsiTypesUtil.getPsiClass(innerType) ?: return null
return lookupMethod(containingClass, literal)
}
}
}
+30 -16
View File
@@ -5,12 +5,14 @@
<description><![CDATA[ <description><![CDATA[
Cajon is an IntelliJ IDEA Plugin for shortening and optimizing AssertJ assertions. Cajon is an IntelliJ IDEA Plugin for shortening and optimizing AssertJ assertions.
It adds inspections and quick fixes to fully make use of the AssertJ methods It adds several inspections and quick fixes to fully use the fluent assertion methods
to make the intention clear and concise. It can also convert JUnit 4 assertions to AssertJ. and thus makes the intention clear and concise, also generating better messages on test failures.
It can also be used to convert JUnit 4 assertions to AssertJ.
It supports referencing inside extracting()-methods with strings, adding refactoring safety.
]]></description> ]]></description>
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description --> <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
<idea-version since-build="182.0"/> <idea-version since-build="173.2696.26"/>
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products --> on how to target different products -->
@@ -19,25 +21,37 @@
<depends>com.intellij.modules.java</depends> <depends>com.intellij.modules.java</depends>
<extensions defaultExtensionNs="com.intellij"> <extensions defaultExtensionNs="com.intellij">
<localInspection groupPath="Java" shortName="AssertThatObjectIsNull" enabledByDefault="true" level="WARNING" <psi.referenceContributor implementation="de.platon42.intellij.plugins.cajon.references.ExtractorReferenceContributor"/>
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatObjectIsNullInspection"/> <localInspection groupPath="Java" shortName="AssertThatObjectIsNullOrNotNull" enabledByDefault="true" level="WARNING"
<localInspection groupPath="Java" shortName="AssertThatObjectIsNotNull" enabledByDefault="true" level="WARNING" implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatObjectIsNullOrNotNullInspection"/>
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatObjectIsNotNullInspection"/> <localInspection groupPath="Java" shortName="AssertThatBooleanCondition" enabledByDefault="true" level="WARNING"
<localInspection groupPath="Java" shortName="AssertThatBooleanIsTrueOrFalse" enabledByDefault="true" implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatBooleanConditionInspection"/>
level="WARNING" <localInspection groupPath="Java" shortName="AssertThatInvertedBooleanCondition" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatBooleanIsTrueOrFalseInspection"/> implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatInvertedBooleanConditionInspection"/>
<localInspection groupPath="Java" shortName="AssertThatInstanceOf" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatInstanceOfInspection"/>
<localInspection groupPath="Java" shortName="AssertThatStringIsEmpty" enabledByDefault="true" level="WARNING" <localInspection groupPath="Java" shortName="AssertThatStringIsEmpty" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatStringIsEmptyInspection"/> implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatStringIsEmptyInspection"/>
<localInspection groupPath="Java" shortName="AssertThatEnumerableIsEmpty" enabledByDefault="true" <localInspection groupPath="Java" shortName="AssertThatEnumerableIsEmpty" enabledByDefault="true" level="WARNING"
level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatEnumerableIsEmptyInspection"/> implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatEnumerableIsEmptyInspection"/>
<localInspection groupPath="Java" shortName="AssertThatSize" enabledByDefault="true" <localInspection groupPath="Java" shortName="AssertThatSize" enabledByDefault="true" level="WARNING"
level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatSizeInspection"/> implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatSizeInspection"/>
<localInspection groupPath="Java" shortName="JUnitAssertToAssertJ" enabledByDefault="true" <localInspection groupPath="Java" shortName="AssertThatBinaryExpression" enabledByDefault="true" level="WARNING"
level="WARNING" implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatBinaryExpressionInspection"/>
<localInspection groupPath="Java" shortName="AssertThatStringExpression" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatStringExpressionInspection"/>
<localInspection groupPath="Java" shortName="JoinAssertThatStatements" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.JoinAssertThatStatementsInspection"/>
<localInspection groupPath="Java" shortName="AssertThatJava8Optional" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatJava8OptionalInspection"/>
<localInspection groupPath="Java" shortName="AssertThatGuavaOptional" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatGuavaOptionalInspection"/>
<localInspection groupPath="Java" shortName="JUnitAssertToAssertJ" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.JUnitAssertToAssertJInspection"/> implementationClass="de.platon42.intellij.plugins.cajon.inspections.JUnitAssertToAssertJInspection"/>
</extensions> </extensions>
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Foo" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
width="226.77px" height="226.77px" viewBox="0 0 226.77 226.77" enable-background="new 0 0 226.77 226.77" xml:space="preserve">
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="44.1792" y1="72.1201" x2="184.0214" y2="-8.6178">
<stop offset="0.2408" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<path fill="url(#SVGID_1_)" stroke="#231F20" stroke-miterlimit="10" d="M210.1,36.551L122.5,7.75
C18.101,26.951,18.101,26.951,18.101,26.951L94.3,55.75L210.1,36.551"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="-12.9795" y1="80.7827" x2="127.5331" y2="161.9077">
<stop offset="0.1763" style="stop-color:#FFFFFF"/>
<stop offset="0.2617" style="stop-color:#F9F9F9"/>
<stop offset="0.3726" style="stop-color:#E9E9E9"/>
<stop offset="0.4976" style="stop-color:#CFCECE"/>
<stop offset="0.6329" style="stop-color:#AAA9A9"/>
<stop offset="0.7765" style="stop-color:#7B7979"/>
<stop offset="0.9248" style="stop-color:#433F40"/>
<stop offset="1" style="stop-color:#231F20"/>
</linearGradient>
<polygon fill="url(#SVGID_2_)" stroke="#231F20" stroke-miterlimit="10" points="17.5,185.35 94.6,218.95 94.3,55.75
18.101,26.951 "/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="88.6709" y1="122.3887" x2="214.4668" y2="133.3944">
<stop offset="0.1216" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#2B2728"/>
<stop offset="1" style="stop-color:#231F20"/>
</linearGradient>
<polygon fill="url(#SVGID_3_)" stroke="#231F20" stroke-miterlimit="10" points="94.5,55.75 94.5,56.35 94.5,55.75 95,219.25
209.5,190.15 209.5,36.65 "/>
</g>
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="51.6982" y1="79.75" x2="51.6982" y2="79.75">
<stop offset="0.1763" style="stop-color:#FFFFFF"/>
<stop offset="0.2617" style="stop-color:#F9F9F9"/>
<stop offset="0.3726" style="stop-color:#E9E9E9"/>
<stop offset="0.4976" style="stop-color:#CFCECE"/>
<stop offset="0.6329" style="stop-color:#AAA9A9"/>
<stop offset="0.7765" style="stop-color:#7B7979"/>
<stop offset="0.9248" style="stop-color:#433F40"/>
<stop offset="1" style="stop-color:#231F20"/>
</linearGradient>
<path fill="url(#SVGID_4_)" stroke="#231F20" stroke-miterlimit="10" d="M51.699,79.75"/>
<path fill="#231F20" stroke="#231F20" stroke-miterlimit="10" d="M171.307,117.313c0.267,13.237-6.324,27.028-14.723,30.805
s-15.423-3.893-15.69-17.132c-0.267-13.236,6.323-27.029,14.723-30.805C164.015,96.405,171.039,104.076,171.307,117.313z"/>
<polygon fill="#39B54A" stroke="#231F20" stroke-width="0.25" stroke-miterlimit="10" points="175.6,143.05 176.2,99.7 183.55,97
191.95,132.25 193.3,92.95 198.1,91.45 196.3,136.6 188.95,138.85 180.85,103.45 180.7,141.55 "/>
<path fill="#009444" stroke="#231F20" stroke-width="0.25" stroke-miterlimit="10" d="M109.9,113.65c1.8,0,25.35-5.25,25.35-5.25
l1.2,38.7l-6.9,7.5l-11.25,3.15l-5.55-5.25l-1.5-6.75l5.1-1.35l1.95,6.6l3.45,1.05l5.25-1.95l4.5-4.35l-0.6-30.9l-19.2,4.051
L109.9,113.65z"/>
<path fill="#00A79D" stroke="#231F20" stroke-width="0.25" stroke-miterlimit="10" d="M46.15,102.4c0-0.45-2.85-6.45-2.85-6.45
l-6.75-3l-5.7,0.15l-1.916,1.667L26.2,97.15l-2.4,5.1l-0.9,8.55l-0.75,12.15l0.3,12.3l2.85,8.25l8.85,4.95l7.2,0.45l5.55-5.551
l1.8-3.6l-3.15-4.05l-2.85,2.25l-3,3.6l-5.4,1.351l-4.2-1.95l-2.4-5.7l-1.05-5.85l0.6-10.051L28,110.8l0.9-6.75l1.95-3.75l6-0.75
l3.45,1.95l2.25,2.7l1.95,1.5L46.15,102.4z"/>
<polygon fill="#2BB673" stroke="#231F20" stroke-width="0.25" stroke-miterlimit="10" points="52.9,151.9 70.4,101.549
76.1,104.249 85.2,164.05 79.1,160.85 73.1,111.05 71.4,110.149 67,127.15 73.7,129.749 74.5,136.351 65.5,132.7 58.1,154.049 "/>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

@@ -0,0 +1,11 @@
<html>
<body>
Turns a binary expression in the kind of assertThat(actual &lt;operator&gt; expected) with .isTrue()/isFalse()/isEqualTo()/isNotEqualTo()
into assertThat(actual).is&lt;operator&gt;(expected).
<!-- tooltip end -->
There are over 150 combinations that are found with this inspections.
It also detects assertThat(actual.equals(expected)) assertions.
Also works with constant expressions on the expected side.
Swaps actual and expected when actual is a constant expression (correctly transforming the used operator).
</body>
</html>
@@ -0,0 +1,8 @@
<html>
<body>
Looks at expected and actual expression being of Guava Optional type and whether the statement effectively tries to assert the
presence, absence or content and then replaces the statement by isPresent(), isAbsent(), or contains().
<!-- tooltip end -->
Requires AssertJ-Guava to be in classpath.
</body>
</html>
@@ -0,0 +1,7 @@
<html>
<body>
Turns assertThat(object instanceof classname).isEqualTo(true/false) into assertThat(object).is(Not)InstanceOf(classname.class).
<!-- tooltip end -->
Also works with constant expressions and Boolean.TRUE/FALSE.
</body>
</html>
@@ -0,0 +1,7 @@
<html>
<body>
Turns assertThat(!condition).isEqualTo(true/false) into assertThat(condition).isFalse()/isTrue().
<!-- tooltip end -->
Also works with constant expressions and Boolean.TRUE/FALSE.
</body>
</html>
@@ -0,0 +1,7 @@
<html>
<body>
Looks at expected and actual expression being of Java 8 Optional type and whether the statement effectively tries to assert the
presence, absence or content and then replaces the statement by isPresent(), isNotPresent(), contains(), or containsSame().
<!-- tooltip end -->
</body>
</html>
@@ -1,6 +0,0 @@
<html>
<body>
Turns assertThat(object).isNotEqualTo(null) into assertThat(object).isNotNull().
<!-- tooltip end -->
</body>
</html>
@@ -1,6 +0,0 @@
<html>
<body>
Turns assertThat(object).isEqualTo(null) into assertThat(object).isNull().
<!-- tooltip end -->
</body>
</html>
@@ -0,0 +1,6 @@
<html>
<body>
Turns assertThat(object).is(Not)EqualTo(null) into assertThat(object).is(Not)Null().
<!-- tooltip end -->
</body>
</html>
@@ -1,6 +1,7 @@
<html> <html>
<body> <body>
Makes assertions on sizes of arrays or collections more concise by replacing them with isEmpty(), isNotEmpty(), hasSize(), or hasSameSizeAs(). Makes assertions on sizes of arrays, collections, strings, or CharSequences more concise by replacing them with isEmpty(), isNotEmpty(), hasSize(), or hasSameSizeAs().
<!-- tooltip end --> <!-- tooltip end -->
Several more conversions are available with AssertJ 13.2.0 or later.
</body> </body>
</html> </html>
@@ -0,0 +1,7 @@
<html>
<body>
Turns assertThat(string.someMethod(arg)).isTrue/isFalse() into assertThat(string).someMethod(arg).
<!-- tooltip end -->
<br>someMethod() can be equals(), equalsIgnoreCase(), contentEquals(), contains(), startsWith(), and endsWith().
</body>
</html>
@@ -131,7 +131,6 @@ public class LightCodeInsightExtension implements ParameterResolver, AfterTestEx
VirtualFile jarFile = LocalFileSystem.getInstance().findFileByIoFile(jarPath.toFile()); VirtualFile jarFile = LocalFileSystem.getInstance().findFileByIoFile(jarPath.toFile());
myFixture.allowTreeAccessForFile(jarFile); myFixture.allowTreeAccessForFile(jarFile);
PsiTestUtil.addLibrary( PsiTestUtil.addLibrary(
myFixture.getModule(),
model, model,
jarPath.getFileName().toString().replace(".jar", ""), jarPath.getFileName().toString().replace(".jar", ""),
jarPath.getParent().toString(), jarPath.getParent().toString(),
@@ -2,11 +2,13 @@ package de.platon42.intellij.playground;
import org.assertj.core.api.ListAssert; import org.assertj.core.api.ListAssert;
import org.assertj.core.data.Offset; import org.assertj.core.data.Offset;
import org.assertj.core.extractor.Extractors;
import java.util.ArrayList; import java.util.*;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Offset.offset; import static org.assertj.core.data.Offset.offset;
import static org.assertj.guava.api.Assertions.assertThat;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class Playground { public class Playground {
@@ -27,8 +29,43 @@ public class Playground {
assertThat(new ArrayList<String>().size()).isEqualTo(1); assertThat(new ArrayList<String>().size()).isEqualTo(1);
assertThat(new ArrayList<String>().size()).isGreaterThanOrEqualTo(1); assertThat(new ArrayList<String>().size()).isGreaterThanOrEqualTo(1);
assertThat(new ArrayList<String>().size()).isZero(); assertThat(new ArrayList<String>().size()).isZero();
assertThat(new ArrayList<String>()).hasSizeGreaterThan(1);
assertThat(new ArrayList<String>()).hasSameSizeAs(new ArrayList<>()); assertThat(new ArrayList<String>()).hasSameSizeAs(new ArrayList<>());
assertThat(new Long[1]).as("etc").hasSameSizeAs(new Long[2]); assertThat(new Long[1]).as("etc").hasSameSizeAs(new Long[2]);
assertThat(new Long[1]).as("etc").hasSameSizeAs(new Long[2]);
}
private void joinStatements() {
List<String> list = new ArrayList<>();
assertThat(list).as("foo").hasSize(2);
assertThat(list).as("bar").contains("barbar"); // comment to keep
assertThat(list).as("etc").contains("etcetc");
// moar!
assertThat(list).doesNotContain("foobar");
assertThat("narf").isNotEqualTo("puit");
assertThat(list).as("bar").contains("barbar");
assertThat(list).as("foo").hasSize(2);
assertThat(list).as("evil").extracting(String::length).contains(2);
assertThat(list).as("bar").contains("barbar");
assertThat("narf").isNotEqualTo("puit");
assertThat(list).as("foo").hasSize(2);
if (true) {
assertThat(list).doesNotContain("narf");
assertThat(list).as("bar").contains("barbar");
}
assertThat(list.get(0)).isNotEmpty();
assertThat(list.get(0)).hasSize(3);
assertThat(list.get(0)).isEqualTo("bar");
assertThat(list.get(0) + "foo").isEqualTo("bar");
assertThat(list.get(0) + "foo").doesNotStartWith("foo");
Iterator<String> iterator = list.iterator();
assertThat(iterator.next()).isEqualTo("foo");
assertThat(iterator.next()).isEqualTo("bar");
} }
private void sizeOfArray() { private void sizeOfArray() {
@@ -69,13 +106,186 @@ public class Playground {
assertThat("").isEqualTo(Boolean.TRUE); assertThat("").isEqualTo(Boolean.TRUE);
} }
private void stringIsEmpty() { private void binaryExpression() {
int primExp = 42;
int primAct = 1337;
Double numberObjExp = 42.0;
Double numberObjAct = 1337.0;
String stringExp = "foo";
String stringAct = "bar";
assertThat(primAct == primExp).isTrue();
assertThat(primAct == 1).isTrue();
assertThat(primAct == primExp).isEqualTo(false);
assertThat(primAct != primExp).isEqualTo(true);
assertThat(1 != primAct).isTrue();
assertThat(primAct != primExp).isNotEqualTo(true);
assertThat(primAct > primExp).isNotEqualTo(false);
assertThat(primAct > primExp).isFalse();
assertThat(primAct > 1).isFalse();
assertThat(primAct >= 1).isTrue();
assertThat(primAct >= primExp).isEqualTo(false);
assertThat(1 <= primAct).isFalse();
assertThat(1 > primAct).isTrue();
assertThat(primAct < primExp).isNotEqualTo(true);
assertThat(primAct <= primExp).isNotEqualTo(false);
assertThat(primAct <= primExp).isFalse();
assertThat(primAct <= 1).isFalse();
assertThat(numberObjAct == 1).isTrue();
assertThat(numberObjAct == numberObjExp).isEqualTo(false);
assertThat(numberObjAct != numberObjExp).isEqualTo(true);
assertThat(1 != numberObjAct).isTrue();
assertThat(numberObjAct != numberObjExp).isNotEqualTo(true);
assertThat(numberObjAct > numberObjExp).isNotEqualTo(false);
assertThat(numberObjAct > 1).isFalse();
assertThat(numberObjAct >= numberObjExp).isTrue();
assertThat(numberObjAct >= numberObjExp).isEqualTo(false);
assertThat(1 <= numberObjAct).isFalse();
assertThat(numberObjAct < numberObjExp).isEqualTo(true);
assertThat(numberObjAct < numberObjExp).isNotEqualTo(true);
assertThat(numberObjAct <= numberObjExp).isNotEqualTo(false);
assertThat(numberObjAct <= 1).isFalse();
assertThat(numberObjAct.equals(numberObjExp)).isFalse();
assertThat(stringAct == stringExp).isNotEqualTo(false);
assertThat(stringAct.equals(stringExp)).isEqualTo(true);
assertThat(stringAct != stringExp).isFalse();
assertThat(stringAct == null).isNotEqualTo(true);
assertThat(null == stringAct).isEqualTo(false);
assertThat(null == null).isTrue();
assertThat(!false).isTrue();
}
private void stringStuff() {
String foo = "bar"; String foo = "bar";
assertThat(foo).isEqualTo(""); assertThat(foo).isEqualTo("");
assertThat(foo).hasSize(0); assertThat(foo).hasSize(0);
assertThat(foo.contains("foobar")).isTrue();
assertThat(foo).contains("foobar");
assertThat(foo.startsWith("foobar")).isTrue();
assertThat(foo).startsWith("foobar");
assertThat(foo.endsWith("foobar")).isTrue();
assertThat(foo).endsWith("foobar");
assertThat(foo.equalsIgnoreCase("foo")).isTrue();
assertThat(foo).isEqualToIgnoringCase("foo");
assertThat(foo.contains("foobar")).isFalse();
assertThat(foo).doesNotContain("foobar");
assertThat(foo.startsWith("foobar")).isFalse();
assertThat(foo).doesNotStartWith("foobar");
assertThat(foo.endsWith("foobar")).isFalse();
assertThat(foo).doesNotEndWith("foobar");
assertThat(foo.equalsIgnoreCase("foo")).isFalse();
assertThat(foo).isNotEqualToIgnoringCase("foo");
ArrayList<String> list = new ArrayList<>();
long[] otherArray = new long[4];
String string = "string";
assertThat(string.length()).isEqualTo(0);
assertThat(string.length()).isZero();
assertThat(string.length()).isNotZero();
assertThat(string.length()).as("hi").isGreaterThan(0);
assertThat(string.length()).isGreaterThanOrEqualTo(1);
assertThat(string.length()).isLessThan(1);
assertThat(string.length()).isLessThanOrEqualTo(0);
assertThat(string.length()).isEqualTo(list.size());
assertThat(string.length()).isEqualTo(otherArray.length);
assertThat(string.length()).isEqualTo(1);
assertThat(string.length()).isGreaterThan(otherArray.length - 1);
assertThat(string.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
assertThat(string.length()).isLessThan(otherArray.length - 3);
assertThat(string.length()).isLessThanOrEqualTo(1 - otherArray.length);
StringBuilder stringBuilder = new StringBuilder();
assertThat(stringBuilder.length()).isEqualTo(0);
assertThat(stringBuilder.length()).isZero();
assertThat(stringBuilder.length()).isNotZero();
assertThat(stringBuilder.length()).as("hi").isGreaterThan(0);
assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(1);
assertThat(stringBuilder.length()).isLessThan(1);
assertThat(stringBuilder.length()).isLessThanOrEqualTo(0);
assertThat(stringBuilder.length()).isEqualTo(list.size());
assertThat(stringBuilder.length()).isEqualTo(otherArray.length);
assertThat(stringBuilder.length()).isEqualTo(1);
assertThat(stringBuilder.length()).isGreaterThan(otherArray.length - 1);
assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
assertThat(stringBuilder.length()).isLessThan(otherArray.length - 3);
assertThat(stringBuilder.length()).isLessThanOrEqualTo(1 - otherArray.length);
}
private void java8Optional() {
Optional<String> opt = Optional.empty();
assertThat(opt.isPresent()).isEqualTo(true);
assertThat(opt.isPresent()).isEqualTo(Boolean.TRUE);
assertThat(opt.isPresent()).isNotEqualTo(false);
assertThat(opt.isPresent()).isNotEqualTo(Boolean.FALSE);
assertThat(opt.isPresent()).isTrue();
assertThat(opt.isPresent()).isEqualTo(false);
assertThat(opt.isPresent()).isEqualTo(Boolean.FALSE);
assertThat(opt.isPresent()).isNotEqualTo(true);
assertThat(opt.isPresent()).isNotEqualTo(Boolean.TRUE);
assertThat(opt.isPresent()).isFalse();
assertThat(opt.get()).isEqualTo("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt).isEqualTo(Optional.of("foo"));
assertThat(opt).isEqualTo(Optional.ofNullable("foo"));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.ofNullable("foo"));
assertThat(opt).isEqualTo(Optional.empty());
assertThat(opt).isNotEqualTo(Optional.empty());
assertThat(opt).isPresent();
}
private void assertThatGuavaOptional() {
com.google.common.base.Optional<String> opt = com.google.common.base.Optional.absent();
assertThat(opt.isPresent()).isEqualTo(true);
assertThat(opt.isPresent()).isEqualTo(Boolean.TRUE);
assertThat(opt.isPresent()).isNotEqualTo(false);
assertThat(opt.isPresent()).isNotEqualTo(Boolean.FALSE);
assertThat(opt.isPresent()).isTrue();
assertThat(opt.isPresent()).isEqualTo(false);
assertThat(opt.isPresent()).isEqualTo(Boolean.FALSE);
assertThat(opt.isPresent()).isNotEqualTo(true);
assertThat(opt.isPresent()).isNotEqualTo(Boolean.TRUE);
assertThat(opt.isPresent()).isFalse();
assertThat(opt.get()).isEqualTo("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).isEqualTo(com.google.common.base.Optional.of("foo"));
assertThat(opt).isEqualTo(com.google.common.base.Optional.fromNullable("foo"));
assertThat(opt).isNotEqualTo(com.google.common.base.Optional.of("foo"));
assertThat(opt).isNotEqualTo(com.google.common.base.Optional.fromNullable("foo"));
assertThat(opt).isEqualTo(com.google.common.base.Optional.absent());
assertThat(opt).isNotEqualTo(com.google.common.base.Optional.absent());
assertThat(opt).isAbsent();
}
private void assertThatInstance() {
String foo = "foo";
assertThat(foo instanceof String).isTrue();
assertThat(foo).isInstanceOf(String.class);
assertThat(foo).isNotInstanceOf(String.class);
} }
private void junitAssertions() { private void junitAssertions() {
assertFalse(!(new int[3].length == new ArrayList<Integer>().size()));
assertThat(!(new int[3].length == new ArrayList<Integer>().size())).isFalse();
assertThat((new int[3].length == new ArrayList<Integer>().size())).isTrue();
assertThat(new int[3].length).isEqualTo(new ArrayList<Integer>().size());
assertThat(new int[3]).hasSameSizeAs(new ArrayList<Integer>());
assertTrue(true); assertTrue(true);
assertTrue("message", true); assertTrue("message", true);
assertFalse(true); assertFalse(true);
@@ -111,13 +321,9 @@ public class Playground {
assertNotSame(bar, foo); assertNotSame(bar, foo);
assertNotSame("same", bar, foo); assertNotSame("same", bar, foo);
assertEquals(1.0, 2.0);
assertEquals(1.0, 2.0, 0.1); assertEquals(1.0, 2.0, 0.1);
assertEquals("equals", 1.0, 2.0);
assertEquals("equals", 1.0, 2.0, 0.1); assertEquals("equals", 1.0, 2.0, 0.1);
assertEquals(1.0f, 2.0f);
assertEquals(1.0f, 2.0f, 0.1f); assertEquals(1.0f, 2.0f, 0.1f);
assertEquals("equals", 1.0f, 2.0f);
assertEquals("equals", 1.0f, 2.0f, 0.1f); assertEquals("equals", 1.0f, 2.0f, 0.1f);
assertNotEquals(1.0, 2.0); assertNotEquals(1.0, 2.0);
@@ -183,6 +389,60 @@ public class Playground {
assertThat(new double[1]).as("array equals").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]).containsExactly(new float[2], offset(1.0f));
assertThat(new float[1]).as("array equals").containsExactly(new float[2], offset(1.0f)); assertThat(new float[1]).as("array equals").containsExactly(new float[2], offset(1.0f));
assertThat(new Object()).extracting("toString");
assertThat(new Object()).extracting(Object::toString, Object::hashCode);
} }
private void findReferences() {
Contact contact = new Contact();
List<Contact> contactList = Collections.emptyList();
assertThat(contact).extracting("name").isEqualTo("foo");
assertThat(contact).extracting("age", "country", "address.street", "street", "address.noMailings", "address.REALLYnoMAILINGS").containsExactly(1, "Elmst. 42");
assertThat(contact).extracting(Extractors.byName("name")).isEqualTo("foo");
assertThat(contact).extracting(Extractors.resultOf("getStreet")).isEqualTo("foo");
assertThat(contact).extracting(Extractors.resultOf("getStreet"), Extractors.byName("narf")).isEqualTo("foo");
assertThat(contactList).extracting("name").isEqualTo("foo");
assertThat(contactList).extracting("name", "moar").isEqualTo("foo");
assertThat(contactList).extracting("name", String.class).isEqualTo("foo");
assertThat(contactList).extracting(Extractors.byName("name")).isEqualTo("foo");
assertThat(contactList).extracting(Extractors.resultOf("getStreet"), Extractors.byName("narf")).isEqualTo("foo");
assertThat(contactList).extractingResultOf("getStreet").isEqualTo("foo");
assertThat(contactList).extractingResultOf("getStreet", String.class).isEqualTo("foo");
assertThat(contactList).flatExtracting("age", "address.street", "street").containsExactly(1, "Elmst. 42");
assertThat(contactList).flatExtracting("age").containsExactly(1, "Elmst. 42");
}
public class Contact {
private String name;
private Integer age;
private Address address;
public String getStreet() {
return address.getStreet();
}
}
public class Address {
private String street;
private String country;
public String getStreet() {
return street;
}
public String getCountry() {
return country;
}
public boolean isNoMailings() {
return true;
}
public Boolean getREALLYnoMAILINGS() {
return true;
}
}
} }
@@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException
@AddLocalJarToModule(Assertions::class) @AddLocalJarToModule(Assertions::class)
abstract class AbstractCajonTest { abstract class AbstractCajonTest {
// See https://github.com/junit-team/junit5/issues/157 // See https://github.com/junit-team/junit5/issues/157, should be resolved with junit5 5.5 M2
protected fun runTest(body: () -> Unit) { protected fun runTest(body: () -> Unit) {
val throwables = arrayOfNulls<Throwable>(1) val throwables = arrayOfNulls<Throwable>(1)
@@ -61,7 +61,7 @@ abstract class AbstractCajonTest {
protected fun executeQuickFixes(myFixture: JavaCodeInsightTestFixture, regex: Regex, expectedFixes: Int) { protected fun executeQuickFixes(myFixture: JavaCodeInsightTestFixture, regex: Regex, expectedFixes: Int) {
val quickfixes = myFixture.getAllQuickFixes().filter { it.familyName.matches(regex) } val quickfixes = myFixture.getAllQuickFixes().filter { it.familyName.matches(regex) }
assertThat(quickfixes).hasSize(expectedFixes) assertThat(quickfixes).`as`("Fixes matched by $regex: ${myFixture.getAllQuickFixes().map { it.familyName }}").hasSize(expectedFixes)
quickfixes.forEach(myFixture::launchAction) quickfixes.forEach(myFixture::launchAction)
} }
} }
@@ -0,0 +1,22 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class AssertThatBinaryExpressionInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/BinaryExpression")
internal fun assertThat_of_binary_expression_can_be_moved_out(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatBinaryExpressionInspection::class.java)
myFixture.configureByFile("BinaryExpressionBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Split binary expression out of assertThat()"), 148)
executeQuickFixes(myFixture, Regex.fromLiteral("Split equals() expression out of assertThat()"), 12)
myFixture.checkResultByFile("BinaryExpressionAfter.java")
}
}
}
@@ -0,0 +1,24 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class AssertThatBooleanConditionInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/BooleanCondition")
internal fun assertThat_with_isEqualTo_true_or_false_can_use_isTrue_or_isFalse(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatBooleanConditionInspection::class.java)
myFixture.configureByFile("BooleanConditionBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isTrue()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isFalse()"), 5)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isTrue()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isFalse()"), 4)
myFixture.checkResultByFile("BooleanConditionAfter.java")
}
}
}
@@ -1,21 +0,0 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class AssertThatBooleanIsTrueOrFalseInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/BooleanIsTrueOrFalse")
internal fun assertThat_with_isEqualTo_true_or_false_can_use_isTrue_or_isFalse(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatBooleanIsTrueOrFalseInspection::class.java)
myFixture.configureByFile("BooleanIsTrueOrFalseBefore.java")
executeQuickFixes(myFixture, Regex("Replace is.*"), 17)
myFixture.checkResultByFile("BooleanIsTrueOrFalseAfter.java")
}
}
}
@@ -14,7 +14,7 @@ internal class AssertThatEnumerableIsEmptyInspectionTest : AbstractCajonTest() {
runTest { runTest {
myFixture.enableInspections(AssertThatEnumerableIsEmptyInspection::class.java) myFixture.enableInspections(AssertThatEnumerableIsEmptyInspection::class.java)
myFixture.configureByFile("EnumerableIsEmptyBefore.java") myFixture.configureByFile("EnumerableIsEmptyBefore.java")
executeQuickFixes(myFixture, Regex("Replace hasSize.*"), 4) executeQuickFixes(myFixture, Regex.fromLiteral("Replace hasSize() with isEmpty()"), 4)
myFixture.checkResultByFile("EnumerableIsEmptyAfter.java") myFixture.checkResultByFile("EnumerableIsEmptyAfter.java")
} }
} }
@@ -0,0 +1,57 @@
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(com.google.common.base.Optional::class, org.assertj.guava.api.Assertions::class, Assertions::class)
@TestDataSubPath("inspections/GuavaOptional")
internal class AssertThatGuavaOptionalInspectionTest : AbstractCajonTest() {
@Test
internal fun assertThat_get_or_isPresent_for_Guava_Optional_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
myFixture.configureByFile("GuavaOptionalBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with Guava assertThat().isPresent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with Guava assertThat().isPresent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with Guava assertThat().isPresent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with Guava assertThat().isAbsent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isAbsent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with Guava assertThat().isAbsent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with Guava assertThat().isAbsent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isTrue() with Guava assertThat().isPresent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isFalse() with Guava assertThat().isAbsent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with Guava assertThat().contains()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove unwrapping of expected expression and replace isEqualTo() with contains()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove unwrapping of expected expression and replace isEqualTo() with Guava assertThat().contains()"), 2)
myFixture.checkResultByFile("GuavaOptionalAfter.java")
}
}
@Test
internal fun adds_missing_Guava_import_any_order(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
myFixture.configureByFile("WithoutPriorGuavaImportBefore.java")
executeQuickFixes(myFixture, Regex(".*eplace .* with .*"), 7)
myFixture.checkResultByFile("WithoutPriorGuavaImportAfter.java")
}
}
@Test
internal fun adds_missing_Guava_import_isAbsent_first(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatGuavaOptionalInspection::class.java)
myFixture.configureByFile("WithoutPriorGuavaImportBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with Guava assertThat().isAbsent()"), 1)
executeQuickFixes(myFixture, Regex(".*eplace .* with .*"), 6)
myFixture.checkResultByFile("WithoutPriorGuavaImportAfter.java")
}
}
}
@@ -0,0 +1,22 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class AssertThatInstanceOfInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/InstanceOf")
internal fun assertThat_with_instanceof_can_be_moved_out(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatInstanceOfInspection::class.java)
myFixture.configureByFile("InstanceOfBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Replace instanceof expression by assertThat().isInstanceOf()"), 5)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace instanceof expression by assertThat().isNotInstanceOf()"), 6)
myFixture.checkResultByFile("InstanceOfAfter.java")
}
}
}
@@ -0,0 +1,21 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class AssertThatInvertedBooleanConditionInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/InvertedBooleanCondition")
internal fun assertThat_with_inverted_boolean_condition_can_be_inverted(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatInvertedBooleanConditionInspection::class.java)
myFixture.configureByFile("InvertedBooleanConditionBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Invert condition in assertThat()"), 21)
myFixture.checkResultByFile("InvertedBooleanConditionAfter.java")
}
}
}
@@ -0,0 +1,31 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class AssertThatJava8OptionalInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/Java8Optional")
internal fun assertThat_get_or_isPresent_for_Java8_Optional_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatJava8OptionalInspection::class.java)
myFixture.configureByFile("Java8OptionalBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with isPresent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with isPresent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with isNotPresent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isNotEqualTo() with isNotPresent()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isTrue() with isPresent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isNotPresent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isPresent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isFalse() with isNotPresent()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove unwrapping of expected expression and replace isEqualTo() with contains()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isEqualTo() with contains()"), 1)
executeQuickFixes(myFixture, Regex.fromLiteral("Unwrap actual expression and replace isSameAs() with containsSame()"), 1)
myFixture.checkResultByFile("Java8OptionalAfter.java")
}
}
}
@@ -1,21 +0,0 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class AssertThatObjectIsNotNullInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/ObjectIsNotNull")
internal fun assertThat_with_isNotEqualTo_null_can_use_isNotNull(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatObjectIsNotNullInspection::class.java)
myFixture.configureByFile("ObjectIsNotNullBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isNotNull()"), 3)
myFixture.checkResultByFile("ObjectIsNotNullAfter.java")
}
}
}
@@ -6,16 +6,17 @@ import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
internal class AssertThatObjectIsNullInspectionTest : AbstractCajonTest() { internal class AssertThatObjectIsNullOrNotNullInspectionTest : AbstractCajonTest() {
@Test @Test
@TestDataSubPath("inspections/ObjectIsNull") @TestDataSubPath("inspections/ObjectIsNullOrNotNull")
internal fun assertThat_with_isEqualTo_null_can_use_isNull(@MyFixture myFixture: JavaCodeInsightTestFixture) { internal fun assertThat_with_isEqualTo_null_can_use_isNull(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest { runTest {
myFixture.enableInspections(AssertThatObjectIsNullInspection::class.java) myFixture.enableInspections(AssertThatObjectIsNullOrNotNullInspection::class.java)
myFixture.configureByFile("ObjectIsNullBefore.java") myFixture.configureByFile("ObjectIsNullOrNotNullBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isNull()"), 3) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isNull()"), 3)
myFixture.checkResultByFile("ObjectIsNullAfter.java") executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotEqualTo() with isNotNull()"), 3)
myFixture.checkResultByFile("ObjectIsNullOrNotNullAfter.java")
} }
} }
} }
@@ -9,13 +9,26 @@ import org.junit.jupiter.api.Test
internal class AssertThatSizeInspectionTest : AbstractCajonTest() { internal class AssertThatSizeInspectionTest : AbstractCajonTest() {
@Test @Test
@TestDataSubPath("inspections/AssertThatSize") @TestDataSubPath("inspections/Size")
internal fun assertThat_size_of_array_or_collection_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) { internal fun assertThat_size_of_array_or_collection_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest { runTest {
myFixture.enableInspections(AssertThatSizeInspection::class.java) myFixture.enableInspections(AssertThatSizeInspection::class.java)
myFixture.configureByFile("AssertThatSizeBefore.java") myFixture.configureByFile("SizeBefore.java")
executeQuickFixes(myFixture, Regex("Replace .*"), 20) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isEmpty()"), 4)
myFixture.checkResultByFile("AssertThatSizeAfter.java") executeQuickFixes(myFixture, Regex.fromLiteral("Replace isZero() with isEmpty()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isNotZero() with isNotEmpty()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isGreaterThan() with isNotEmpty()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isGreaterThanOrEqualTo() with isNotEmpty()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThan() with isEmpty()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThanOrEqualTo() with isEmpty()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with hasSameSizeAs()"), 12)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with hasSize()"), 8)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isGreaterThan() with hasSizeGreaterThan()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isGreaterThanOrEqualTo() with hasSizeGreaterThanOrEqualTo()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThan() with hasSizeLessThan()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace isLessThanOrEqualTo() with hasSizeLessThanOrEqualTo()"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove size determination of expected expression and replace hasSize() with hasSameSizeAs()"), 12)
myFixture.checkResultByFile("SizeAfter.java")
} }
} }
} }
@@ -0,0 +1,34 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class AssertThatStringExpressionInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/StringExpression")
internal fun assertThat_with_certain_String_methods(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(AssertThatStringExpressionInspection::class.java)
myFixture.configureByFile("StringExpressionBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Remove isEmpty() of expected expression and use assertThat().isEmpty() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove equals() of expected expression and use assertThat().isEqualTo() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove equalsIgnoreCase() of expected expression and use assertThat().isEqualToIgnoringCase() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove contentEquals() of expected expression and use assertThat().isEqualTo() instead"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove contains() of expected expression and use assertThat().contains() instead"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove startsWith() of expected expression and use assertThat().startsWith() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove endsWith() of expected expression and use assertThat().endsWith() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove isEmpty() of expected expression and use assertThat().isNotEmpty() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove equals() of expected expression and use assertThat().isNotEqualTo() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove equalsIgnoreCase() of expected expression and use assertThat().isNotEqualToIgnoringCase() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove contentEquals() of expected expression and use assertThat().isNotEqualTo() instead"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove contains() of expected expression and use assertThat().doesNotContain() instead"), 4)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove startsWith() of expected expression and use assertThat().doesNotStartWith() instead"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Remove endsWith() of expected expression and use assertThat().doesNotEndWith() instead"), 2)
myFixture.checkResultByFile("StringExpressionAfter.java")
}
}
}
@@ -14,7 +14,8 @@ internal class AssertThatStringIsEmptyInspectionTest : AbstractCajonTest() {
runTest { runTest {
myFixture.enableInspections(AssertThatStringIsEmptyInspection::class.java) myFixture.enableInspections(AssertThatStringIsEmptyInspection::class.java)
myFixture.configureByFile("StringIsEmptyBefore.java") myFixture.configureByFile("StringIsEmptyBefore.java")
executeQuickFixes(myFixture, Regex("Replace .*"), 4) executeQuickFixes(myFixture, Regex.fromLiteral("Replace isEqualTo() with isEmpty()"), 2)
executeQuickFixes(myFixture, Regex.fromLiteral("Replace hasSize() with isEmpty()"), 2)
myFixture.checkResultByFile("StringIsEmptyAfter.java") myFixture.checkResultByFile("StringIsEmptyAfter.java")
} }
} }
@@ -0,0 +1,21 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.junit.jupiter.api.Test
internal class JoinAssertThatStatementsInspectionTest : AbstractCajonTest() {
@Test
@TestDataSubPath("inspections/JoinStatements")
internal fun assertThat_size_of_array_or_collection_can_be_simplified(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.enableInspections(JoinAssertThatStatementsInspection::class.java)
myFixture.configureByFile("JoinStatementsBefore.java")
executeQuickFixes(myFixture, Regex.fromLiteral("Join assertThat() statements"), 6)
myFixture.checkResultByFile("JoinStatementsAfter.java")
}
}
}
@@ -0,0 +1,93 @@
package de.platon42.intellij.plugins.cajon.references
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import de.platon42.intellij.jupiter.MyFixture
import de.platon42.intellij.jupiter.TestDataSubPath
import de.platon42.intellij.plugins.cajon.AbstractCajonTest
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
@TestDataSubPath("references")
internal class ExtractorReferenceContributorTest : AbstractCajonTest() {
@Test
internal fun extractor_is_able_to_find_reference_for_field_extracting(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference1.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).isEqualTo("private String name;")
}
}
@Test
internal fun extractor_is_able_to_find_reference_for_first_part_of_a_path(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference2.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).isEqualTo("protected Address address;")
}
}
@Test
internal fun extractor_is_able_to_find_reference_for_second_part_of_a_path_and_both_getter_and_field(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference3.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).startsWith("private String street;")
}
}
@Test
internal fun extractor_is_able_to_find_reference_on_a_bare_method_call(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference4.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).startsWith("public Boolean getREALLYnoMAILINGS()")
}
}
@Test
internal fun extractor_is_able_to_find_reference_with_only_Getter_on_second_part(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference5.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).startsWith("public boolean isNoMailings()")
}
}
@Test
internal fun extractor_is_able_to_find_reference_using_byName_extractor(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference6.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).isEqualTo("private String name;")
}
}
@Test
internal fun extractor_is_able_to_find_reference_using_resultOf_extractor(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference7.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).startsWith("public String getStreetName()")
}
}
@Test
internal fun extractor_is_able_to_find_reference_for_field_extraction_on_list(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference8.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).isEqualTo("private String name;")
}
}
@Test
internal fun extractor_is_able_to_find_reference_for_field_flat_extraction_of_path_on_list(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference9.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).startsWith("private String street;")
}
}
@Test
internal fun extractor_is_able_to_find_reference_for_extraction_on_result_of_method(@MyFixture myFixture: JavaCodeInsightTestFixture) {
runTest {
myFixture.configureByFiles("FindReference10.java", "Address.java", "Contact.java")
assertThat(myFixture.elementAtCaret.text).startsWith("public String getStreetName()")
}
}
}
@@ -1,35 +0,0 @@
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
public class assertThatSize {
private void assertThatSize() {
ArrayList<String> list = new ArrayList<>();
ArrayList<String> otherList = new ArrayList<>();
long[] array = new long[5];
long[] otherArray = new long[4];
assertThat(list).isEmpty();
assertThat(list).isEmpty();
assertThat(list).isNotEmpty();
assertThat(list).as("hi").isNotEmpty();
assertThat(list).isNotEmpty();
assertThat(list).isEmpty();
assertThat(list).isEmpty();
assertThat(list).hasSameSizeAs(otherList);
assertThat(list).hasSameSizeAs(array);
assertThat(list).hasSize(1);
assertThat(array).isEmpty();
assertThat(array).isEmpty();
assertThat(array).isNotEmpty();
assertThat(array).as("hi").isNotEmpty();
assertThat(array).isNotEmpty();
assertThat(array).isEmpty();
assertThat(array).isEmpty();
assertThat(array).hasSameSizeAs(list);
assertThat(array).hasSameSizeAs(otherArray);
assertThat(array).hasSize(1);
}
}
@@ -1,35 +0,0 @@
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
public class assertThatSize {
private void assertThatSize() {
ArrayList<String> list = new ArrayList<>();
ArrayList<String> otherList = new ArrayList<>();
long[] array = new long[5];
long[] otherArray = new long[4];
assertThat(list.size()).isEqualTo(0);
assertThat(list.size()).isZero();
assertThat(list.size()).isNotZero();
assertThat(list.size()).as("hi").isGreaterThan(0);
assertThat(list.size()).isGreaterThanOrEqualTo(1);
assertThat(list.size()).isLessThan(1);
assertThat(list.size()).isLessThanOrEqualTo(0);
assertThat(list.size()).isEqualTo(otherList.size());
assertThat(list.size()).isEqualTo(array.length);
assertThat(list.size()).isEqualTo(1);
assertThat(array.length).isEqualTo(0);
assertThat(array.length).isZero();
assertThat(array.length).isNotZero();
assertThat(array.length).as("hi").isGreaterThan(0);
assertThat(array.length).isGreaterThanOrEqualTo(1);
assertThat(array.length).isLessThan(1);
assertThat(array.length).isLessThanOrEqualTo(0);
assertThat(array.length).isEqualTo(list.size());
assertThat(array.length).isEqualTo(otherArray.length);
assertThat(array.length).isEqualTo(1);
}
}
@@ -0,0 +1,194 @@
import static org.assertj.core.api.Assertions.assertThat;
public class BinaryExpression {
private void binaryExpression() {
int primExp = 42;
int primAct = 1337;
Double numberObjExp = 42.0;
Double numberObjAct = 1337.0;
String stringExp = "foo";
String stringAct = "bar";
assertThat(primAct).isEqualTo(primExp);
assertThat(primAct).isEqualTo(primExp);
assertThat(primAct).isEqualTo(primExp);
assertThat(primAct).isEqualTo(primExp);
assertThat(primAct).isEqualTo(primExp);
assertThat(primAct).isEqualTo(1);
assertThat(primAct).isEqualTo(1);
assertThat(primAct).isNotEqualTo(primExp);
assertThat(primAct).isNotEqualTo(primExp);
assertThat(primAct).isNotEqualTo(primExp);
assertThat(primAct).isNotEqualTo(primExp);
assertThat(primAct).isNotEqualTo(primExp);
assertThat(primAct).isNotEqualTo(1);
assertThat(primAct).isNotEqualTo(1);
assertThat(primAct).isNotEqualTo(primExp);
assertThat(primAct).isNotEqualTo(primExp);
assertThat(primAct).isNotEqualTo(primExp);
assertThat(primAct).isNotEqualTo(1);
assertThat(primAct).isNotEqualTo(1);
assertThat(primAct).isEqualTo(primExp);
assertThat(primAct).isEqualTo(primExp);
assertThat(primAct).isEqualTo(primExp);
assertThat(primAct).isEqualTo(1);
assertThat(primAct).isEqualTo(1);
assertThat(primAct).isGreaterThan(primExp);
assertThat(primAct).isGreaterThan(primExp);
assertThat(primAct).isGreaterThan(primExp);
assertThat(primAct).isGreaterThan(1);
assertThat(primAct).isGreaterThan(1);
assertThat(primAct).isLessThanOrEqualTo(primExp);
assertThat(primAct).isLessThanOrEqualTo(primExp);
assertThat(primAct).isLessThanOrEqualTo(primExp);
assertThat(primAct).isLessThanOrEqualTo(1);
assertThat(primAct).isLessThanOrEqualTo(1);
assertThat(primAct).isGreaterThanOrEqualTo(primExp);
assertThat(primAct).isGreaterThanOrEqualTo(primExp);
assertThat(primAct).isGreaterThanOrEqualTo(primExp);
assertThat(primAct).isGreaterThanOrEqualTo(1);
assertThat(primAct).isGreaterThanOrEqualTo(1);
assertThat(primAct).isLessThan(primExp);
assertThat(primAct).isLessThan(primExp);
assertThat(primAct).isLessThan(primExp);
assertThat(primAct).isLessThan(1);
assertThat(primAct).isLessThan(1);
assertThat(primAct).isLessThan(primExp);
assertThat(primAct).isLessThan(primExp);
assertThat(primAct).isLessThan(primExp);
assertThat(primAct).isLessThan(1);
assertThat(primAct).isLessThan(1);
assertThat(primAct).isGreaterThanOrEqualTo(primExp);
assertThat(primAct).isGreaterThanOrEqualTo(primExp);
assertThat(primAct).isGreaterThanOrEqualTo(primExp);
assertThat(primAct).isGreaterThanOrEqualTo(1);
assertThat(primAct).isGreaterThanOrEqualTo(1);
assertThat(primAct).isLessThanOrEqualTo(primExp);
assertThat(primAct).isLessThanOrEqualTo(primExp);
assertThat(primAct).isLessThanOrEqualTo(primExp);
assertThat(primAct).isLessThanOrEqualTo(1);
assertThat(primAct).isLessThanOrEqualTo(1);
assertThat(primAct).isGreaterThan(primExp);
assertThat(primAct).isGreaterThan(primExp);
assertThat(primAct).isGreaterThan(primExp);
assertThat(primAct).isGreaterThan(1);
assertThat(primAct).isGreaterThan(1);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isEqualTo(1);
assertThat(numberObjAct).isEqualTo(1);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(1);
assertThat(numberObjAct).isNotEqualTo(1);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(1);
assertThat(numberObjAct).isNotEqualTo(1);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isEqualTo(1);
assertThat(numberObjAct).isEqualTo(1);
assertThat(numberObjAct).isGreaterThan(numberObjExp);
assertThat(numberObjAct).isGreaterThan(numberObjExp);
assertThat(numberObjAct).isGreaterThan(numberObjExp);
assertThat(numberObjAct).isGreaterThan(1);
assertThat(numberObjAct).isGreaterThan(1);
assertThat(numberObjAct).isLessThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isLessThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isLessThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isLessThanOrEqualTo(1);
assertThat(numberObjAct).isLessThanOrEqualTo(1);
assertThat(numberObjAct).isGreaterThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isGreaterThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isGreaterThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isGreaterThanOrEqualTo(1);
assertThat(numberObjAct).isGreaterThanOrEqualTo(1);
assertThat(numberObjAct).isLessThan(numberObjExp);
assertThat(numberObjAct).isLessThan(numberObjExp);
assertThat(numberObjAct).isLessThan(numberObjExp);
assertThat(numberObjAct).isLessThan(1);
assertThat(numberObjAct).isLessThan(1);
assertThat(numberObjAct).isLessThan(numberObjExp);
assertThat(numberObjAct).isLessThan(numberObjExp);
assertThat(numberObjAct).isLessThan(numberObjExp);
assertThat(numberObjAct).isLessThan(1);
assertThat(numberObjAct).isLessThan(1);
assertThat(numberObjAct).isGreaterThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isGreaterThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isGreaterThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isGreaterThanOrEqualTo(1);
assertThat(numberObjAct).isGreaterThanOrEqualTo(1);
assertThat(numberObjAct).isLessThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isLessThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isLessThanOrEqualTo(numberObjExp);
assertThat(numberObjAct).isLessThanOrEqualTo(1);
assertThat(numberObjAct).isLessThanOrEqualTo(1);
assertThat(numberObjAct).isGreaterThan(numberObjExp);
assertThat(numberObjAct).isGreaterThan(numberObjExp);
assertThat(numberObjAct).isGreaterThan(numberObjExp);
assertThat(numberObjAct).isGreaterThan(1);
assertThat(numberObjAct).isGreaterThan(1);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(numberObjAct).isNotEqualTo(numberObjExp);
assertThat(stringAct).isSameAs(stringExp);
assertThat(stringAct).isSameAs(stringExp);
assertThat(stringAct).isSameAs(stringExp);
assertThat(stringAct).isNotSameAs(stringExp);
assertThat(stringAct).isNotSameAs(stringExp);
assertThat(stringAct).isNotSameAs(stringExp);
assertThat(stringAct).isEqualTo(stringExp);
assertThat(stringAct).isEqualTo(stringExp);
assertThat(stringAct).isEqualTo(stringExp);
assertThat(stringAct).isNotEqualTo(stringExp);
assertThat(stringAct).isNotEqualTo(stringExp);
assertThat(stringAct).isNotEqualTo(stringExp);
assertThat(stringAct).isNotSameAs(stringExp);
assertThat(stringAct).isNotSameAs(stringExp);
assertThat(stringAct).isNotSameAs(stringExp);
assertThat(stringAct).isSameAs(stringExp);
assertThat(stringAct).isSameAs(stringExp);
assertThat(stringAct).isSameAs(stringExp);
assertThat(stringAct).isNull();
assertThat(stringAct).isNull();
assertThat(stringAct).isNull();
assertThat(stringAct).isNotNull();
assertThat(stringAct).isNotNull();
assertThat(stringAct).isNotNull();
assertThat(stringAct).isNull();
assertThat(stringAct).isNull();
assertThat(stringAct).isNull();
assertThat(stringAct).isNotNull();
assertThat(stringAct).isNotNull();
assertThat(stringAct).isNotNull();
assertThat(null == null).isTrue();
assertThat(!false).isTrue();
}
}
@@ -0,0 +1,194 @@
import static org.assertj.core.api.Assertions.assertThat;
public class BinaryExpression {
private void binaryExpression() {
int primExp = 42;
int primAct = 1337;
Double numberObjExp = 42.0;
Double numberObjAct = 1337.0;
String stringExp = "foo";
String stringAct = "bar";
assertThat(primAct == primExp).isTrue();
assertThat(primAct == primExp).isEqualTo(true);
assertThat(primAct == primExp).isEqualTo(Boolean.TRUE);
assertThat(primAct == primExp).isNotEqualTo(false);
assertThat(primAct == primExp).isNotEqualTo(Boolean.FALSE);
assertThat(primAct == 1).isTrue();
assertThat(1 == primAct).isTrue();
assertThat(primAct == primExp).isFalse();
assertThat(primAct == primExp).isEqualTo(false);
assertThat(primAct == primExp).isEqualTo(Boolean.FALSE);
assertThat(primAct == primExp).isNotEqualTo(true);
assertThat(primAct == primExp).isNotEqualTo(Boolean.TRUE);
assertThat(primAct == 1).isFalse();
assertThat(1 == primAct).isFalse();
assertThat(primAct != primExp).isTrue();
assertThat(primAct != primExp).isEqualTo(true);
assertThat(primAct != primExp).isNotEqualTo(false);
assertThat(primAct != 1).isTrue();
assertThat(1 != primAct).isTrue();
assertThat(primAct != primExp).isFalse();
assertThat(primAct != primExp).isEqualTo(false);
assertThat(primAct != primExp).isNotEqualTo(true);
assertThat(primAct != 1).isFalse();
assertThat(1 != primAct).isFalse();
assertThat(primAct > primExp).isTrue();
assertThat(primAct > primExp).isEqualTo(true);
assertThat(primAct > primExp).isNotEqualTo(false);
assertThat(primAct > 1).isTrue();
assertThat(1 < primAct).isTrue();
assertThat(primAct > primExp).isFalse();
assertThat(primAct > primExp).isEqualTo(false);
assertThat(primAct > primExp).isNotEqualTo(true);
assertThat(primAct > 1).isFalse();
assertThat(1 < primAct).isFalse();
assertThat(primAct >= primExp).isTrue();
assertThat(primAct >= primExp).isEqualTo(true);
assertThat(primAct >= primExp).isNotEqualTo(false);
assertThat(primAct >= 1).isTrue();
assertThat(1 <= primAct).isTrue();
assertThat(primAct >= primExp).isFalse();
assertThat(primAct >= primExp).isEqualTo(false);
assertThat(primAct >= primExp).isNotEqualTo(true);
assertThat(primAct >= 1).isFalse();
assertThat(1 <= primAct).isFalse();
assertThat(primAct < primExp).isTrue();
assertThat(primAct < primExp).isEqualTo(true);
assertThat(primAct < primExp).isNotEqualTo(false);
assertThat(primAct < 1).isTrue();
assertThat(1 > primAct).isTrue();
assertThat(primAct < primExp).isFalse();
assertThat(primAct < primExp).isEqualTo(false);
assertThat(primAct < primExp).isNotEqualTo(true);
assertThat(primAct < 1).isFalse();
assertThat(1 > primAct).isFalse();
assertThat(primAct <= primExp).isTrue();
assertThat(primAct <= primExp).isEqualTo(true);
assertThat(primAct <= primExp).isNotEqualTo(false);
assertThat(primAct <= 1).isTrue();
assertThat(1 >= primAct).isTrue();
assertThat(primAct <= primExp).isFalse();
assertThat(primAct <= primExp).isEqualTo(false);
assertThat(primAct <= primExp).isNotEqualTo(true);
assertThat(primAct <= 1).isFalse();
assertThat(1 >= primAct).isFalse();
assertThat(numberObjAct == numberObjExp).isTrue();
assertThat(numberObjAct == numberObjExp).isEqualTo(true);
assertThat(numberObjAct == numberObjExp).isNotEqualTo(false);
assertThat(numberObjAct == 1).isTrue();
assertThat(1 == numberObjAct).isTrue();
assertThat(numberObjAct == numberObjExp).isFalse();
assertThat(numberObjAct == numberObjExp).isEqualTo(false);
assertThat(numberObjAct == numberObjExp).isNotEqualTo(true);
assertThat(numberObjAct == 1).isFalse();
assertThat(1 == numberObjAct).isFalse();
assertThat(numberObjAct != numberObjExp).isTrue();
assertThat(numberObjAct != numberObjExp).isEqualTo(true);
assertThat(numberObjAct != numberObjExp).isNotEqualTo(false);
assertThat(numberObjAct != 1).isTrue();
assertThat(1 != numberObjAct).isTrue();
assertThat(numberObjAct != numberObjExp).isFalse();
assertThat(numberObjAct != numberObjExp).isEqualTo(false);
assertThat(numberObjAct != numberObjExp).isNotEqualTo(true);
assertThat(numberObjAct != 1).isFalse();
assertThat(1 != numberObjAct).isFalse();
assertThat(numberObjAct > numberObjExp).isTrue();
assertThat(numberObjAct > numberObjExp).isEqualTo(true);
assertThat(numberObjAct > numberObjExp).isNotEqualTo(false);
assertThat(numberObjAct > 1).isTrue();
assertThat(1 < numberObjAct).isTrue();
assertThat(numberObjAct > numberObjExp).isFalse();
assertThat(numberObjAct > numberObjExp).isEqualTo(false);
assertThat(numberObjAct > numberObjExp).isNotEqualTo(true);
assertThat(numberObjAct > 1).isFalse();
assertThat(1 < numberObjAct).isFalse();
assertThat(numberObjAct >= numberObjExp).isTrue();
assertThat(numberObjAct >= numberObjExp).isEqualTo(true);
assertThat(numberObjAct >= numberObjExp).isNotEqualTo(false);
assertThat(numberObjAct >= 1).isTrue();
assertThat(1 <= numberObjAct).isTrue();
assertThat(numberObjAct >= numberObjExp).isFalse();
assertThat(numberObjAct >= numberObjExp).isEqualTo(false);
assertThat(numberObjAct >= numberObjExp).isNotEqualTo(true);
assertThat(numberObjAct >= 1).isFalse();
assertThat(1 <= numberObjAct).isFalse();
assertThat(numberObjAct < numberObjExp).isTrue();
assertThat(numberObjAct < numberObjExp).isEqualTo(true);
assertThat(numberObjAct < numberObjExp).isNotEqualTo(false);
assertThat(numberObjAct < 1).isTrue();
assertThat(1 > numberObjAct).isTrue();
assertThat(numberObjAct < numberObjExp).isFalse();
assertThat(numberObjAct < numberObjExp).isEqualTo(false);
assertThat(numberObjAct < numberObjExp).isNotEqualTo(true);
assertThat(numberObjAct < 1).isFalse();
assertThat(1 > numberObjAct).isFalse();
assertThat(numberObjAct <= numberObjExp).isTrue();
assertThat(numberObjAct <= numberObjExp).isEqualTo(true);
assertThat(numberObjAct <= numberObjExp).isNotEqualTo(false);
assertThat(numberObjAct <= 1).isTrue();
assertThat(1 >= numberObjAct).isTrue();
assertThat(numberObjAct <= numberObjExp).isFalse();
assertThat(numberObjAct <= numberObjExp).isEqualTo(false);
assertThat(numberObjAct <= numberObjExp).isNotEqualTo(true);
assertThat(numberObjAct <= 1).isFalse();
assertThat(1 >= numberObjAct).isFalse();
assertThat(numberObjAct.equals(numberObjExp)).isTrue();
assertThat(numberObjAct.equals(numberObjExp)).isEqualTo(true);
assertThat(numberObjAct.equals(numberObjExp)).isNotEqualTo(false);
assertThat(numberObjAct.equals(numberObjExp)).isFalse();
assertThat(numberObjAct.equals(numberObjExp)).isEqualTo(false);
assertThat(numberObjAct.equals(numberObjExp)).isNotEqualTo(true);
assertThat(stringAct == stringExp).isTrue();
assertThat(stringAct == stringExp).isEqualTo(true);
assertThat(stringAct == stringExp).isNotEqualTo(false);
assertThat(stringAct == stringExp).isFalse();
assertThat(stringAct == stringExp).isEqualTo(false);
assertThat(stringAct == stringExp).isNotEqualTo(true);
assertThat(stringAct.equals(stringExp)).isTrue();
assertThat(stringAct.equals(stringExp)).isEqualTo(true);
assertThat(stringAct.equals(stringExp)).isNotEqualTo(false);
assertThat(stringAct.equals(stringExp)).isFalse();
assertThat(stringAct.equals(stringExp)).isEqualTo(false);
assertThat(stringAct.equals(stringExp)).isNotEqualTo(true);
assertThat(stringAct != stringExp).isTrue();
assertThat(stringAct != stringExp).isEqualTo(true);
assertThat(stringAct != stringExp).isNotEqualTo(false);
assertThat(stringAct != stringExp).isFalse();
assertThat(stringAct != stringExp).isEqualTo(false);
assertThat(stringAct != stringExp).isNotEqualTo(true);
assertThat(stringAct == null).isTrue();
assertThat(stringAct == null).isEqualTo(true);
assertThat(stringAct == null).isNotEqualTo(false);
assertThat(stringAct == null).isFalse();
assertThat(stringAct == null).isEqualTo(false);
assertThat(stringAct == null).isNotEqualTo(true);
assertThat(null == stringAct).isTrue();
assertThat(null == stringAct).isEqualTo(true);
assertThat(null == stringAct).isNotEqualTo(false);
assertThat(null == stringAct).isFalse();
assertThat(null == stringAct).isEqualTo(false);
assertThat(null == stringAct).isNotEqualTo(true);
assertThat(null == null).isTrue();
assertThat(!false).isTrue();
}
}
@@ -1,8 +1,8 @@
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public class BooleanIsTrueOrFalse { public class BooleanCondition {
private void booleanIsTrueOrFalse() { private void booleanCondition() {
boolean primitive = false; boolean primitive = false;
Boolean object = Boolean.TRUE; Boolean object = Boolean.TRUE;
@@ -1,8 +1,8 @@
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public class BooleanIsTrueOrFalse { public class BooleanCondition {
private void booleanIsTrueOrFalse() { private void booleanCondition() {
boolean primitive = false; boolean primitive = false;
Boolean object = Boolean.TRUE; Boolean object = Boolean.TRUE;
@@ -0,0 +1,52 @@
import com.google.common.base.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;
public class GuavaOptional {
private void guavaOptional() {
Optional<String> opt = Optional.absent();
assertThat(opt).isPresent();
assertThat(opt).isPresent();
assertThat(opt).isPresent();
assertThat(opt).isPresent();
assertThat(opt).isPresent();
assertThat(opt).isAbsent();
assertThat(opt).isAbsent();
assertThat(opt).isAbsent();
assertThat(opt).isAbsent();
assertThat(opt).isAbsent();
assertThat(opt).contains("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).contains("foo");
assertThat(opt).contains("foo");
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isAbsent();
assertThat(opt).isPresent();
org.assertj.guava.api.Assertions.assertThat(opt).contains("foo");
org.assertj.guava.api.Assertions.assertThat(opt).contains("foo");
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.of("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isAbsent();
org.assertj.guava.api.Assertions.assertThat(opt).isPresent();
assertThat(opt).contains("foo");
assertThat(opt).contains("foo");
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.of("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isAbsent();
assertThat(opt).isPresent();
}
}
@@ -0,0 +1,52 @@
import com.google.common.base.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;
public class GuavaOptional {
private void guavaOptional() {
Optional<String> opt = Optional.absent();
assertThat(opt.isPresent()).isEqualTo(true);
assertThat(opt.isPresent()).isEqualTo(Boolean.TRUE);
assertThat(opt.isPresent()).isNotEqualTo(false);
assertThat(opt.isPresent()).isNotEqualTo(Boolean.FALSE);
assertThat(opt.isPresent()).isTrue();
assertThat(opt.isPresent()).isEqualTo(false);
assertThat(opt.isPresent()).isEqualTo(Boolean.FALSE);
assertThat(opt.isPresent()).isNotEqualTo(true);
assertThat(opt.isPresent()).isNotEqualTo(Boolean.TRUE);
assertThat(opt.isPresent()).isFalse();
assertThat(opt.get()).isEqualTo("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).isEqualTo(Optional.of("foo"));
assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isEqualTo(Optional.absent());
assertThat(opt).isNotEqualTo(Optional.absent());
org.assertj.guava.api.Assertions.assertThat(opt).isEqualTo(Optional.of("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.of("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
org.assertj.guava.api.Assertions.assertThat(opt).isEqualTo(Optional.absent());
org.assertj.guava.api.Assertions.assertThat(opt).isNotEqualTo(Optional.absent());
org.assertj.core.api.Assertions.assertThat(opt).isEqualTo(Optional.of("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.of("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
org.assertj.core.api.Assertions.assertThat(opt).isEqualTo(Optional.absent());
org.assertj.core.api.Assertions.assertThat(opt).isNotEqualTo(Optional.absent());
}
}
@@ -0,0 +1,27 @@
import com.google.common.base.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;
public class GuavaOptional {
private void guavaOptional() {
Optional<String> opt = Optional.absent();
assertThat(opt).contains("foo");
assertThat(opt).contains("foo");
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isPresent();
assertThat(opt).isAbsent();
assertThat(opt).contains("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).isAbsent();
assertThat(opt).isPresent();
}
}
@@ -0,0 +1,26 @@
import com.google.common.base.Optional;
import static org.assertj.core.api.Assertions.assertThat;
public class GuavaOptional {
private void guavaOptional() {
Optional<String> opt = Optional.absent();
assertThat(opt).isEqualTo(Optional.of("foo"));
assertThat(opt).isEqualTo(Optional.fromNullable("foo"));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.fromNullable("foo"));
assertThat(opt.isPresent()).isTrue();
assertThat(opt.isPresent()).isFalse();
assertThat(opt.get()).isEqualTo("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).isEqualTo(Optional.absent());
assertThat(opt).isNotEqualTo(Optional.absent());
}
}
@@ -0,0 +1,22 @@
import static org.assertj.core.api.Assertions.assertThat;
public class InstanceOf {
private void instanceOf() {
Boolean object = Boolean.TRUE;
assertThat(object).isInstanceOf(Boolean.class);
assertThat(object).isInstanceOf(Boolean.class);
assertThat(object).isInstanceOf(Boolean.class);
assertThat(object).isInstanceOf(Boolean.class);
assertThat(object).isInstanceOf(Boolean.class);
assertThat(object).isNotInstanceOf(Boolean.class);
assertThat(object).isNotInstanceOf(Boolean.class);
assertThat(object).isNotInstanceOf(Boolean.class);
assertThat(object).isNotInstanceOf(Boolean.class);
assertThat(object).isNotInstanceOf(Boolean.class);
assertThat(object).as("nah").isNotInstanceOf(Boolean.class);
}
}
@@ -0,0 +1,22 @@
import static org.assertj.core.api.Assertions.assertThat;
public class InstanceOf {
private void instanceOf() {
Boolean object = Boolean.TRUE;
assertThat(object instanceof Boolean).isEqualTo(Boolean.TRUE);
assertThat(object instanceof Boolean).isEqualTo(true);
assertThat(object instanceof Boolean).isNotEqualTo(Boolean.FALSE);
assertThat(object instanceof Boolean).isNotEqualTo(false);
assertThat(object instanceof Boolean).isTrue();
assertThat(object instanceof Boolean).isEqualTo(Boolean.FALSE);
assertThat(object instanceof Boolean).isEqualTo(false);
assertThat(object instanceof Boolean).isNotEqualTo(Boolean.TRUE);
assertThat(object instanceof Boolean).isNotEqualTo(true);
assertThat(object instanceof Boolean).isFalse();
assertThat(((object)) instanceof Boolean).as("nah").isEqualTo(true && !true);
}
}
@@ -0,0 +1,34 @@
import static org.assertj.core.api.Assertions.assertThat;
public class InvertedBooleanCondition {
private void invertedBooleanCondition() {
boolean primitive = false;
Boolean object = Boolean.TRUE;
assertThat(primitive).isFalse();
assertThat(primitive).isFalse();
assertThat(primitive).isFalse();
assertThat(primitive).isFalse();
assertThat(primitive).isFalse();
assertThat(object).isFalse();
assertThat(object).isFalse();
assertThat(object).isFalse();
assertThat(object).isFalse();
assertThat(object).isFalse();
assertThat(primitive).isTrue();
assertThat(primitive).isTrue();
assertThat(primitive).isTrue();
assertThat(primitive).isTrue();
assertThat(primitive).isTrue();
assertThat(object).isTrue();
assertThat(object).isTrue();
assertThat(object).isTrue();
assertThat(object).isTrue();
assertThat(object).isTrue();
assertThat(!((primitive))).as("nah").isTrue();
assertThat(!object).isEqualTo(Boolean.TRUE && !Boolean.TRUE);
}
}
@@ -0,0 +1,34 @@
import static org.assertj.core.api.Assertions.assertThat;
public class InvertedBooleanCondition {
private void invertedBooleanCondition() {
boolean primitive = false;
Boolean object = Boolean.TRUE;
assertThat(!primitive).isEqualTo(Boolean.TRUE);
assertThat(!primitive).isEqualTo(true);
assertThat(!primitive).isNotEqualTo(Boolean.FALSE);
assertThat(!primitive).isNotEqualTo(false);
assertThat(!primitive).isTrue();
assertThat(!object).isEqualTo(Boolean.TRUE);
assertThat(!object).isEqualTo(true);
assertThat(!object).isNotEqualTo(Boolean.FALSE);
assertThat(!object).isNotEqualTo(false);
assertThat(!object).isTrue();
assertThat(!primitive).isEqualTo(Boolean.FALSE);
assertThat(!primitive).isEqualTo(false);
assertThat(!primitive).isNotEqualTo(Boolean.TRUE);
assertThat(!primitive).isNotEqualTo(true);
assertThat(!primitive).isFalse();
assertThat(!object).isEqualTo(Boolean.FALSE);
assertThat(!object).isEqualTo(false);
assertThat(!object).isNotEqualTo(Boolean.TRUE);
assertThat(!object).isNotEqualTo(true);
assertThat(!object).isFalse();
assertThat(!(((!((primitive)))))).as("nah").isEqualTo(true && !true);
assertThat(!object).isEqualTo(Boolean.TRUE && !Boolean.TRUE);
}
}
@@ -0,0 +1,35 @@
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
public class Java8Optional {
private void java8Optional() {
Optional<String> opt = Optional.empty();
assertThat(opt).isPresent();
assertThat(opt).isPresent();
assertThat(opt).isPresent();
assertThat(opt).isPresent();
assertThat(opt).isPresent();
assertThat(opt).isNotPresent();
assertThat(opt).isNotPresent();
assertThat(opt).isNotPresent();
assertThat(opt).isNotPresent();
assertThat(opt).isNotPresent();
assertThat(opt).contains("foo");
assertThat(opt).containsSame("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).contains("foo");
assertThat(opt).contains("foo");
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.ofNullable("foo"));
assertThat(opt).isNotPresent();
assertThat(opt).isPresent();
}
}
@@ -0,0 +1,35 @@
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
public class Java8Optional {
private void java8Optional() {
Optional<String> opt = Optional.empty();
assertThat(opt.isPresent()).isEqualTo(true);
assertThat(opt.isPresent()).isEqualTo(Boolean.TRUE);
assertThat(opt.isPresent()).isNotEqualTo(false);
assertThat(opt.isPresent()).isNotEqualTo(Boolean.FALSE);
assertThat(opt.isPresent()).isTrue();
assertThat(opt.isPresent()).isEqualTo(false);
assertThat(opt.isPresent()).isEqualTo(Boolean.FALSE);
assertThat(opt.isPresent()).isNotEqualTo(true);
assertThat(opt.isPresent()).isNotEqualTo(Boolean.TRUE);
assertThat(opt.isPresent()).isFalse();
assertThat(opt.get()).isEqualTo("foo");
assertThat(opt.get()).isSameAs("foo");
assertThat(opt.get()).isNotEqualTo("foo");
assertThat(opt.get()).isNotSameAs("foo");
assertThat(opt).isEqualTo(Optional.of("foo"));
assertThat(opt).isEqualTo(Optional.ofNullable("foo"));
assertThat(opt).isNotEqualTo(Optional.of("foo"));
assertThat(opt).isNotEqualTo(Optional.ofNullable("foo"));
assertThat(opt).isEqualTo(Optional.empty());
assertThat(opt).isNotEqualTo(Optional.empty());
}
}
@@ -0,0 +1,40 @@
import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
public class JoinStatements {
private void joinStatements() {
List<String> list = new ArrayList<>();
// the future is always born in pain
/* tricky */
assertThat(list).as("foo").hasSize(2)
/* do another */
/* do one */.as("bar").contains("barbar")
// comment to keep
.doesNotContain("barbara") // another comment to keep
.doesNotContain("wrzlbrmpft")
/* and a multi line comment
after the statement */
// across two lines
.as("etc")/* what a nasty comment */.contains("etcetc")
// moar!
.doesNotContain("foobar");
assertThat("narf").isNotEqualTo("puit").as("bar").contains("barbar").as("foo").hasSize(2);
assertThat(list).as("evil").extracting(String::length).contains(2);
assertThat(list).as("bar").contains("barbar");
assertThat("narf").isNotEqualTo("puit").as("foo").hasSize(2);
if (true) {
assertThat(list).doesNotContain("narf").as("bar").contains("barbar");
}
assertThat(list.get(0)).isNotEmpty().hasSize(3).isEqualTo("bar");
assertThat(list.get(0) + "foo").isEqualTo("bar").doesNotStartWith("foo");
Iterator<String> iterator = list.iterator();
assertThat(iterator.next()).isEqualTo("foo");
assertThat(iterator.next()).isEqualTo("bar");
}
}
@@ -0,0 +1,44 @@
import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
public class JoinStatements {
private void joinStatements() {
List<String> list = new ArrayList<>();
// the future is always born in pain
/* tricky */assertThat(list).as("foo").hasSize(2); /* do one */ /* do another */
assertThat(list).as("bar").contains("barbar"); // comment to keep
assertThat(list).doesNotContain("barbara") // another comment to keep
.doesNotContain("wrzlbrmpft") // across two lines
; /* and a multi line comment
after the statement */
assertThat(list).as("etc")/* what a nasty comment */.contains("etcetc");
// moar!
assertThat(list).doesNotContain("foobar");
assertThat("narf").isNotEqualTo("puit");
assertThat(list).as("bar").contains("barbar");
assertThat(list).as("foo").hasSize(2);
assertThat(list).as("evil").extracting(String::length).contains(2);
assertThat(list).as("bar").contains("barbar");
assertThat("narf").isNotEqualTo("puit");
assertThat(list).as("foo").hasSize(2);
if (true) {
assertThat(list).doesNotContain("narf");
assertThat(list).as("bar").contains("barbar");
}
assertThat(list.get(0)).isNotEmpty();
assertThat(list.get(0)).hasSize(3);
assertThat(list.get(0)).isEqualTo("bar");
assertThat(list.get(0) + "foo").isEqualTo("bar");
assertThat(list.get(0) + "foo").doesNotStartWith("foo");
Iterator<String> iterator = list.iterator();
assertThat(iterator.next()).isEqualTo("foo");
assertThat(iterator.next()).isEqualTo("bar");
}
}
@@ -1,10 +0,0 @@
import static org.assertj.core.api.Assertions.assertThat;
public class ObjectIsNotNull {
private void objectIsNotNull() {
assertThat("").isNotNull();
assertThat("").as("nah").isNotNull();
assertThat(new Object).isNotNull();
}
}
@@ -1,10 +0,0 @@
import static org.assertj.core.api.Assertions.assertThat;
public class ObjectIsNotNull {
private void objectIsNotNull() {
assertThat("").isNotEqualTo(null);
assertThat("").as("nah").isNotEqualTo(null);
assertThat(new Object).isNotEqualTo(null);
}
}
@@ -5,6 +5,10 @@ public class ObjectIsNull {
private void objectIsNull() { private void objectIsNull() {
assertThat("").isNull(); assertThat("").isNull();
assertThat("").as("nah").isNull(); assertThat("").as("nah").isNull();
assertThat(new Object).isNull(); assertThat(new Object()).isNull();
assertThat("").isNotNull();
assertThat("").as("nah").isNotNull();
assertThat(new Object()).isNotNull();
} }
} }
@@ -5,6 +5,10 @@ public class ObjectIsNull {
private void objectIsNull() { private void objectIsNull() {
assertThat("").isEqualTo(null); assertThat("").isEqualTo(null);
assertThat("").as("nah").isEqualTo(null); assertThat("").as("nah").isEqualTo(null);
assertThat(new Object).isEqualTo(null); assertThat(new Object()).isEqualTo(null);
assertThat("").isNotEqualTo(null);
assertThat("").as("nah").isNotEqualTo(null);
assertThat(new Object()).isNotEqualTo(null);
} }
} }
@@ -0,0 +1,99 @@
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
public class Size {
private void size() {
ArrayList<String> list = new ArrayList<>();
ArrayList<String> otherList = new ArrayList<>();
long[] array = new long[5];
long[] otherArray = new long[4];
String string = "string";
StringBuilder stringBuilder = new StringBuilder();
assertThat(list).isEmpty();
assertThat(list).isEmpty();
assertThat(list).isNotEmpty();
assertThat(list).as("hi").isNotEmpty();
assertThat(list).isNotEmpty();
assertThat(list).isEmpty();
assertThat(list).isEmpty();
assertThat(list).hasSameSizeAs(otherList);
assertThat(list).hasSameSizeAs(array);
assertThat(list).hasSize(string.length());
assertThat(list).hasSize(stringBuilder.length());
assertThat(list).hasSize(1);
assertThat(list).hasSizeGreaterThan(otherList.size() * 2);
assertThat(list).hasSizeGreaterThanOrEqualTo(otherList.size() * 2);
assertThat(list).hasSizeLessThan(otherList.size() * 2);
assertThat(list).hasSizeLessThanOrEqualTo(otherList.size() * 2);
assertThat(list).hasSameSizeAs(otherList);
assertThat(list).hasSameSizeAs(array);
assertThat(list).hasSize(string.length());
assertThat(list).hasSize(stringBuilder.length());
assertThat(array).isEmpty();
assertThat(array).isEmpty();
assertThat(array).isNotEmpty();
assertThat(array).as("hi").isNotEmpty();
assertThat(array).isNotEmpty();
assertThat(array).isEmpty();
assertThat(array).isEmpty();
assertThat(array).hasSameSizeAs(list);
assertThat(array).hasSameSizeAs(otherArray);
assertThat(array).hasSize(string.length());
assertThat(array).hasSize(stringBuilder.length());
assertThat(array).hasSize(1);
assertThat(array).hasSizeGreaterThan(otherArray.length - 1);
assertThat(array).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
assertThat(array).hasSizeLessThan(otherArray.length - 3);
assertThat(array).hasSizeLessThanOrEqualTo(1 - otherArray.length);
assertThat(array).hasSameSizeAs(list);
assertThat(array).hasSameSizeAs(otherArray);
assertThat(array).hasSize(string.length());
assertThat(array).hasSize(stringBuilder.length());
assertThat(string).isEmpty();
assertThat(string).isEmpty();
assertThat(string).isNotEmpty();
assertThat(string).as("hi").isNotEmpty();
assertThat(string).isNotEmpty();
assertThat(string).isEmpty();
assertThat(string).isEmpty();
assertThat(string).hasSameSizeAs(list);
assertThat(string).hasSameSizeAs(otherArray);
assertThat(string).hasSameSizeAs(string);
assertThat(string).hasSameSizeAs(stringBuilder);
assertThat(string).hasSize(1);
assertThat(string).hasSizeGreaterThan(otherArray.length - 1);
assertThat(string).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
assertThat(string).hasSizeLessThan(otherArray.length - 3);
assertThat(string).hasSizeLessThanOrEqualTo(1 - otherArray.length);
assertThat(string).hasSameSizeAs(otherList);
assertThat(string).hasSameSizeAs(array);
assertThat(string).hasSameSizeAs(string);
assertThat(string).hasSameSizeAs(stringBuilder);
assertThat(stringBuilder).isEmpty();
assertThat(stringBuilder).isEmpty();
assertThat(stringBuilder).isNotEmpty();
assertThat(stringBuilder).as("hi").isNotEmpty();
assertThat(stringBuilder).isNotEmpty();
assertThat(stringBuilder).isEmpty();
assertThat(stringBuilder).isEmpty();
assertThat(stringBuilder).hasSameSizeAs(list);
assertThat(stringBuilder).hasSameSizeAs(otherArray);
assertThat(stringBuilder).hasSameSizeAs(string);
assertThat(stringBuilder).hasSameSizeAs(stringBuilder);
assertThat(stringBuilder).hasSize(1);
assertThat(stringBuilder).hasSizeGreaterThan(otherArray.length - 1);
assertThat(stringBuilder).hasSizeGreaterThanOrEqualTo(otherArray.length + 1);
assertThat(stringBuilder).hasSizeLessThan(otherArray.length - 3);
assertThat(stringBuilder).hasSizeLessThanOrEqualTo(1 - otherArray.length);
assertThat(stringBuilder).hasSameSizeAs(otherList);
assertThat(stringBuilder).hasSameSizeAs(array);
assertThat(stringBuilder).hasSameSizeAs(string);
assertThat(stringBuilder).hasSameSizeAs(stringBuilder);
}
}
@@ -0,0 +1,99 @@
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
public class Size {
private void size() {
ArrayList<String> list = new ArrayList<>();
ArrayList<String> otherList = new ArrayList<>();
long[] array = new long[5];
long[] otherArray = new long[4];
String string = "string";
StringBuilder stringBuilder = new StringBuilder();
assertThat(list.size()).isEqualTo(0);
assertThat(list.size()).isZero();
assertThat(list.size()).isNotZero();
assertThat(list.size()).as("hi").isGreaterThan(0);
assertThat(list.size()).isGreaterThanOrEqualTo(1);
assertThat(list.size()).isLessThan(1);
assertThat(list.size()).isLessThanOrEqualTo(0);
assertThat(list.size()).isEqualTo(otherList.size());
assertThat(list.size()).isEqualTo(array.length);
assertThat(list.size()).isEqualTo(string.length());
assertThat(list.size()).isEqualTo(stringBuilder.length());
assertThat(list.size()).isEqualTo(1);
assertThat(list.size()).isGreaterThan(otherList.size() * 2);
assertThat(list.size()).isGreaterThanOrEqualTo(otherList.size() * 2);
assertThat(list.size()).isLessThan(otherList.size() * 2);
assertThat(list.size()).isLessThanOrEqualTo(otherList.size() * 2);
assertThat(list).hasSize(otherList.size());
assertThat(list).hasSize(array.length);
assertThat(list).hasSize(string.length());
assertThat(list).hasSize(stringBuilder.length());
assertThat(array.length).isEqualTo(0);
assertThat(array.length).isZero();
assertThat(array.length).isNotZero();
assertThat(array.length).as("hi").isGreaterThan(0);
assertThat(array.length).isGreaterThanOrEqualTo(1);
assertThat(array.length).isLessThan(1);
assertThat(array.length).isLessThanOrEqualTo(0);
assertThat(array.length).isEqualTo(list.size());
assertThat(array.length).isEqualTo(otherArray.length);
assertThat(array.length).isEqualTo(string.length());
assertThat(array.length).isEqualTo(stringBuilder.length());
assertThat(array.length).isEqualTo(1);
assertThat(array.length).isGreaterThan(otherArray.length - 1);
assertThat(array.length).isGreaterThanOrEqualTo(otherArray.length + 1);
assertThat(array.length).isLessThan(otherArray.length - 3);
assertThat(array.length).isLessThanOrEqualTo(1 - otherArray.length);
assertThat(array).hasSize(list.size());
assertThat(array).hasSize(otherArray.length);
assertThat(array).hasSize(string.length());
assertThat(array).hasSize(stringBuilder.length());
assertThat(string.length()).isEqualTo(0);
assertThat(string.length()).isZero();
assertThat(string.length()).isNotZero();
assertThat(string.length()).as("hi").isGreaterThan(0);
assertThat(string.length()).isGreaterThanOrEqualTo(1);
assertThat(string.length()).isLessThan(1);
assertThat(string.length()).isLessThanOrEqualTo(0);
assertThat(string.length()).isEqualTo(list.size());
assertThat(string.length()).isEqualTo(otherArray.length);
assertThat(string.length()).isEqualTo(string.length());
assertThat(string.length()).isEqualTo(stringBuilder.length());
assertThat(string.length()).isEqualTo(1);
assertThat(string.length()).isGreaterThan(otherArray.length - 1);
assertThat(string.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
assertThat(string.length()).isLessThan(otherArray.length - 3);
assertThat(string.length()).isLessThanOrEqualTo(1 - otherArray.length);
assertThat(string).hasSize(otherList.size());
assertThat(string).hasSize(array.length);
assertThat(string).hasSize(string.length());
assertThat(string).hasSize(stringBuilder.length());
assertThat(stringBuilder.length()).isEqualTo(0);
assertThat(stringBuilder.length()).isZero();
assertThat(stringBuilder.length()).isNotZero();
assertThat(stringBuilder.length()).as("hi").isGreaterThan(0);
assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(1);
assertThat(stringBuilder.length()).isLessThan(1);
assertThat(stringBuilder.length()).isLessThanOrEqualTo(0);
assertThat(stringBuilder.length()).isEqualTo(list.size());
assertThat(stringBuilder.length()).isEqualTo(otherArray.length);
assertThat(stringBuilder.length()).isEqualTo(string.length());
assertThat(stringBuilder.length()).isEqualTo(stringBuilder.length());
assertThat(stringBuilder.length()).isEqualTo(1);
assertThat(stringBuilder.length()).isGreaterThan(otherArray.length - 1);
assertThat(stringBuilder.length()).isGreaterThanOrEqualTo(otherArray.length + 1);
assertThat(stringBuilder.length()).isLessThan(otherArray.length - 3);
assertThat(stringBuilder.length()).isLessThanOrEqualTo(1 - otherArray.length);
assertThat(stringBuilder).hasSize(otherList.size());
assertThat(stringBuilder).hasSize(array.length);
assertThat(stringBuilder).hasSize(string.length());
assertThat(stringBuilder).hasSize(stringBuilder.length());
}
}
@@ -0,0 +1,47 @@
import static org.assertj.core.api.Assertions.assertThat;
public class StringExpression {
private void stringExpression() {
String string = "string";
StringBuilder stringBuilder = new StringBuilder();
assertThat(string).isEmpty();
assertThat(string).isEmpty();
assertThat(string).isEqualTo("foo");
assertThat(string).isEqualTo("foo");
assertThat(string).isEqualToIgnoringCase("foo");
assertThat(string).isEqualToIgnoringCase("foo");
assertThat(string).isEqualTo("foo");
assertThat(string).isEqualTo("foo");
assertThat(string).isEqualTo(stringBuilder);
assertThat(string).isEqualTo(stringBuilder);
assertThat(string).contains("foo");
assertThat(string).contains("foo");
assertThat(string).contains(stringBuilder);
assertThat(string).contains(stringBuilder);
assertThat(string).startsWith("foo");
assertThat(string).startsWith("foo");
assertThat(string).endsWith("foo");
assertThat(string).endsWith("foo");
assertThat(string).isNotEmpty();
assertThat(string).isNotEmpty();
assertThat(string).isNotEqualTo("foo");
assertThat(string).isNotEqualTo("foo");
assertThat(string).isNotEqualToIgnoringCase("foo");
assertThat(string).isNotEqualToIgnoringCase("foo");
assertThat(string).isNotEqualTo("foo");
assertThat(string).isNotEqualTo("foo");
assertThat(string).isNotEqualTo(stringBuilder);
assertThat(string).isNotEqualTo(stringBuilder);
assertThat(string).doesNotContain("foo");
assertThat(string).doesNotContain("foo");
assertThat(string).doesNotContain(stringBuilder);
assertThat(string).doesNotContain(stringBuilder);
assertThat(string).doesNotStartWith("foo");
assertThat(string).doesNotStartWith("foo");
assertThat(string).doesNotEndWith("foo");
assertThat(string).doesNotEndWith("foo");
}
}
@@ -0,0 +1,47 @@
import static org.assertj.core.api.Assertions.assertThat;
public class StringExpression {
private void stringExpression() {
String string = "string";
StringBuilder stringBuilder = new StringBuilder();
assertThat(string.isEmpty()).isEqualTo(true);
assertThat(string.isEmpty()).isTrue();
assertThat(string.equals("foo")).isEqualTo(true);
assertThat(string.equals("foo")).isTrue();
assertThat(string.equalsIgnoreCase("foo")).isEqualTo(true);
assertThat(string.equalsIgnoreCase("foo")).isTrue();
assertThat(string.contentEquals("foo")).isEqualTo(true);
assertThat(string.contentEquals("foo")).isTrue();
assertThat(string.contentEquals(stringBuilder)).isTrue();
assertThat(string.contentEquals(stringBuilder)).isEqualTo(true);
assertThat(string.contains("foo")).isEqualTo(true);
assertThat(string.contains("foo")).isTrue();
assertThat(string.contains(stringBuilder)).isEqualTo(true);
assertThat(string.contains(stringBuilder)).isTrue();
assertThat(string.startsWith("foo")).isEqualTo(true);
assertThat(string.startsWith("foo")).isTrue();
assertThat(string.endsWith("foo")).isEqualTo(true);
assertThat(string.endsWith("foo")).isTrue();
assertThat(string.isEmpty()).isEqualTo(false);
assertThat(string.isEmpty()).isFalse();
assertThat(string.equals("foo")).isEqualTo(false);
assertThat(string.equals("foo")).isFalse();
assertThat(string.equalsIgnoreCase("foo")).isEqualTo(false);
assertThat(string.equalsIgnoreCase("foo")).isFalse();
assertThat(string.contentEquals("foo")).isEqualTo(false);
assertThat(string.contentEquals("foo")).isFalse();
assertThat(string.contentEquals(stringBuilder)).isFalse();
assertThat(string.contentEquals(stringBuilder)).isEqualTo(false);
assertThat(string.contains("foo")).isEqualTo(false);
assertThat(string.contains("foo")).isFalse();
assertThat(string.contains(stringBuilder)).isEqualTo(false);
assertThat(string.contains(stringBuilder)).isFalse();
assertThat(string.startsWith("foo")).isEqualTo(false);
assertThat(string.startsWith("foo")).isFalse();
assertThat(string.endsWith("foo")).isEqualTo(false);
assertThat(string.endsWith("foo")).isFalse();
}
}
@@ -0,0 +1,20 @@
public class Address {
private String street;
private String country;
private String getStreet() {
return street;
}
public String getCountry() {
return country;
}
public boolean isNoMailings() {
return true;
}
public Boolean getREALLYnoMAILINGS() {
return true;
}
}
@@ -0,0 +1,9 @@
public class Contact {
private String name;
public Integer age;
protected Address address;
public String getStreetName()
{
return address.getStreet();
}
}
@@ -0,0 +1,15 @@
import org.assertj.core.extractor.Extractors;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class FindReference1 {
private void findReferences() {
Contact contact = new Contact();
assertThat(contact).extracting("name<caret>").isEqualTo("foo");
}
}
@@ -0,0 +1,15 @@
import org.assertj.core.extractor.Extractors;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class FindReference10 {
private void findReferences() {
List<Contact> contactList = Collections.emptyList();
assertThat(contactList).extractingResultOf("getStreetName<caret>").isEqualTo("foo");
}
}

Some files were not shown because too many files have changed in this diff Show More