Skip to content

Commit 14f790f

Browse files
authored
fix(linter): improve jest/no-restricted-matchers (#11292)
- re-word diagnostic messages ("Disallow specific matchers & modifiers" => "Use of `{chain_call}` is disallowed") - add section describing how configuring this rule works - minor other code refactorings to improve readability
1 parent 3a49220 commit 14f790f

File tree

2 files changed

+54
-45
lines changed

2 files changed

+54
-45
lines changed

crates/oxc_linter/src/rules/jest/no_restricted_matchers.rs

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,14 @@ use crate::{
1515
},
1616
};
1717

18-
// TODO: re-word diagnostic messages
19-
fn restricted_chain(x0: &str, span1: Span) -> OxcDiagnostic {
20-
OxcDiagnostic::warn("Disallow specific matchers & modifiers")
21-
.with_help(format!("Use of `{x0:?}` is disallowed`"))
22-
.with_label(span1)
18+
fn restricted_chain(chain_call: &str, span: Span) -> OxcDiagnostic {
19+
OxcDiagnostic::warn(format!("Use of `{chain_call}` is disallowed")).with_label(span)
2320
}
2421

25-
fn restricted_chain_with_message(x0: &str, span1: Span) -> OxcDiagnostic {
26-
OxcDiagnostic::warn("Disallow specific matchers & modifiers")
27-
.with_help(format!("{x0:?}"))
28-
.with_label(span1)
22+
fn restricted_chain_with_message(chain_call: &str, message: &str, span: Span) -> OxcDiagnostic {
23+
OxcDiagnostic::warn(format!("Use of `{chain_call}` is disallowed"))
24+
.with_help(message.to_string())
25+
.with_label(span)
2926
}
3027

3128
#[derive(Debug, Default, Clone)]
@@ -51,9 +48,33 @@ declare_oxc_lint!(
5148
///
5249
/// ### Examples
5350
///
54-
/// Examples of **incorrect** code for this rule:
55-
/// ```javascript
51+
/// Bans are expressed in the form of a map, with the value being either a string message to be shown,
52+
/// or null if only the default rule message should be used. Bans are checked against the start of
53+
/// the expect chain - this means that to ban a specific matcher entirely you must specify all
54+
/// six permutations, but allows you to ban modifiers as well. By default, this map is empty, meaning
55+
/// no matchers or modifiers are banned.
56+
///
57+
/// Example configuration:
58+
/// ```json
59+
/// {
60+
/// "jest/no-restricted-matchers": [
61+
/// "error",
62+
/// {
63+
/// "toBeFalsy": null,
64+
/// "resolves": "Use `expect(await promise)` instead.",
65+
/// "toHaveBeenCalledWith": null,
66+
/// "not.toHaveBeenCalledWith": null,
67+
/// "resolves.toHaveBeenCalledWith": null,
68+
/// "rejects.toHaveBeenCalledWith": null,
69+
/// "resolves.not.toHaveBeenCalledWith": null,
70+
/// "rejects.not.toHaveBeenCalledWith": null
71+
/// }
72+
/// ]
73+
/// }
74+
/// ```
5675
///
76+
/// Examples of **incorrect** code for this rule with the above configuration:
77+
/// ```javascript
5778
/// it('is false', () => {
5879
/// // if this has a modifier (i.e. `not.toBeFalsy`), it would be considered fine
5980
/// expect(a).toBeFalsy();
@@ -80,15 +101,13 @@ const MODIFIER_NAME: [&str; 3] = ["not", "rejects", "resolves"];
80101

81102
impl Rule for NoRestrictedMatchers {
82103
fn from_configuration(value: serde_json::Value) -> Self {
83-
let restricted_matchers = &value
104+
let restricted_matchers = value
84105
.get(0)
85106
.and_then(serde_json::Value::as_object)
86107
.map(Self::compile_restricted_matchers)
87108
.unwrap_or_default();
88109

89-
Self(Box::new(NoRestrictedMatchersConfig {
90-
restricted_matchers: restricted_matchers.clone(),
91-
}))
110+
Self(Box::new(NoRestrictedMatchersConfig { restricted_matchers }))
92111
}
93112

94113
fn run_on_jest_node<'a, 'c>(
@@ -135,7 +154,7 @@ impl NoRestrictedMatchers {
135154
if message.is_empty() {
136155
ctx.diagnostic(restricted_chain(&chain_call, span));
137156
} else {
138-
ctx.diagnostic(restricted_chain_with_message(message, span));
157+
ctx.diagnostic(restricted_chain_with_message(&chain_call, message, span));
139158
}
140159
}
141160
}
@@ -145,10 +164,10 @@ impl NoRestrictedMatchers {
145164
if MODIFIER_NAME.contains(&restriction)
146165
|| Path::new(restriction).extension().is_some_and(|ext| ext.eq_ignore_ascii_case("not"))
147166
{
148-
return chain_call.starts_with(restriction);
167+
chain_call.starts_with(restriction)
168+
} else {
169+
chain_call == restriction
149170
}
150-
151-
chain_call == restriction
152171
}
153172

154173
pub fn compile_restricted_matchers(
Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,85 @@
11
---
22
source: crates/oxc_linter/src/tester.rs
33
---
4-
eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
4+
eslint-plugin-jest(no-restricted-matchers): Use of `toBe` is disallowed
55
╭─[no_restricted_matchers.tsx:1:11]
66
1expect(a).toBe(b)
77
· ────
88
╰────
9-
help: Use of `"toBe"` is disallowed`
109

11-
⚠ eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
10+
eslint-plugin-jest(no-restricted-matchers): Use of `toBe` is disallowed
1211
╭─[no_restricted_matchers.tsx:1:11]
1312
1expect(a)["toBe"](b)
1413
· ──────
1514
╰────
16-
help: Use of `"toBe"` is disallowed`
1715

18-
eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
16+
eslint-plugin-jest(no-restricted-matchers): Use of `not` is disallowed
1917
╭─[no_restricted_matchers.tsx:1:11]
2018
1expect(a).not[x]()
2119
· ───
2220
╰────
23-
help: Use of `"not"` is disallowed`
2421

25-
⚠ eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
22+
eslint-plugin-jest(no-restricted-matchers): Use of `not.toBe` is disallowed
2623
╭─[no_restricted_matchers.tsx:1:11]
2724
1expect(a).not.toBe(b)
2825
· ────────
2926
╰────
30-
help: Use of `"not.toBe"` is disallowed`
3127

32-
eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
28+
eslint-plugin-jest(no-restricted-matchers): Use of `resolves.toBe` is disallowed
3329
╭─[no_restricted_matchers.tsx:1:11]
3430
1expect(a).resolves.toBe(b)
3531
· ─────────────
3632
╰────
37-
help: Use of `"resolves.toBe"` is disallowed`
3833

39-
⚠ eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
34+
eslint-plugin-jest(no-restricted-matchers): Use of `resolves.not.toBe` is disallowed
4035
╭─[no_restricted_matchers.tsx:1:11]
4136
1expect(a).resolves.not.toBe(b)
4237
· ─────────────────
4338
╰────
44-
help: Use of `"resolves.not.toBe"` is disallowed`
4539

46-
eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
40+
eslint-plugin-jest(no-restricted-matchers): Use of `resolves.not.toBe` is disallowed
4741
╭─[no_restricted_matchers.tsx:1:11]
4842
1expect(a).resolves.not.toBe(b)
4943
· ─────────────────
5044
╰────
51-
help: Use of `"resolves.not.toBe"` is disallowed`
5245

53-
⚠ eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
46+
eslint-plugin-jest(no-restricted-matchers): Use of `not.toBe` is disallowed
5447
╭─[no_restricted_matchers.tsx:1:11]
5548
1expect(a).not.toBe(b)
5649
· ────────
5750
╰────
58-
help: Use of `"not.toBe"` is disallowed`
5951

60-
eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
52+
eslint-plugin-jest(no-restricted-matchers): Use of `resolves.not.toBe` is disallowed
6153
╭─[no_restricted_matchers.tsx:1:11]
6254
1expect(a).resolves.not.toBe(b)
6355
· ─────────────────
6456
╰────
65-
help: Use of `"resolves.not.toBe"` is disallowed`
6657

67-
⚠ eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
58+
eslint-plugin-jest(no-restricted-matchers): Use of `toBe` is disallowed
6859
╭─[no_restricted_matchers.tsx:1:11]
6960
1expect(a).toBe(b)
7061
· ────
7162
╰────
72-
help: "Prefer `toStrictEqual` instead"
63+
help: Prefer `toStrictEqual` instead
7364

74-
⚠ eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
65+
eslint-plugin-jest(no-restricted-matchers): Use of `resolves.toBe` is disallowed
7566
╭─[no_restricted_matchers.tsx:3:54]
7667
2test('some test', async () => {
7768
3await expect(Promise.resolve(1)).resolves.toBe(1);
7869
· ─────────────
7970
4 │ });
8071
╰────
81-
help: "Use `expect(await promise)` instead."
72+
help: Use `expect(await promise)` instead.
8273

83-
⚠ eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
74+
eslint-plugin-jest(no-restricted-matchers): Use of `rejects.toBeFalsy` is disallowed
8475
╭─[no_restricted_matchers.tsx:1:29]
8576
1expect(Promise.resolve({})).rejects.toBeFalsy()
8677
· ─────────────────
8778
╰────
88-
help: Use of `"rejects.toBeFalsy"` is disallowed`
8979

90-
eslint-plugin-jest(no-restricted-matchers): Disallow specific matchers & modifiers
80+
eslint-plugin-jest(no-restricted-matchers): Use of `not.toHaveBeenCalledWith` is disallowed
9181
╭─[no_restricted_matchers.tsx:1:24]
9282
1expect(uploadFileMock).not.toHaveBeenCalledWith('file.name')
9383
· ────────────────────────
9484
╰────
95-
help: "Use not.toHaveBeenCalled instead"
85+
help: Use not.toHaveBeenCalled instead

0 commit comments

Comments
 (0)