Skip to content

Commit

Permalink
chore: avoid unnecessary repetition of warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
shulaoda committed Aug 26, 2024
1 parent 7988c3c commit 053676e
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 81 deletions.
51 changes: 39 additions & 12 deletions crates/oxc_linter/src/rules/vitest/prefer_each.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashSet;

use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
Expand Down Expand Up @@ -60,7 +62,16 @@ declare_oxc_lint!(
);

impl Rule for PreferEach {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
fn run_once(&self, ctx: &LintContext<'_>) {
let mut skip = HashSet::<AstNodeId>::new();
ctx.nodes().iter().for_each(|node| {
Self::run(node, ctx, &mut skip);
});
}
}

impl PreferEach {
fn run<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>, skip: &mut HashSet<AstNodeId>) {
let kind = node.kind();

let AstKind::CallExpression(call_expr) = kind else { return };
Expand Down Expand Up @@ -88,19 +99,35 @@ impl Rule for PreferEach {
AstKind::ForStatement(_)
| AstKind::ForInStatement(_)
| AstKind::ForOfStatement(_) => {
if !is_in_test(ctx, parent_node.id()) {
let fn_name = if matches!(
vitest_fn_call.kind(),
JestFnKind::General(JestGeneralFnKind::Test)
) {
"it"
} else {
"describe"
};

ctx.diagnostic(use_prefer_each(call_expr.callee.span(), fn_name));
if skip.contains(&parent_node.id()) || is_in_test(ctx, parent_node.id()) {
return;
}

let fn_name = if matches!(
vitest_fn_call.kind(),
JestFnKind::General(JestGeneralFnKind::Test)
) {
"it"
} else {
"describe"
};

let span = match parent_node.kind() {
AstKind::ForStatement(statement) => {
Span::new(statement.span.start, statement.body.span().start)
}
AstKind::ForInStatement(statement) => {
Span::new(statement.span.start, statement.body.span().start)
}
AstKind::ForOfStatement(statement) => {
Span::new(statement.span.start, statement.body.span().start)
}
_ => unreachable!(),
};

skip.insert(parent_node.id());
ctx.diagnostic(use_prefer_each(span, fn_name));

break;
}
_ => {}
Expand Down
103 changes: 34 additions & 69 deletions crates/oxc_linter/src/snapshots/prefer_each.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,154 +2,119 @@
source: crates/oxc_linter/src/tester.rs
---
eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:2:10]
╭─[prefer_each.tsx:1:3]
1for (const [input, expected] of data) {
· ──────────────────────────────────────
2it(`results in ${expected}`, () => {
· ──
3expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:2:10]
╭─[prefer_each.tsx:1:2]
1for (const [input, expected] of data) {
· ──────────────────────────────────────
2describe(`when the input is ${input}`, () => {
· ────────
3it(`results in ${expected}`, () => {
╰────
help: Prefer using `describe.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:2:10]
╭─[prefer_each.tsx:1:1]
1for (const [input, expected] of data) {
· ──────────────────────────────────────
2describe(`when the input is ${input}`, () => {
· ────────
3it(`results in ${expected}`, () => {
╰────
help: Prefer using `describe.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:10:10]
╭─[prefer_each.tsx:9:11]
8
9for (const [input, expected] of data) {
· ──────────────────────────────────────
10it.skip(`results in ${expected}`, () => {
· ───────
11expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:2:10]
╭─[prefer_each.tsx:1:1]
1for (const [input, expected] of data) {
· ──────────────────────────────────────
2it.skip(`results in ${expected}`, () => {
· ───────
3expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:6:10]
╭─[prefer_each.tsx:5:11]
4
5for (const [input, expected] of data) {
· ──────────────────────────────────────
6it.skip(`results in ${expected}`, () => {
· ───────
7expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:2:10]
╭─[prefer_each.tsx:1:2]
1for (const [input, expected] of data) {
· ──────────────────────────────────────
2it.skip(`results in ${expected}`, () => {
· ───────
3expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:6:10]
╭─[prefer_each.tsx:5:11]
4
5for (const [input, expected] of data) {
· ──────────────────────────────────────
6it.skip(`results in ${expected}`, () => {
· ───────
7expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:2:10]
╭─[prefer_each.tsx:1:1]
1for (const [input, expected] of data) {
· ──────────────────────────────────────
2it(`results in ${expected}`, () => {
· ──
3expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:6:10]
5
6it(`results in ${expected}`, () => {
· ──
7expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:2:10]
╭─[prefer_each.tsx:1:1]
1for (const [input, expected] of data) {
· ──────────────────────────────────────
2it(`results in ${expected}`, () => {
· ──
3expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:8:10]
╭─[prefer_each.tsx:7:11]
6
7for (const [input, expected] of data) {
· ──────────────────────────────────────
8it(`results in ${expected}`, () => {
· ──
9expect(fn(input)).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:2:10]
╭─[prefer_each.tsx:1:1]
1for (const [input, expected] of data) {
· ──────────────────────────────────────
2beforeEach(() => setupSomething(input));
· ──────────
3
╰────
help: Prefer using `describe.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:4:10]
3
4test(`results in ${expected}`, () => {
· ────
5expect(doSomething()).toBe(expected)
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:3:10]
╭─[prefer_each.tsx:2:11]
1
2for (const [input, expected] of data) {
· ──────────────────────────────────────
3it("only returns numbers that are greater than seven", function () {
· ──
4const numbers = getNumbers(input);
╰────
help: Prefer using `it.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:3:10]
╭─[prefer_each.tsx:2:11]
1
2for (const [input, expected] of data) {
· ──────────────────────────────────────
3beforeEach(() => setupSomething(input));
· ──────────
4
╰────
help: Prefer using `describe.each` rather than a manual loop.

eslint-plugin-vitest(prefer-each): Enforce using `each` rather than manual loops
╭─[prefer_each.tsx:5:10]
4
5it("only returns numbers that are greater than seven", function () {
· ──
6const numbers = getNumbers();
╰────
help: Prefer using `it.each` rather than a manual loop.

0 comments on commit 053676e

Please sign in to comment.