Skip to content

Commit fb549e1

Browse files
committed
1 parent cc7e893 commit fb549e1

File tree

6 files changed

+205
-67
lines changed

6 files changed

+205
-67
lines changed

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

+9-4
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,24 @@ use crate::{
1212
rule::Rule,
1313
utils::{
1414
collect_possible_jest_call_node, get_test_plugin_name, parse_jest_fn_call, JestFnKind,
15-
JestGeneralFnKind, ParsedJestFnCallNew, PossibleJestNode,
15+
JestGeneralFnKind, ParsedJestFnCallNew, PossibleJestNode, TestPluginName,
1616
},
1717
};
1818

19-
fn consistent_method(x0: &str, x1: &str, x2: &str, span0: Span) -> OxcDiagnostic {
19+
fn consistent_method(x0: TestPluginName, x1: &str, x2: &str, span0: Span) -> OxcDiagnostic {
2020
OxcDiagnostic::warn(format!(
2121
"{x0}(consistent-test-it): Enforce `test` and `it` usage conventions",
2222
))
2323
.with_help(format!("Prefer using {x1:?} instead of {x2:?}"))
2424
.with_label(span0)
2525
}
2626

27-
fn consistent_method_within_describe(x0: &str, x1: &str, x2: &str, span0: Span) -> OxcDiagnostic {
27+
fn consistent_method_within_describe(
28+
x0: TestPluginName,
29+
x1: &str,
30+
x2: &str,
31+
span0: Span,
32+
) -> OxcDiagnostic {
2833
OxcDiagnostic::warn(format!(
2934
"{x0}(consistent-test-it): Enforce `test` and `it` usage conventions",
3035
))
@@ -211,7 +216,7 @@ impl ConsistentTestIt {
211216
fn run<'a>(
212217
&self,
213218
describe_nesting_hash: &mut FxHashMap<ScopeId, i32>,
214-
plugin_name: &str,
219+
plugin_name: TestPluginName,
215220
possible_jest_node: &PossibleJestNode<'a, '_>,
216221
ctx: &LintContext<'a>,
217222
) {

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
rule::Rule,
99
utils::{
1010
collect_possible_jest_call_node, get_test_plugin_name, parse_general_jest_fn_call,
11-
JestFnKind, JestGeneralFnKind, ParsedGeneralJestFnCall, PossibleJestNode,
11+
JestFnKind, JestGeneralFnKind, ParsedGeneralJestFnCall, PossibleJestNode, TestPluginName,
1212
},
1313
};
1414

@@ -63,7 +63,12 @@ declare_oxc_lint!(
6363
correctness
6464
);
6565

66-
fn no_disabled_tests_diagnostic(x0: &str, x1: &str, x2: &str, span3: Span) -> OxcDiagnostic {
66+
fn no_disabled_tests_diagnostic(
67+
x0: TestPluginName,
68+
x1: &str,
69+
x2: &str,
70+
span3: Span,
71+
) -> OxcDiagnostic {
6772
OxcDiagnostic::warn(format!("{x0}(no-disabled-tests): {x1:?}"))
6873
.with_help(format!("{x2:?}"))
6974
.with_label(span3)
@@ -103,7 +108,7 @@ impl Rule for NoDisabledTests {
103108

104109
fn run<'a>(
105110
possible_jest_node: &PossibleJestNode<'a, '_>,
106-
plugin_name: &str,
111+
plugin_name: TestPluginName,
107112
ctx: &LintContext<'a>,
108113
) {
109114
let node = possible_jest_node.node;

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

+91-21
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,24 @@ use crate::{
77
context::LintContext,
88
rule::Rule,
99
utils::{
10-
collect_possible_jest_call_node, parse_general_jest_fn_call, JestFnKind, JestGeneralFnKind,
11-
MemberExpressionElement, ParsedGeneralJestFnCall, PossibleJestNode,
10+
collect_possible_jest_call_node, get_test_plugin_name, parse_general_jest_fn_call,
11+
JestFnKind, JestGeneralFnKind, MemberExpressionElement, ParsedGeneralJestFnCall,
12+
PossibleJestNode, TestPluginName,
1213
},
1314
};
1415

15-
fn no_focused_tests_diagnostic(span0: Span) -> OxcDiagnostic {
16-
OxcDiagnostic::warn("eslint-plugin-jest(no-focused-tests): Unexpected focused test.")
17-
.with_help("Remove focus from test.")
18-
.with_label(span0)
16+
fn no_focused_tests_diagnostic(span0: Span, x1: TestPluginName) -> OxcDiagnostic {
17+
match x1 {
18+
TestPluginName::Jest => {
19+
OxcDiagnostic::warn(format!("{x1}(no-focused-tests): Unexpected focused test."))
20+
.with_help("Remove focus from test.")
21+
.with_label(span0)
22+
}
23+
TestPluginName::Vitest => {
24+
OxcDiagnostic::warn(format!("{x1}(no-focused-tests): Focused tests are not allowed."))
25+
.with_label(span0)
26+
}
27+
}
1928
}
2029

2130
#[derive(Debug, Default, Clone)]
@@ -49,19 +58,35 @@ declare_oxc_lint!(
4958
/// table
5059
/// `();
5160
/// ```
61+
///
62+
/// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md),
63+
/// to use it, add the following configuration to your `.eslintrc.json`:
64+
///
65+
/// ```json
66+
/// {
67+
/// "rules": {
68+
/// "vitest/no-focused-tests": "error"
69+
/// }
70+
/// }
71+
/// ```
5272
NoFocusedTests,
5373
correctness
5474
);
5575

5676
impl Rule for NoFocusedTests {
5777
fn run_once(&self, ctx: &LintContext) {
78+
let plugin_name = get_test_plugin_name(ctx);
5879
for node in &collect_possible_jest_call_node(ctx) {
59-
run(node, ctx);
80+
run(node, plugin_name, ctx);
6081
}
6182
}
6283
}
6384

64-
fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) {
85+
fn run<'a>(
86+
possible_jest_node: &PossibleJestNode<'a, '_>,
87+
plugin_name: TestPluginName,
88+
ctx: &LintContext<'a>,
89+
) {
6590
let node = possible_jest_node.node;
6691
let AstKind::CallExpression(call_expr) = node.kind() else {
6792
return;
@@ -75,30 +100,40 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>)
75100
}
76101

77102
if name.starts_with('f') {
78-
ctx.diagnostic_with_fix(no_focused_tests_diagnostic(call_expr.span), |fixer| {
79-
fixer.delete_range(Span::sized(call_expr.span.start, 1))
80-
});
103+
ctx.diagnostic_with_fix(
104+
no_focused_tests_diagnostic(
105+
Span::new(
106+
call_expr.span.start,
107+
call_expr.span.start + u32::try_from(name.len()).unwrap_or(1),
108+
),
109+
plugin_name,
110+
),
111+
|fixer| fixer.delete_range(Span::sized(call_expr.span.start, 1)),
112+
);
81113

82114
return;
83115
}
84116

85117
let only_node = members.iter().find(|member| member.is_name_equal("only"));
86118
if let Some(only_node) = only_node {
87-
ctx.diagnostic_with_fix(no_focused_tests_diagnostic(call_expr.span), |fixer| {
88-
let mut span = only_node.span.expand_left(1);
89-
if !matches!(only_node.element, MemberExpressionElement::IdentName(_)) {
90-
span = span.expand_right(1);
91-
}
92-
fixer.delete_range(span)
93-
});
119+
ctx.diagnostic_with_fix(
120+
no_focused_tests_diagnostic(only_node.span, plugin_name),
121+
|fixer| {
122+
let mut span = only_node.span.expand_left(1);
123+
if !matches!(only_node.element, MemberExpressionElement::IdentName(_)) {
124+
span = span.expand_right(1);
125+
}
126+
fixer.delete_range(span)
127+
},
128+
);
94129
}
95130
}
96131

97132
#[test]
98133
fn test() {
99134
use crate::tester::Tester;
100135

101-
let pass = vec![
136+
let mut pass = vec![
102137
("describe()", None),
103138
("it()", None),
104139
("describe.skip()", None),
@@ -114,7 +149,7 @@ fn test() {
114149
("test.concurrent()", None),
115150
];
116151

117-
let fail = vec![
152+
let mut fail = vec![
118153
("describe.only()", None),
119154
// TODO: this need set setting like `settings: { jest: { globalAliases: { describe: ['context'] } } },`
120155
// ("context.only()", None),
@@ -137,12 +172,47 @@ fn test() {
137172
("fit.each`table`()", None),
138173
];
139174

140-
let fix = vec![
175+
let mut fix = vec![
141176
("describe.only('foo', () => {})", "describe('foo', () => {})", None),
142177
("describe['only']('foo', () => {})", "describe('foo', () => {})", None),
143178
("fdescribe('foo', () => {})", "describe('foo', () => {})", None),
144179
];
145180

181+
let pass_vitest = vec![
182+
(r#"it("test", () => {});"#, None),
183+
(r#"describe("test group", () => {});"#, None),
184+
(r#"it("test", () => {});"#, None),
185+
(r#"describe("test group", () => {});"#, None),
186+
];
187+
188+
let fail_vitest = vec![
189+
(
190+
r#"
191+
import { it } from 'vitest';
192+
it.only("test", () => {});
193+
"#,
194+
None,
195+
),
196+
(r#"describe.only("test", () => {});"#, None),
197+
(r#"test.only("test", () => {});"#, None),
198+
(r#"it.only.each([])("test", () => {});"#, None),
199+
(r#"test.only.each``("test", () => {});"#, None),
200+
(r#"it.only.each``("test", () => {});"#, None),
201+
];
202+
203+
let fix_vitest = vec![
204+
(r#"it.only("test", () => {});"#, r#"it("test", () => {});"#, None),
205+
(r#"describe.only("test", () => {});"#, r#"describe("test", () => {});"#, None),
206+
(r#"test.only("test", () => {});"#, r#"test("test", () => {});"#, None),
207+
(r#"it.only.each([])("test", () => {});"#, r#"it.each([])("test", () => {});"#, None),
208+
(r#"test.only.each``("test", () => {});"#, r#"test.each``("test", () => {});"#, None),
209+
(r#"it.only.each``("test", () => {});"#, r#"it.each``("test", () => {});"#, None),
210+
];
211+
212+
pass.extend(pass_vitest);
213+
fail.extend(fail_vitest);
214+
fix.extend(fix_vitest);
215+
146216
Tester::new(NoFocusedTests::NAME, pass, fail)
147217
.with_jest_plugin(true)
148218
.expect_fix(fix)

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ use crate::{
1010
rule::Rule,
1111
utils::{
1212
get_test_plugin_name, parse_jest_fn_call, JestFnKind, JestGeneralFnKind,
13-
ParsedJestFnCallNew, PossibleJestNode,
13+
ParsedJestFnCallNew, PossibleJestNode, TestPluginName,
1414
},
1515
};
1616

17-
fn reorder_hooks(x0: &str, x1: &str, x2: &str, span0: Span) -> OxcDiagnostic {
17+
fn reorder_hooks(x0: TestPluginName, x1: &str, x2: &str, span0: Span) -> OxcDiagnostic {
1818
OxcDiagnostic::warn(format!(
1919
"{x0}(prefer-hooks-in-order): Prefer having hooks in a consistent order.",
2020
))

0 commit comments

Comments
 (0)