Skip to content

Commit 049c2d3

Browse files
authored
docs: add object support for combined reason and validation (fixes #61570 requirement)
1 parent 036ee9c commit 049c2d3

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

proposals/expect-failure-enhancements.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Feature proposal: `expectFailure` enhancements
22

33
## Summary
4-
Update the `expectFailure` option in `test()` to accept different types of values, enabling both **custom failure messages** and **error validation**. This aligns with `skip` and `todo` options while adding capabilities similar to `assert.throws`.
4+
Update the `expectFailure` option in `test()` to accept different types of values, enabling both **custom failure messages** and **error validation**. This proposal integrates the requirements from [nodejs/node#61570](https://github.com/nodejs/node/issues/61570), ensuring consistency with `skip`/`todo` while adding robust validation capabilities.
55

66
## API & Behavior
77

8-
The behavior of `expectFailure` is determined by the type of value provided:
8+
The behavior of `expectFailure` is strictly determined by the type of value provided:
99

1010
### 1. String: Failure Reason
1111
When a **non-empty string** is provided, it acts as a documentation message (reason), identical to `skip` and `todo` options.
@@ -20,7 +20,6 @@ test('fails with a specific reason', {
2020
- **Behavior**: The test is expected to fail. The string is treated as a label/reason.
2121
- **Validation**: None. It accepts *any* error.
2222
- **Output**: The reporter displays the string (e.g., `# EXPECTED FAILURE Bug #123...`).
23-
- **Rationale**: Maintains consistency with existing `test` options where a string implies a reason/description.
2423

2524
### 2. RegExp: Error Matcher
2625
When a **RegExp** is provided, it acts as a validator for the thrown error.
@@ -36,24 +35,41 @@ test('fails with matching error', {
3635
- **Validation**: Strict matching against the error message.
3736
- **Output**: Standard expected failure output.
3837

39-
## Ambiguity Resolution
40-
Potential ambiguity between "String as Reason" and "String as Matcher" is resolved by strict type separation:
41-
* `typeof value === 'string'`**Reason** (Documentation only)
42-
* `value instanceof RegExp`**Matcher** (Validation)
38+
### 3. Object: Reason & Validation
39+
When an **Object** is provided, it allows specifying both a failure reason and validation logic simultaneously.
40+
41+
```js
42+
test('fails with reason and specific error', {
43+
expectFailure: {
44+
message: 'Bug #123: Edge case behavior', // Reason
45+
match: /Index out of bounds/ // Validation
46+
}
47+
}, () => {
48+
throw new RangeError('Index out of bounds');
49+
});
50+
```
51+
- **Properties**:
52+
- `message` (String): The failure reason/label (displayed in reporter).
53+
- `match` (RegExp | Object | Function): Validation logic (similar to `assert.throws` validation argument).
54+
- **Behavior**: The test passes **only if** the error matches the `match` criteria.
55+
- **Output**: The reporter displays the `message`.
4356

44-
Users needing to match a specific string error message should use a RegExp (e.g., `/Error message/`) to avoid confusion.
57+
## Ambiguity Resolution
58+
Potential ambiguity is resolved by strict type separation:
59+
* `typeof value === 'string'`**Reason**
60+
* `value instanceof RegExp`**Matcher**
61+
* `typeof value === 'object'`**Both** (Explicit properties)
4562

4663
## Edge Cases & Implementation Details
4764

4865
### Empty String (`expectFailure: ''`)
4966
Following standard JavaScript truthiness rules, an empty string should be treated as **falsy**.
50-
5167
* `expectFailure: ''` behaves exactly like `expectFailure: false`.
5268
* The feature is **disabled**, and the test is expected to pass normally.
5369

5470
### Type Safety for `this.passed`
5571
The implementation must ensure that `this.passed` remains a strict `boolean`.
56-
Assigning a string directly (e.g., `this.passed = this.expectFailure`) is unsafe as it introduces type pollution (assigning `""` or `"reason"` instead of `false`/`true`).
72+
Assigning a string directly (e.g., `this.passed = this.expectFailure`) is unsafe as it introduces type pollution.
5773

5874
**Recommended Implementation Logic:**
5975
```javascript

0 commit comments

Comments
 (0)