Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BugPattern to rewrite assertThat(...).isEqualTo(null) to assertThat(...).isNull() #133

Merged
merged 10 commits into from
Jun 29, 2022

Conversation

oxkitsune
Copy link
Contributor

@oxkitsune oxkitsune commented Jun 15, 2022

Implement BugPattern to rewrite assertThat(...).isEqualTo(null) to assertThat(...).isNull()

Example:

- assertThat(foo).isEqualTo(null);
+ assertThat(foo).isNull();

Suggested commit message:

Add BugPattern to rewrite `assertThat(...).isEqualTo(null)` to `assertThat(...).isNull()` (#133)

@oxkitsune oxkitsune marked this pull request as ready for review June 16, 2022 07:26
@oxkitsune oxkitsune requested a review from rickie June 16, 2022 07:26
Copy link
Member

@rickie rickie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most important thing is that we don't flag only AssertJ usages of isEqualTo, which should be the case 😄.

@oxkitsune
Copy link
Contributor Author

I'm going to redo the Matcher as I learned some neat tricks to simplify this a lot!

@oxkitsune oxkitsune requested a review from rickie June 17, 2022 11:56
@Stephan202
Copy link
Member

I'm going to redo the Matcher as I learned some neat tricks to simplify this a lot!

That's the spirit 💪. I'll let @rickie do a new review round first, but perhaps some of the (functional and/or stylistic) tweaks I applied in #135 are applicable here as well :)

Copy link
Member

@Stephan202 Stephan202 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased and added a commit. Suggested commit message:

Prefer AssertJ's `isNull()` assertion over `isEqualTo(null)` (#133)

Copy link
Member

@Stephan202 Stephan202 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, one open point: we should document why we can't use Refaster for this, e.g. with an example.

(Requesting changes so we don't forget.)

Copy link
Member

@rickie rickie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, there were like 6 comments from when I started reviewing before @Stephan202 made some changes, sorry about that. Can't delete them anymore 🤔.

Made a suggestion w.r.t. the explanation.

Overall, changes LGTM 😄.


/**
* A {@link BugChecker} which flags {@code asserThat(someValue).isEqualTo(null)} for further
* simplification
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* simplification
* simplification.

Javadoc should end with a dot :).

" public void testAssertThat() {",
" String nullValue = null;",
" assertThat(12).isEqualTo(12);",
" // BUG: Diagnostic contains: assertThat(...).isNull()",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
" // BUG: Diagnostic contains: assertThat(...).isNull()",
" // BUG: Diagnostic contains:",

" isEqualTo(null);",
" }",
"",
" private boolean isEqualTo (Object value) {",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to follow the google-java-format in the tests as well.

.addInputLines(
"A.java",
"import static org.assertj.core.api.Assertions.assertThat;",
"import com.google.common.collect.ImmutableSortedSet;",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any usages of this 👀.

private static final long serialVersionUID = 1L;

private static final Matcher<MethodInvocationTree> ASSERT_IS_EQUAL =
Matchers.allOf(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Matchers we generally statically import. That reads a bit nicer :)

import com.sun.source.tree.MethodInvocationTree;

/**
* A {@link BugChecker} which flags AssertJ {@code isEqualTo(null)} checks for simplification. <br>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first line of the Javadoc is a short summary. After that we have an empty line with optionally extra explanations.

Also <br> is not used in the Javadoc (see the suggestion I'm about to push).
The google-java-format plugin in IntelliJ automatically adds the <p> in front of the text if there was an empty line between it and the summary.

/**
* A {@link BugChecker} which flags AssertJ {@code isEqualTo(null)} checks for simplification. <br>
* This cannot be done using a refaster template, as refaster is unable to match the abstraction
* layers in AssertJ
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* layers in AssertJ
* layers in AssertJ.

Sentence should end with a dot.


/**
* A {@link BugChecker} which flags AssertJ {@code isEqualTo(null)} checks for simplification. <br>
* This cannot be done using a refaster template, as refaster is unable to match the abstraction
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* This cannot be done using a refaster template, as refaster is unable to match the abstraction
* This cannot be done using a Refaster template, as Refaster is unable to match the abstraction

* This cannot be done using a refaster template, as refaster is unable to match the abstraction
* layers in AssertJ
*
* <p>Example: <code>assertThat("foo").isEqualTo(null)</code> will not be matched by refaster.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I completely understand the suggestion, some context is missing here. When trying to implement this using Refaster templates, the issue was a bit more specific. From the +- 10 before templates, only 5 or 6 matched. So a few (I don't remember which ones) didn't work for Refaster.

There is a good chance the proposed examples does work. That's why I proposed a slightly different test. Not sure if we should figure out which (sub)types didn't match to provide examples in the Javadoc. Perhaps this is good enough. WDYT?

@rickie rickie added this to the 0.1.0 milestone Jun 28, 2022
Comment on lines 26 to 27
* <p>This cannot be done by using only Refaster templates, as Refaster is not able to match *all*
* {@code AbstractAssert} subtypes correctly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just raises questions for me. Do we have a concrete example that fails, so that I can identify the underlying cause (and then turn that into a concise explanation)? :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, assertThat("foo").isEqualTo(null) was mentioned in a preceding commit. Will check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key point here is that there exist specialized overloads (not overrides) of isEqualTo that we also wish to match. Added a commit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether this suggestions_really_ describes problem. Adding all of these overloads to a Refaster template would not work. For some reason, Refaster fails to match some of the overloads. So I recall we had about 8 before templates but some specific overloads didn't do anything because Refaster couldn't correctly match all these types.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like to see such an example, then. OTOH, not sure it matters: the current description isn't wrong: even if Refaster would work it'd (a) be a lot of work and (b) not be future-proof.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, I agree with your points. I don't think it is worth the hassle to get to the specific examples. Let's roll with the current state 🚀 .

@Stephan202 Stephan202 merged commit c500516 into master Jun 29, 2022
@Stephan202 Stephan202 deleted the gdejong/psm-1298 branch June 29, 2022 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants