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!: Stricter rule test validations #17654
feat!: Stricter rule test validations #17654
Conversation
✅ Deploy Preview for docs-eslint canceled.
|
Note that I do have more of this implemented in: https://github.com/bmish/eslint/tree/RFC-84 |
Added the second check for requiring a |
Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update. |
Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update. |
This pull request was auto-closed due to inactivity. While we wish we could keep working on every request, we unfortunately don't have the bandwidth to continue here and need to focus on other things. You can resubmit this pull request if you would like to continue working on it. |
@DMartens good progress on this PR. Are you still working on it? We should try to finish it up soon for ESLint v9.
Let me know if you're stuck on anything. |
Yes, I am still working on this. I was just waiting for feedback but with the PR reopened I guess this PR is wanted.
|
Excellent, yes definitely eager to see this PR completed, thanks! |
Did everything except copying the assertions / tests for flat rule tester (and the duplicate test case detection (should this be a separate PR?)).
|
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.
Looking pretty good so far.
I would definitely leave "duplicate test case detection" to a separate PR, as it's much more complicated as described in the RFC, and I personally ran into a lot of edge cases with it and trouble getting it perfect when implementing it for a similar linter.
lib/rule-tester/rule-tester.js
Outdated
@@ -1153,6 +1160,7 @@ class RuleTester { | |||
); | |||
} else { | |||
assert.strictEqual(result.output, item.output, "Output is incorrect."); | |||
assert.notStrictEqual(item.code, item.output, "Use 'output: null' if the rule does not fix this case instead of copying the code."); |
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.
Omit 'output'
is my first recommendation to fix. Also could simplify wording:
assert.notStrictEqual(item.code, item.output, "Use 'output: null' if the rule does not fix this case instead of copying the code."); | |
assert.notStrictEqual(item.code, item.output, "Omit 'output' or use 'output: null' if there is no autofix."); |
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 this is a preference (maybe a case for eslint-plugin-eslint-plugin?) as personally I try to be as explicit as possible. As the developer copied the code to output I think they want to keep the output property as there would've been no error forcing them to add the output
property.
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 people want to be explicit, that's fine. But I do think we should mention that the property can be omitted as one option. Similar to how schema: []
can be omitted from rules starting in ESLint v9.
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 doesn't seem to be addressed yet.
Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update. |
We're going to remove RuleTester soon, so all changes should be done in FlatRuleTester only. |
Now that the alpha is out, it should be a good time to address these merge conflicts. @DMartens are you able to fix this up in the next week? Want to make sure this is ready for the beta. |
I should be able to fix those merge issues this week. |
Great. No need for a new PR. Can just fix the merge conflicts so that the correct file is updated. |
I've started on the duplicate test case detection here: So we'll need to have both of these PRs ready for the beta in a week. |
Thanks for the code reviews. I should have addressed all raised points in their own commit. export default {
messages: {
id: "{{ expected }}"
},
create(context) {
context.report({ messageId: "id", data: { actual: true });
},
} This is makes sure that all placeholders can be replaced (especially now that |
Looks like one test is failing now.
|
I think this would need another RFC. Could you please open a separate issue to discuss this? |
Sorry for the delay. I fixed up the mentioned error messages and added a test case for when the |
I think the case described in #17654 (comment) hasn't been addressed. |
lib/rule-tester/rule-tester.js
Outdated
if (!message.suggestions) { | ||
assert.ok(!error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0), `Error should have suggestions on error with message: "${message.message}"`); | ||
} else if (!error.suggestions || Array.isArray(error.suggestions) && error.suggestions.length === 0) { | ||
assert.ok(message.suggestions.length === 0, `Error should have no suggestions on error with message: "${message.message}"`); | ||
} else { |
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 (!message.suggestions) { | |
assert.ok(!error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0), `Error should have suggestions on error with message: "${message.message}"`); | |
} else if (!error.suggestions || Array.isArray(error.suggestions) && error.suggestions.length === 0) { | |
assert.ok(message.suggestions.length === 0, `Error should have no suggestions on error with message: "${message.message}"`); | |
} else { | |
if (!error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0)) { | |
if (message.suggestions) { | |
assert.fail(`Error should have no suggestions on error with message: "${message.message}"`); | |
} | |
} else { | |
if (!message.suggestions) { | |
assert.fail(`Error should have suggestions on error with message: "${message.message}"`); | |
} |
I think we can simplify this to avoid duplicating the !error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0
condition.
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 thought some more about it and I think assigning a hasSuggestions
+ expectSuggestions
variables and collapsing the second branch is easier to understand (see the new commits).
Looks good so far. I think the only remaining thing is to check if the received message has suggestions in this case: eslint/lib/rule-tester/rule-tester.js Lines 959 to 962 in 10485e8
|
lib/rule-tester/rule-tester.js
Outdated
@@ -916,6 +920,7 @@ class RuleTester { | |||
|
|||
// Just an error message. | |||
assertMessageMatches(message.message, error); | |||
assert.ok(message.suggestions === void 0 || message.suggestions.length === 0, `The message has untested. suggestions. Please convert the error at index ${i} into an object by assigning this message to a 'message' property.`); |
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.
assert.ok(message.suggestions === void 0 || message.suggestions.length === 0, `The message has untested. suggestions. Please convert the error at index ${i} into an object by assigning this message to a 'message' property.`); | |
assert.ok(message.suggestions === void 0, `Error at index ${i} has suggestions. Please convert the test error into an object and specify 'suggestions' property on it to test suggestions.`); |
For consistency with the check and the error message in the other case.
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, thanks!
Great work on this! |
Prerequisites checklist
What is the purpose of this pull request? (put an "X" next to an item)
Implements part of RFC 84, refs #15104.
As the responding issue is closed, but still planned for v9, I decided to create a draft PR with only the first check implemented.
If this PR is unwanted, free feel to close it.
My plan, if this PR is accepted, is to create one commit per check only for
RuleTester
, then add documentation as some details may change and at last port the changes toFlatRuleTester
.[ ] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofix to a rule
[ ] Add a CLI option
[ ] Add something to the core
[x] Other, please explain: Rule Tester
What changes did you make? (Give an overview)
Assertions added to invalid test case error objects:
Assertions added to invalid test case suggestion objects:
Assertions added to all test cases:
Is there anything you'd like reviewers to focus on?
How should the added suggestion matchers for existing core rule be handled?
For the suggestion existence check there are currently 18 missing suggestions from 2 rules.
Should I put them in the same commit as the check, as a separate commit or fix them all at the end?