-
Notifications
You must be signed in to change notification settings - Fork 131
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
feat: add prefer-explicit-assert rule #29
Conversation
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.
Looks good 👍
Left a few smaller comments.
lib/rules/no-get-by-assert.js
Outdated
|
||
create: function(context) { | ||
return { | ||
[`CallExpression > Identifier[name=${/^getBy(LabelText|PlaceholderText|Text|AltText|Title|DisplayValue|Role|TestId)$/}]`]( |
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.
Could this be extendable by the user if needed? For example we have some custom selectors e.g. getByIcon
that I would like to fall under the same rule but should not be part of the default configuration.
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.
Yes, I can make it extendable so users can add their own queries. I always have doubts about just checking getBy*
default queries + custom ones or check everything starting by getBy
, but I think I prefer the first one and make it extendable so you and other users can add custom queries and avoid false positives with other things.
lib/rules/no-get-by-assert.js
Outdated
url: getDocsUrl('no-get-by-assert'), | ||
}, | ||
messages: { | ||
noGetByAssert: 'Disallowed use of `getBy*` query as implicit assert', |
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.
Is this the message user will see on hover in VSCode for example? Should it include some information to use the expect(queryBy*)...
pattern?
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.
Yes, this is the message you'll get when linting the code (or your IDE pass the linter for you). To be honest I don't know what to put here, so I just put something simple mirroring other rules from ESLint. Suggestions are more than welcome.
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 would go for something like Use queryBy assertions instead of getBy
. What do you think?
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.
Same as previous mentions to queryBy
: user can't be forced to do that, we can only mention the fact that the getBy
must be transformed into explicit assert.
docs/rules/no-get-by-assert.md
Outdated
```js | ||
// wrapping the get query within a `expect` and use some matcher for | ||
// making the assertion more explicit | ||
expect(getByText('foo')).toBeDefined(); |
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.
Shouldn't it be expect(queryByText)
instead of expect(getByText)
? 🤔
Such an example would be conflicting with the prefer-expect-query-by
rule.
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.
That's actually from a different rule so I would avoid having this one encouraging two things: asserting explicitly and asserting with queryBy*
, so just leaving this rule for the former and prefer-expect-query-by
for the latter.
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.
Yes, but as prefer-expect-query-by
is in the recommended rules, I found it a little bit weird to say expect(getBy)
is correct (although it is for this rule technically speaking) 🙂
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.
Well, in the example of this specific rule that's fine. It would be weird to see expect(queryByText('foo')).toBeDefined();
when the rule only talk about getBy*
, so I wanted to clarify that specific use is valid for this rule.
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.
Sure! What about putting a side note stating that though expect(getBy)
is valid for this rule, it is recommended to use queryBy
for asserting elements' presence? Then, the user would know it's valid to use expect(getBy)
while still being aware it's not recommended. What do you think? 🙂
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.
That sounds absolutely reasonable. I'll address the feedback here later.
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.
My 2 cents: I understand both points. However, since this is a documentation to something that is to be considered "valid", I would expect that we write things that are "valid", which is not really the case with expect(getBy)
, as we also have a recommended rule for it.
At least we should mention to wrap it into an expect
and then to change it to queryBy
, and link it to the other rule for more reference.
docs/rules/no-get-by-assert.md
Outdated
@@ -0,0 +1,51 @@ | |||
# Disallow `getBy*` queries as assertion method itself (no-get-by-assert) |
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.
The rule name sounds a bit strange to me. When it comes to preferences, ESLint rules are usually named prefer-...
, I think it should be the case here.
no-get-by-assert
implies here that doing assertions with getBy
queries is wrong. I think something like prefer-query-by-assert
is more clear to the user as discussed in the issue
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'm happy to rename this to prefer-*
rule but I would avoid using query-by for same reason I commented before, so I would go for something like prefer-explicit-assert
. What do you think?
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.
prefer-explicit-assert
sounds good to me!
lib/rules/no-get-by-assert.js
Outdated
url: getDocsUrl('no-get-by-assert'), | ||
}, | ||
messages: { | ||
noGetByAssert: 'Disallowed use of `getBy*` query as implicit assert', |
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 would go for something like Use queryBy assertions instead of getBy
. What do you think?
lib/rules/no-get-by-assert.js
Outdated
!isDirectlyCalledByFunction(node) && | ||
!isReturnedByArrowFunctionExpression(node) && | ||
!isDeclared(node) && | ||
!isReturnedByReturnStatement(node) |
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 really like this approach. It makes the edge cases clear and readable 👌
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 like it too, but I'm always concerned about if I left one edge case out 😨
All feedback for renaming the rule, add proper references to |
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.
Small tiny fix to do but everything LGTM otherwise 👍
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.
Very nice, thanks for addressing the feedback! I have one additional request, to make sure the rule works in those cases as well.
ruleTester.run('prefer-explicit-assert', rule, { | ||
valid: [ | ||
{ | ||
code: `getByText`, |
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.
Can you also check for when queries are not destructured?
const rendered = render(<App />)
rendered.getByText('...')
// ...
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 spot! This actually found some issues in the rule, so I'm adding those tests and fixing the rule implementation.
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.
Tests added, rule fixed and more examples added to the doc
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, looks good to me now
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.
LGTM, great job! 🎉
🎉 This PR is included in version 1.3.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
@all-contributors please add @emmenko for review |
I've put up a pull request to add @emmenko! 🎉 |
New rule:
no-get-by-assertprefer-explicit-assertThis closes #28