feat: add assertion options to RuleTester#137
feat: add assertion options to RuleTester#137fasttime merged 22 commits intoeslint:mainfrom ST-DDT:2025-rule-tester-assertion-options
Conversation
|
I think it's a great idea to drive this kind of consistency, but I do wonder if this is the best place to set that kind of expectation. It seems like something that might be more appropriate as an eslint rule in |
nzakas
left a comment
There was a problem hiding this comment.
Thanks for putting this together. I left some comments inline.
|
I think I covered all comments. |
|
All addressed |
|
All addressed |
|
All pending comments addressed. |
|
All pending comments addressed. |
fasttime
left a comment
There was a problem hiding this comment.
I left a suggestion, but otherwise LGTM.
Co-authored-by: Francesco Trotta <github@fasttime.org>
| * | ||
| * @default false | ||
| */ | ||
| requireMessage?: boolean | 'message' | 'messageId'; |
There was a problem hiding this comment.
I think there should be an extra assertion to disallow using a number for errors (maybe named disallowErrorShorthand).
As a result the boolean variant would be useless as the rule tester checks this by default for error objects.
Further this allows an easier migration, as the plugin maintainers can gradually enable the rules by either:
- First disallowing the error shorthand and then requiring the properties
- First adding the required location or message properties and then handling the error shorthands
There was a problem hiding this comment.
Just for clarification, so instead of
errors: 5
You have to use
A) errors: ['foo',...]
or B) errors: [{...}]
There was a problem hiding this comment.
This is dependent on the other assertions.
- none: allows both
requireMessage: "message"would allow both as the message providedrequireMessage: "messageId"would only allow B) as the message is providedrequireLocation: truewould only allow B) as a location is required
There was a problem hiding this comment.
IMO this is entirely/mostly covered by adding requireMessage.
What do the others think?
There was a problem hiding this comment.
@DMartens Are you suggesting that requireMessage and requireLocation alone should not disallow numeric values for errors, and instead there should be a separate option to do so?
There was a problem hiding this comment.
So if disallowShorthand is false/undefined, you can just use the error count even if requireMessage is enabled?
I dont like that. Because then it behaves like requireMessage/location isnt set in the first place.
There was a problem hiding this comment.
We can handle the option as true by default (when not specified) for the other options but I think the possibility to differentiate should be there.
There was a problem hiding this comment.
The requirement for errors to include either a message or messageId was discussed in #84. While this makes sense in many scenarios, it can be bypassed by specifying errors as a number (accepting all the implied limitations of doing so). That discussion also affirmed that using a numeric value for errors remains a valid option.
Given that ESLint has supported this behavior by default, I tend to agree with @DMartens that it makes sense to maintain the possibility of specifying a number for errors, even if requireMessage will enforce one of message or messageId when errors is an array. I'm open to revisiting the scope of this RFC if the team can reach an agreement.
There was a problem hiding this comment.
I'm not sure I agree that we should make a change here. To me, if someone wants to use errors: number, then they wouldn't opt-in to these assertions in the first place.
I think requireMessage: true explicitly affirms that someone does not want to allow errors: number.
There was a problem hiding this comment.
I think this is solved with the mentioned additional assertion disallowErrorShorthand, which defaults to true.
This keeps the current proposed behavior but allows users to opt-out.
This behaviour could also be implemented with requireMessage: false but I think disallowErrorShorthand should be preferred as requireLoc (and maybe requireData) is also affected.
| * @default false | ||
| */ | ||
| requireLocation?: boolean; | ||
| }, |
There was a problem hiding this comment.
Another helpful check would be requireData which requires the data error property when a messageId is used and the referenced message has placeholders ({{ placeholder }}).
There was a problem hiding this comment.
Would this imply requireMessage: 'messageId'?
There was a problem hiding this comment.
I also considered requiring the data block (if needed) into requireMessage: 'messageId'.
What do you+the others think?
There was a problem hiding this comment.
This would not imply requireMessage: 'messageId' as the message already has the placeholders filled in. So there is no need for data.
There was a problem hiding this comment.
I'm not sure whether I understand the last comment.
IMO requireData results in ({data: *})[]
AFAICT The current code only checks for data in the messageId block. Which makes sense to me, as data is used to fill in the placeholders in its message.
Most messageId checks are very broad as most rules only have one or two messages. So also checking for data is kind of relevant. Which is why I would implicitly attach it to the requireMessageId option.
There was a problem hiding this comment.
This option (requireData) should only be active when the error has a messageId as data is useless when message is specified (you already provide the message with every placeholder filled in).
The validator only has to check whether data is specified as there is already an error when data is specified and placeholders are missing.
Coupling this with the requireMessage: "messageId" would be unintuitive as that reads as only the "messageId" is required.
There was a problem hiding this comment.
I agree a requireData assertion could be helpful. As this would be a separate option, it could be also discussed in a follow-up RFC.
There was a problem hiding this comment.
Agreed, the scope of this RFC is already well-defined and I don't think we should be expanding at this point in time. @DMartens feel free to open an issue to start the discussion around a requireData assertion option.
nzakas
left a comment
There was a problem hiding this comment.
I'm happy with the current state of this RFC.
|
@fasttime can you check if your review comments have been addressed? |
|
Yes, I see both of the suggestions to be non-blocking:
|
|
Moving to final commenting. |
|
No further comments here, so merging. |
|
Should I create a PR for the implementation now? |
@ST-DDT yes, please! Issue eslint/eslint#19921 is already assigned to you. |
Summary
Add options that control which assertions are required for each
RuleTestertest case.Related Issues
The idea was initially sparked by this comment: vuejs/eslint-plugin-vue#2773 (comment)
The first steps have been taken in: eslint/eslint#19904
This lead to the issue that this RFC is based on: eslint/eslint#19921