Skip to content

Commit 771daa4

Browse files
fix(js_analyze): handle chained test.each calls in noMisplacedAssertion (#10680)
1 parent 1e7dbfc commit 771daa4

6 files changed

Lines changed: 72 additions & 9 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Fixed [#10635](https://github.com/biomejs/biome/issues/10635): Biome now recognizes chained
6+
table tests such as `test.concurrent.each()` and `it.concurrent.each()` as test calls, fixing
7+
`noMisplacedAssertion` false positives and improving formatting for those test declarations.

crates/biome_js_analyze/tests/specs/suspicious/noMisplacedAssertion/valid.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,22 @@ test("something", () => {
99
expect("something").toBeTrue()
1010
})
1111

12+
test.each(arr)("works as expected", () => {
13+
expect();
14+
});
15+
16+
test.concurrent.each(arr)("works as expected", () => {
17+
expect();
18+
});
19+
20+
it.concurrent.each(arr)("works as expected", () => {
21+
expect();
22+
});
23+
24+
test.concurrent.only.each(arr)("works as expected", () => {
25+
expect();
26+
});
27+
1228
Deno.test("something", () => {
1329
expect("something").toBeTrue()
1430
})
@@ -48,4 +64,4 @@ expect.extend({
4864

4965
expect.addEqualityTesters([areVolumesEqual]);
5066

51-
expect.addSnapshotSerializer(serializer);
67+
expect.addSnapshotSerializer(serializer);

crates/biome_js_analyze/tests/specs/suspicious/noMisplacedAssertion/valid.js.snap

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ test("something", () => {
1515
expect("something").toBeTrue()
1616
})
1717
18+
test.each(arr)("works as expected", () => {
19+
expect();
20+
});
21+
22+
test.concurrent.each(arr)("works as expected", () => {
23+
expect();
24+
});
25+
26+
it.concurrent.each(arr)("works as expected", () => {
27+
expect();
28+
});
29+
30+
test.concurrent.only.each(arr)("works as expected", () => {
31+
expect();
32+
});
33+
1834
Deno.test("something", () => {
1935
expect("something").toBeTrue()
2036
})
@@ -55,4 +71,5 @@ expect.extend({
5571
expect.addEqualityTesters([areVolumesEqual]);
5672
5773
expect.addSnapshotSerializer(serializer);
74+
5875
```

crates/biome_js_formatter/tests/specs/js/module/declarations/test_declaration.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,9 @@ describe("with retry option", { retry: 2 }, () => {
3232
it("with timeout option", { timeout: 5000 }, () => {
3333
console.log("test");
3434
});
35+
36+
// Chained table test
37+
test.concurrent.each(arr)(
38+
"works as expected", () => {
39+
expect();
40+
});

crates/biome_js_formatter/tests/specs/js/module/declarations/test_declaration.js.snap

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ it("with timeout option", { timeout: 5000 }, () => {
4141
console.log("test");
4242
});
4343
44+
// Chained table test
45+
test.concurrent.each(arr)(
46+
"works as expected", () => {
47+
expect();
48+
});
49+
4450
```
4551

4652

@@ -78,4 +84,9 @@ it("with timeout option", { timeout: 5000 }, () => {
7884
console.log("test");
7985
});
8086
87+
// Chained table test
88+
test.concurrent.each(arr)("works as expected", () => {
89+
expect();
90+
});
91+
8192
```

crates/biome_js_syntax/src/expr_ext.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,23 +1092,29 @@ impl AnyJsExpression {
10921092
false
10931093
}
10941094

1095-
/// Checks whether the current function call is:
1096-
/// - `it`: many libraries such as Node.js, Mocha, Jest, etc.
1097-
/// - `test`: many libraries such as Node.js, bun, etc.
1095+
/// Checks whether the current function call is a test body context:
1096+
/// - `it` and `test` calls accepted by [`contains_a_test_pattern`], such as
1097+
/// `it.only` or `test.concurrent`
1098+
/// - `it.each` and `test.each` table test calls accepted by
1099+
/// [`contains_a_test_each_pattern`], such as `test.concurrent.each`
10981100
/// - [`Deno.test`](https://docs.deno.com/runtime/manual/basics/testing/)
10991101
/// - [`waitFor`](https://testing-library.com/docs/dom-testing-library/api-async/#waitfor)
1102+
///
1103+
/// [`contains_a_test_pattern`]: crate::AnyJsExpression::contains_a_test_pattern
1104+
/// [`contains_a_test_each_pattern`]: crate::AnyJsExpression::contains_a_test_each_pattern
11001105
pub fn contains_it_call(&self) -> bool {
1101-
let mut members = CalleeNamesIterator::new(self.clone());
1102-
1103-
let texts: [Option<TokenText>; 2] = [members.next(), members.next()];
1106+
let members = CalleeNamesIterator::new(self.clone()).collect::<Vec<_>>();
11041107

1105-
let mut rev = texts.iter().rev().flatten();
1108+
let mut rev = members.iter().rev();
11061109

11071110
let first = rev.next().map(|t| t.text());
11081111
let second = rev.next().map(|t| t.text());
11091112

11101113
match first {
1111-
Some("test" | "it" | "waitFor") => true,
1114+
Some("test" | "it") => {
1115+
self.contains_a_test_pattern() || self.contains_a_test_each_pattern()
1116+
}
1117+
Some("waitFor") => true,
11121118
Some("Deno") => matches!(second, Some("test")),
11131119
_ => false,
11141120
}

0 commit comments

Comments
 (0)