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

Introduce JUnitSingleArguments bug checker #816

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Venorcis
Copy link
Contributor

@Venorcis Venorcis commented Oct 6, 2023

Adds a bugchecker that flags uses of JUnit Arguments when only a single (or in a weird edge case no) argument is used.

An example can be seen in the diff of the MethodMatcherFactoryTest 😄

@github-actions
Copy link

github-actions bot commented Oct 6, 2023

  • Surviving mutants in this change: 1
  • Killed mutants in this change: 5
class surviving killed
🧟tech.picnic.errorprone.bugpatterns.JUnitSingleArguments 1 5

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@github-actions
Copy link

github-actions bot commented Oct 6, 2023

Looks good. All 6 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.JUnitSingleArguments 0 6

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@Venorcis Venorcis force-pushed the vkoeman/junit-arguments-single branch from 3af06e2 to 10dfe9d Compare October 6, 2023 15:34
@github-actions
Copy link

github-actions bot commented Oct 6, 2023

Looks good. All 6 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.JUnitSingleArguments 0 6

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@Venorcis Venorcis force-pushed the vkoeman/junit-arguments-single branch from cacc565 to 8645037 Compare October 6, 2023 15:45
@github-actions
Copy link

github-actions bot commented Oct 6, 2023

Looks good. All 6 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.JUnitSingleArguments 0 6

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

1 similar comment
@github-actions
Copy link

github-actions bot commented Oct 6, 2023

Looks good. All 6 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.JUnitSingleArguments 0 6

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@Venorcis Venorcis force-pushed the vkoeman/junit-arguments-single branch from 8645037 to efd3a9a Compare October 6, 2023 16:09
@github-actions
Copy link

github-actions bot commented Oct 6, 2023

Looks good. All 6 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.JUnitSingleArguments 0 6

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Oct 7, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

100.0% 100.0% Coverage
0.0% 0.0% Duplication

@github-actions
Copy link

github-actions bot commented Oct 7, 2023

Looks good. All 6 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.JUnitSingleArguments 0 6

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

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.

Nice rule! I suspect we an make it robust in the common case, but will need to find some time to look closer into the least-impactful approach.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (ARGUMENTS_ARGUMENTS.matches(tree, state) && tree.getArguments().size() <= 1) {
return describeMatch(tree, SourceCode.unwrapMethodInvocation(tree, state));
Copy link
Member

Choose a reason for hiding this comment

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

This would cause a compilation error w.r.t. the return type, right? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I wasn't sure how we deal with the fix suggestions. AFAIK not all suggestions necessarily lead to directly compiling code? We can ofc. remove it here and just flag instead 🤷🏻‍♂️

Copy link
Member

Choose a reason for hiding this comment

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

We try either produce compilable code or only flag the issue, with a strong preference for the former (as the latter really introduces quite a bit more friction). That said, especially some of the Refaster rules can in special circumstances break the code.

For this case we could:

  1. Simplify the factory method if it has a single return statement, using similar logic we use in JUnitValueSource.
  2. Only flag otherwise.

(But that's considerably more complicated than the current proposal, so if you're like "uuuuuh", I get that. Don't mind having a stab; would just take a bit of time.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah understood. In the most common use case we 'only' need to replace <Arguments> with <T> in the method definition. Perhaps it's relatively easy to add the suggestion for this use case and still resort to flagging any other occurrences (they would be weird but you never know 😛 ).

Copy link
Member

Choose a reason for hiding this comment

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

Indeed, that's the lines along which I'm thinking 👍

(Both inside Picnic and for the upcoming integration test framework against open-source repos we run Error Prone in a loop until it no longer makes any changes, which can only work if each intermediate state compiles successfully.)

Copy link
Member

Choose a reason for hiding this comment

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

I've looked a bit closer at this topic, and the logic in JUnitValueSource shows that there are quite a lot of details to consider:

  1. There are different ways in which the Arguments can be wrapped in a top-level collection/stream/array.
  2. The factory method can have multiple return statements.
  3. The return type could change from MonadType<Arguments> or Arguments[] to MonadType<Object> or Object[], but ideally we're more specific.
  4. Only if all Arguments instances have exactly one value can we do the unwrapping (in case of variability we should likely emit a separate warning).
  5. Ideally we do all this in a way that reuses relevant pieces of logic from JUnitValueSource.

I'm likely missing a few other details. Happy to dive deeper into this, but it'll be a while before I find the time to really sit down for this.

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.

2 participants