-
Notifications
You must be signed in to change notification settings - Fork 49
Introduce JUnitMethodSourceGenericParams bug checker
#1786
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
base: master
Are you sure you want to change the base?
Introduce JUnitMethodSourceGenericParams bug checker
#1786
Conversation
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
rickie
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice check idea! Mostly testing that should be improved. I didn't go through the code yet properly, will do that after my holiday :)
...contrib/src/main/java/tech/picnic/errorprone/bugpatterns/JUnitMethodSourceGenericParams.java
Outdated
Show resolved
Hide resolved
...contrib/src/main/java/tech/picnic/errorprone/bugpatterns/JUnitMethodSourceGenericParams.java
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| Optional<AnnotationTree> methodSourceAnnotation = findMethodSourceAnnotation(tree, state); | ||
| if (methodSourceAnnotation.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to go over the mutation tests by adding some more coverage :)
error-prone-utils/src/main/java/tech/picnic/errorprone/utils/MoreASTHelpers.java
Show resolved
Hide resolved
032b7ac to
704b79e
Compare
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
d273d2a to
81947fd
Compare
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
81947fd to
0823854
Compare
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
mohamedsamehsalah
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for review @rickie 🙌
I tried to address the mutation test reports, but I will need help to cover all of them. I tried to put the reasoning in the comments.
| "class A {", | ||
| // Used to explicitly highlight that we ignore non-parameterized types during this test, | ||
| // as they are not subject to the check. | ||
| " static class IrrelevantNonParameterizedType {}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(1) I want to ignore non-parameterised types explicitly. The reasoning: These type checks are either performed by Java during compile time or checked by JUnit at runtime.
The checker, as the documentation mentions, should flag cases that are not covered by either.
| List<? extends ExpressionTree> arguments = argumentMethodInvocationTree.getArguments(); | ||
| if (treeToString(argumentMethodInvocationTree.getMethodSelect(), state) | ||
| .contentEquals(ARGUMENT_SET)) { | ||
| // We skip the first argument, because it's the argument set name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(2) This and the next mutation test will be hard to cover because the first argument of the argumentSet API is non-parametrised, thus, ignored.
| private static boolean allParameterisedArgumentsHaveApplicableTypes( | ||
| Type testMethodParameterType, Type methodSourceProviderType, Types types) { | ||
| if (!testMethodParameterType.isParameterized() || !methodSourceProviderType.isParameterized()) { | ||
| // Skip non-parameterised arguments, as any type incompatibility will be flagged by JUnit at |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(3) This is intended, to limit the scope of the checker.
| * @see ASTHelpers#getUpperBound(Type, Types) | ||
| */ | ||
| public static Type getLowerBound(Type type, Types types) { | ||
| if (type.hasTag(TypeTag.WILDCARD)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This should be covered by the BugChecker test) 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I drop the second and third if statement, the test + the BugCheck test succeeds 🤔.
- if (type.hasTag(TypeTag.TYPEVAR) && ((TypeVar) type).isCaptured()) {
- return types.cvarLowerBound(type);
- }
-
- if (type.getLowerBound() != null) {
- return type.getLowerBound();
- }
+// if (type.hasTag(TypeTag.TYPEVAR) && ((TypeVar) type).isCaptured()) {
+// return types.cvarLowerBound(type);
+// }
+//
+// if (type.getLowerBound() != null) {
+// return type.getLowerBound();
+// }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should figure out if we need these statements or not. Otherwise we should find how to test them. If we can kill more mutants, we can be more sure about what we are actually testing / trying to catch here.
0823854 to
c0a3c4a
Compare
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
rickie
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only some small comments so far. Takes a while to review, but flashing already.
| * | ||
| * @param methodTree The method tree on which to find the annotation from. | ||
| * @param state The {@link VisitorState} from which to derive the AST location of interest. | ||
| * @return Returns the {@code @MethodSource} annotation on the given method, if any. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double word if we keep "Returns". And we can use link with fully qualified name as we do above in this class :)
| .doTest(); | ||
| } | ||
|
|
||
| @Test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great coverage, looks good.
| * @return The lower bound of the type, or the type itself if it has no lower bound. | ||
| * @see ASTHelpers#getUpperBound(Type, Types) | ||
| */ | ||
| public static Type getLowerBound(Type type, Types types) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could argue this belongs in a class MoreTypes as it's on the Types class, but I think it's fine to leave it here TBH.
| * @see ASTHelpers#getUpperBound(Type, Types) | ||
| */ | ||
| public static Type getLowerBound(Type type, Types types) { | ||
| if (type.hasTag(TypeTag.WILDCARD)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I drop the second and third if statement, the test + the BugCheck test succeeds 🤔.
- if (type.hasTag(TypeTag.TYPEVAR) && ((TypeVar) type).isCaptured()) {
- return types.cvarLowerBound(type);
- }
-
- if (type.getLowerBound() != null) {
- return type.getLowerBound();
- }
+// if (type.hasTag(TypeTag.TYPEVAR) && ((TypeVar) type).isCaptured()) {
+// return types.cvarLowerBound(type);
+// }
+//
+// if (type.getLowerBound() != null) {
+// return type.getLowerBound();
+// }
| private static final Matcher<ExpressionTree> SUPPORTED_METHOD_SOURCE_PROVIDERS = | ||
| staticMethod() | ||
| .onDescendantOfAny( | ||
| List.class.getCanonicalName(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's sort those :)
|
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol I confused myself with flushing what I had and not 😬.
Pushing a commit with some changes. Let's discuss some of the mutants to get that more sorted out :).
The check has a nice shape. Let's do these two things:
- Run it on a repo of ours internally (I recall you might have done this a while back as you asked me about it 🤔).
- I've to continue reviewing :)
| * @see ASTHelpers#getUpperBound(Type, Types) | ||
| */ | ||
| public static Type getLowerBound(Type type, Types types) { | ||
| if (type.hasTag(TypeTag.WILDCARD)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should figure out if we need these statements or not. Otherwise we should find how to test them. If we can kill more mutants, we can be more sure about what we are actually testing / trying to catch here.



JUnit's parameterized tests, annotated with
@MethodSource, do not have generic type information at runtime. This means that we can pass a Set of Integers as an argument to a test method which accepts a Set of Strings, and JUnit would disregard the accepted type.This bug checker flags such cases.
Potential Bug⚠️
Suggested commit message