-
-
Notifications
You must be signed in to change notification settings - Fork 5
doc(proposal): add expectFailure enhancements #10
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: main
Are you sure you want to change the base?
Conversation
|
@Han5991 this should reference nodejs/node#61570 which goes beyond nodejs/node#61563. It may end up being the case that a fix for the latter lands before the former, since the latter is relatively trivial and simply brings --EDIT-- I'm a little confused. Your first proposal, #9, included a way to supply both a reason and an expected error as I proposed in nodejs/node#61570, but this one does not. |
…1570 requirement)
|
Sorry for the confusion. PR #9 was accidentally opened from my other account, so I closed it and opened this one instead. |
|
Alternative syntaxes to consider for supplying both reason and expected error: test('fails with reason and specific error', {
expectFailure: 'Bug #123: Edge case behavior',
expectFailureMessage: /err msg pattern/
}, () => ...);or for consistency with test('fails with reason and specific error', {
expectFailure: 'Bug #123: Edge case behavior',
expectFailureError: <RegExp> | <Function> | <Object> | <Error>
}, () => ...);The user can supply either one of the two new options or both. |
|
Consistency with |
|
Thanks for the feedback! Implementation: |
|
the terseness and legibility of with+message is very nice. as i said on your PR, it gets my top vote. |
Update the `expectFailure` enhancements proposal based on feedback and implementation alignment:
- Consolidate validation logic under the `with` property within an object.
- Remove direct RegExp support in favor of the object syntax for consistency.
- Specify usage of `assert.throws` for robust error validation.
- Document alternatives considered (flat options).
|
IIR, we had originally envisioned it('should do the thing', { expectFailure: 'chromium#1234' }, () => {…});
it('should do another thing', { expectFailure: /some telltale needle/ }, () => {…});
it('should do something else', { expectFailure: new RangeError(…) }, () => {…});Where matcher would follow the behaviour of |
0de23a6 to
abb5912
Compare
6e1e4a8 to
87802e3
Compare
I've updated the proposal to reflect the latest feedback. Ready for re-review! |
Explicitly state that passing an empty object ({}) to expectFailure should throw ERR_INVALID_ARG_VALUE to prevent ambiguity and potential user error.
|
RE the back and forth on whether I agree with @ljharb in general, but in this specific case it will result in Also, given the specificity of the linked |
JakobJingleheimer
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 this!
I think some whitespace is amiss (e.g. too many spaces between * and the text, too much indentation, missing blank line between heading and its content, etc).
| message: 'Bug #123: Edge case behavior', // Reason | ||
| with: /Index out of bounds/ // Validation |
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 these keys are a bit ambiguous. I think message → label and with → match (or matcher or matching, or perhaps error?)
| 'must not be an empty object' | ||
| ); | ||
| ``` | ||
| * If the object contains `with` or `message` properties → **Configuration Object**. |
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 if it contains either or both but no more → config object
- Update property names to match/label in description to match code examples. - Fix markdown formatting (whitespace, blank lines) as requested.
|
Thanks for the detailed review! I've updated the proposal to address your feedback |
JakobJingleheimer
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.
🙌 LGTM aside from the small revert needed because of my mistaken assumption.
| When a **RegExp**, **Class** (Function), or **Error Object** is provided directly, it acts as the validation logic. This leverages `assert.throws` behavior directly. | ||
| ### Matcher: Error constructor, Error-like object, RegExp, or validation function | ||
|
|
||
| When a `Error` constructor, `Error`-like object, `RegExp`, or validation function is provided, it is treated as validation to match against, mirroring the behaviour of [`assert.throws`](https://nodejs.org/docs/latest-v25.x/api/assert.html#assertthrowsfn-error-message) (possibly leveraging it under the hood). |
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.
nit 😅
| When a `Error` constructor, `Error`-like object, `RegExp`, or validation function is provided, it is treated as validation to match against, mirroring the behaviour of [`assert.throws`](https://nodejs.org/docs/latest-v25.x/api/assert.html#assertthrowsfn-error-message) (possibly leveraging it under the hood). | |
| When an `Error` constructor, `Error`-like object, `RegExp`, or validation function is provided, it is treated as validation to match against, mirroring the behaviour of [`assert.throws`](https://nodejs.org/docs/latest-v25.x/api/assert.html#assertthrowsfn-error-message) (possibly leveraging it under the hood). |
| * The feature is **disabled** only if `expectFailure` is `undefined` or `false`. | ||
| * **All other values** enable the feature (treat as truthy). | ||
| * `expectFailure: ''` (Empty String) → **Enabled** (treats as generic failure expectation). | ||
| * `expectFailure: 0` → **Enabled** (treated as a Matcher Object unless specific logic excludes numbers, but per consistency it enables the feature). | ||
| * The feature is **disabled** if `expectFailure` is **falsy** (e.g., `false`, `null`, `undefined`, `0`, `''`). | ||
| * **Truthy values** enable the feature. |
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.
Whoops, sorry, I was wrong about this: #10 (comment)
You can revert this part of the change—it was good/correct before.
ljharb
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.
LGTM overall
| ``` | ||
| - **Behavior**: The test is expected to fail. The string is treated as a label/reason. | ||
| - **Validation**: None. It accepts _any_ error. | ||
| - **Output**: The reporter displays the string literally (e.g., `# EXPECTED FAILURE Bug #123…`). |
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.
| - **Output**: The reporter displays the string literally (e.g., `# EXPECTED FAILURE Bug #123…`). | |
| - **Output**: The reporter displays the string literally, prefixed by a TAP comment character (e.g., `# EXPECTED FAILURE Bug #123…`). |
| - **Properties**: | ||
| - `label` (String): The failure reason/label (displayed in reporter). | ||
| - `match` (RegExp | Object | Function | Class): Validation logic. This is passed directly to `assert.throws` validation argument, supporting all its capabilities. | ||
| - **Behavior**: The test passes **only if** the error matches the `match` criteria. | ||
| - **Output**: The reporter displays the `label`. |
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 that either one of these properties must be present, or it should throw - iow, using the object form with just a label is fine, because it reduces diff churn if match is added or removed later; and using the object form with just match is fine, because it reduces diff churn if label is added later - but if you have neither, it's far more likely to be a bug than intentional behavior.
(update: i see further down that this is the case, but imo it should also mention here that one of these two properties must be present)
This PR adds a proposal for enhancing expectFailure to support both custom messages (for reasoning) and validation (matching errors via regex/objects), addressing the needs discussed in nodejs/node#61563.