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

feat: add prefer-explicit-assert rule #29

Merged
merged 9 commits into from
Oct 24, 2019
Merged

Conversation

Belco90
Copy link
Member

@Belco90 Belco90 commented Oct 21, 2019

New rule: no-get-by-assert prefer-explicit-assert

This closes #28

Copy link

@Meemaw Meemaw left a 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.


create: function(context) {
return {
[`CallExpression > Identifier[name=${/^getBy(LabelText|PlaceholderText|Text|AltText|Title|DisplayValue|Role|TestId)$/}]`](
Copy link

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.

Copy link
Member Author

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.

url: getDocsUrl('no-get-by-assert'),
},
messages: {
noGetByAssert: 'Disallowed use of `getBy*` query as implicit assert',
Copy link

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?

Copy link
Member Author

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.

Copy link
Collaborator

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?

Copy link
Member Author

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.

```js
// wrapping the get query within a `expect` and use some matcher for
// making the assertion more explicit
expect(getByText('foo')).toBeDefined();
Copy link
Collaborator

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.

Copy link
Member Author

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.

Copy link
Collaborator

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) 🙂

Copy link
Member Author

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.

Copy link
Collaborator

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? 🙂

Copy link
Member Author

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.

Copy link
Contributor

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.

@@ -0,0 +1,51 @@
# Disallow `getBy*` queries as assertion method itself (no-get-by-assert)
Copy link
Collaborator

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

Copy link
Member Author

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?

Copy link
Collaborator

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!

url: getDocsUrl('no-get-by-assert'),
},
messages: {
noGetByAssert: 'Disallowed use of `getBy*` query as implicit assert',
Copy link
Collaborator

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?

!isDirectlyCalledByFunction(node) &&
!isReturnedByArrowFunctionExpression(node) &&
!isDeclared(node) &&
!isReturnedByReturnStatement(node)
Copy link
Collaborator

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 👌

Copy link
Member Author

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 😨

@Belco90
Copy link
Member Author

Belco90 commented Oct 22, 2019

All feedback for renaming the rule, add proper references to prefer-expect-query-by rule, add option for custom queries and improve error message have been addressed. Please let me know what you think now :)

@Belco90 Belco90 changed the title feat: add no-get-by-assert rule feat: add prefer-explicit-assert rule Oct 22, 2019
thomaslombart
thomaslombart previously approved these changes Oct 23, 2019
Copy link
Collaborator

@thomaslombart thomaslombart left a 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 👍

lib/rules/prefer-explicit-assert.js Outdated Show resolved Hide resolved
Copy link
Contributor

@emmenko emmenko left a 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.

docs/rules/prefer-explicit-assert.md Outdated Show resolved Hide resolved
ruleTester.run('prefer-explicit-assert', rule, {
valid: [
{
code: `getByText`,
Copy link
Contributor

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('...')
// ...

Copy link
Member Author

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.

Copy link
Member Author

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

Copy link
Contributor

@emmenko emmenko left a 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

Copy link
Collaborator

@thomaslombart thomaslombart left a comment

Choose a reason for hiding this comment

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

LGTM, great job! 🎉

@Belco90 Belco90 merged commit 7da2b75 into master Oct 24, 2019
@Belco90 Belco90 deleted the feature/no-get-by-assert-rule branch October 24, 2019 08:39
@Belco90
Copy link
Member Author

Belco90 commented Oct 24, 2019

🎉 This PR is included in version 1.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@Belco90
Copy link
Member Author

Belco90 commented Oct 24, 2019

@all-contributors please add @emmenko for review

@allcontributors
Copy link
Contributor

@Belco90

I've put up a pull request to add @emmenko! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

No get* to assert element is in document
4 participants