refactor(linter): make some jest rules report more detailed (#1666)

This commit is contained in:
Wenzhe Wang 2023-12-14 11:05:06 +08:00 committed by GitHub
parent 7594a9d10f
commit d719af473c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 98 additions and 99 deletions

View file

@ -7,7 +7,7 @@ use oxc_diagnostics::{
thiserror::Error,
};
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use oxc_span::{GetSpan, Span};
use regex::Regex;
use crate::{
@ -117,7 +117,7 @@ fn run<'a>(
let has_assert_function = check_arguments(call_expr, &rule.assert_function_names, ctx);
if !has_assert_function {
ctx.diagnostic(ExpectExpectDiagnostic(call_expr.span));
ctx.diagnostic(ExpectExpectDiagnostic(call_expr.callee.span()));
}
}
}

View file

@ -13,8 +13,8 @@ use crate::{
context::LintContext,
rule::Rule,
utils::{
collect_possible_jest_call_node, is_type_of_jest_fn_call, JestFnKind, JestGeneralFnKind,
PossibleJestNode,
collect_possible_jest_call_node, is_type_of_jest_fn_call, parse_expect_jest_fn_call,
JestFnKind, JestGeneralFnKind, PossibleJestNode,
},
};
@ -77,13 +77,14 @@ fn run<'a>(
) {
let node = possible_jest_node.node;
if let AstKind::CallExpression(call_expr) = node.kind() {
if !is_type_of_jest_fn_call(call_expr, possible_jest_node, ctx, &[JestFnKind::Expect]) {
let Some(jest_fn_call) = parse_expect_jest_fn_call(call_expr, possible_jest_node, ctx)
else {
return;
}
};
let has_condition_or_catch = check_parents(node, id_nodes_mapping, ctx, false);
if has_condition_or_catch {
ctx.diagnostic(NoConditionalExpectDiagnostic(call_expr.span));
ctx.diagnostic(NoConditionalExpectDiagnostic(jest_fn_call.head.span));
}
}
}

View file

@ -44,8 +44,12 @@ impl Rule for NoExport {
return;
}
for local_export in &ctx.semantic().module_record().local_export_entries {
ctx.diagnostic(NoExportDiagnostic(local_export.span));
for span in ctx.semantic().module_record().exported_bindings.values() {
ctx.diagnostic(NoExportDiagnostic(*span));
}
if let Some(span) = ctx.semantic().module_record().export_default {
ctx.diagnostic(NoExportDiagnostic(span));
}
}
}

View file

@ -5,124 +5,118 @@ expression: expect_expect
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ it("should fail", () => {});
· ───────────────────────────
· ──
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ it("should fail", myTest); function myTest() {}
· ─────────────────────────
· ──
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ test("should fail", () => {});
· ─────────────────────────────
· ────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ test.skip("should fail", () => {});
· ──────────────────────────────────
· ─────────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ afterEach(() => {});
· ───────────────────
· ─────────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ it("should fail", () => { somePromise.then(() => {}); });
· ────────────────────────────────────────────────────────
· ──
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ test("should fail", () => { foo(true).toBe(true); })
· ────────────────────────────────────────────────────
· ────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ it("should also fail",() => expectSaga(mySaga).returns());
· ─────────────────────────────────────────────────────────
· ──
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ test('should fail', () => request.get().foo().expect(456));
· ──────────────────────────────────────────────────────────
· ────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ test('should fail', () => request.get().foo().bar().expect(456));
· ────────────────────────────────────────────────────────────────
· ────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ test('should fail', () => tester.request(123));
· ──────────────────────────────────────────────
· ────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ test('should fail', () => request(123));
· ───────────────────────────────────────
· ────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │ test('should fail', () => request(123));
· ───────────────────────────────────────
· ────
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:3:1]
3 │
4 │ ╭─▶ checkThat('this passes', () => {
5 │ │ // ...
6 │ ╰─▶ });
7 │
3 │
4 │ checkThat('this passes', () => {
· ─────────
5 │ // ...
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:3:1]
3 │
4 │ ╭─▶ checkThat.skip('this passes', () => {
5 │ │ // ...
6 │ ╰─▶ });
7 │
3 │
4 │ checkThat.skip('this passes', () => {
· ──────────────
5 │ // ...
╰────
help: Add assertion(s) in this Test
⚠ eslint-plugin-jest(expect-expect): Test has no assertions
╭─[expect_expect.tsx:1:1]
1 │
2 │ ╭─▶ it("should warn on non-assert await expression", async () => {
3 │ │ const asyncFunction = async () => {
4 │ │ throw new Error('nope')
5 │ │ };
6 │ │ await foo(asyncFunction()).rejects.toThrow();
7 │ ╰─▶ });
8 │
1 │
2 │ it("should warn on non-assert await expression", async () => {
· ──
3 │ const asyncFunction = async () => {
╰────
help: Add assertion(s) in this Test

View file

@ -6,7 +6,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ something && expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -15,7 +15,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ a || b && expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -24,7 +24,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ (a || b) && expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -33,7 +33,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ a || (b && expect(something).toHaveBeenCalled());
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -42,7 +42,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ a && b && expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -51,7 +51,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ a && b || expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -60,7 +60,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ (a && b) || expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -69,7 +69,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ function getValue() {
3 │ something && expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -78,7 +78,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ something || expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -87,7 +87,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it.each``('foo', () => {
3 │ something || expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -96,7 +96,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it.each()('foo', () => {
3 │ something || expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -105,7 +105,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ function getValue() {
3 │ something || expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -114,7 +114,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ something ? expect(something).toHaveBeenCalled() : noop();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -123,7 +123,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ function getValue() {
3 │ something ? expect(something).toHaveBeenCalled() : noop();
· ────────────────────────────────────
· ──────
4 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -132,7 +132,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('foo', () => {
3 │ something ? noop() : expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -141,7 +141,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it.each``('foo', () => {
3 │ something ? noop() : expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -150,7 +150,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it.each()('foo', () => {
3 │ something ? noop() : expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ })
╰────
help: Avoid calling `expect` conditionally`
@ -159,7 +159,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ function getValue() {
3 │ something ? noop() : expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
4 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -168,7 +168,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:6:1]
6 │ default:
7 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
8 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -177,7 +177,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:4:1]
4 │ case 'value':
5 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
6 │ default:
╰────
help: Avoid calling `expect` conditionally`
@ -186,7 +186,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:4:1]
4 │ case 'value':
5 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
6 │ default:
╰────
help: Avoid calling `expect` conditionally`
@ -195,7 +195,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:4:1]
4 │ case 'value':
5 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
6 │ default:
╰────
help: Avoid calling `expect` conditionally`
@ -204,7 +204,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:6:1]
6 │ default:
7 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
8 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -213,7 +213,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:3:1]
3 │ if(doSomething) {
4 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
5 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -222,7 +222,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } else {
6 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -231,7 +231,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } else {
6 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -240,7 +240,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } else {
6 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -249,7 +249,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:3:1]
3 │ if(doSomething) {
4 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
5 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -258,7 +258,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } else {
6 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -267,7 +267,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } catch (err) {
6 │ expect(err).toMatch('Error');
· ────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -276,7 +276,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } catch (err) {
6 │ expect(err).toMatch('Error');
· ────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -285,7 +285,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } catch (err) {
6 │ expect(err).toMatch('Error');
· ────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -294,7 +294,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } catch (err) {
6 │ expect(err).toMatch('Error');
· ────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -303,7 +303,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } catch (err) {
6 │ expect(err).toMatch('Error');
· ────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -312,7 +312,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ } catch {
6 │ expect(something).toHaveBeenCalled();
· ────────────────────────────────────
· ──────
7 │ }
╰────
help: Avoid calling `expect` conditionally`
@ -321,7 +321,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:4:1]
4 │ .then(() => { throw new Error('oh noes!'); })
5 │ .catch(error => expect(error).toBeInstanceOf(Error));
· ───────────────────────────────────
· ──────
6 │ });
╰────
help: Avoid calling `expect` conditionally`
@ -330,7 +330,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:8:1]
8 │ .then(() => { throw new Error('oh noes!'); })
9 │ .catch(error => expect(error).toBeInstanceOf(Error));
· ───────────────────────────────────
· ──────
10 │ });
╰────
help: Avoid calling `expect` conditionally`
@ -339,7 +339,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:6:1]
6 │ .then(() => { throw new Error('oh noes!'); })
7 │ .catch(error => expect(error).toBeInstanceOf(Error))
· ───────────────────────────────────
· ──────
8 │ .then(() => { throw new Error('oh noes!'); })
╰────
help: Avoid calling `expect` conditionally`
@ -348,7 +348,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:4:1]
4 │ .then(() => { throw new Error('oh noes!'); })
5 │ .catch(error => expect(error).toBeInstanceOf(Error))
· ───────────────────────────────────
· ──────
6 │ .then(() => { throw new Error('oh noes!'); })
╰────
help: Avoid calling `expect` conditionally`
@ -357,7 +357,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:5:1]
5 │ .catch(error => expect(error).toBeInstanceOf(Error))
6 │ .catch(error => expect(error).toBeInstanceOf(Error));
· ───────────────────────────────────
· ──────
7 │ });
╰────
help: Avoid calling `expect` conditionally`
@ -366,7 +366,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:4:1]
4 │ .catch(error => expect(error).toBeInstanceOf(Error))
5 │ .catch(error => expect(error).toBeInstanceOf(Error))
· ───────────────────────────────────
· ──────
6 │ .catch(error => expect(error).toBeInstanceOf(Error));
╰────
help: Avoid calling `expect` conditionally`
@ -375,7 +375,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:3:1]
3 │ await Promise.resolve()
4 │ .catch(error => expect(error).toBeInstanceOf(Error))
· ───────────────────────────────────
· ──────
5 │ .catch(error => expect(error).toBeInstanceOf(Error))
╰────
help: Avoid calling `expect` conditionally`
@ -384,7 +384,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:3:1]
3 │ await Promise.resolve()
4 │ .catch(error => expect(error).toBeInstanceOf(Error))
· ───────────────────────────────────
· ──────
5 │ .then(() => { throw new Error('oh noes!'); })
╰────
help: Avoid calling `expect` conditionally`
@ -393,7 +393,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:4:1]
4 │ .then(() => { throw new Error('oh noes!'); })
5 │ .catch(error => expect(error).toBeInstanceOf(Error));
· ───────────────────────────────────
· ──────
6 │ });
╰────
help: Avoid calling `expect` conditionally`
@ -402,7 +402,7 @@ expression: no_conditional_expect
╭─[no_conditional_expect.tsx:2:1]
2 │ it('works', async () => {
3 │ await somePromise.catch(error => expect(error).toBeInstanceOf(Error));
· ───────────────────────────────────
· ──────
4 │ });
╰────
help: Avoid calling `expect` conditionally`

View file

@ -5,7 +5,7 @@ expression: no_export
⚠ eslint-plugin-jest(no-export): Do not export from a test file.
╭─[no_export.tsx:1:1]
1 │ export const myThing = 'invalid'; test('a test', () => { expect(1).toBe(1);});
· ──────────────────────────
· ───────
╰────
help: If you want to share code between tests, move it into a separate file and import it from there.
@ -13,7 +13,7 @@ expression: no_export
╭─[no_export.tsx:1:1]
1 │
2 │ export const myThing = 'invalid';
· ──────────────────────────
· ───────
3 │
╰────
help: If you want to share code between tests, move it into a separate file and import it from there.
@ -22,7 +22,7 @@ expression: no_export
╭─[no_export.tsx:1:1]
1 │
2 │ export const myThing = 'invalid';
· ──────────────────────────
· ───────
3 │
╰────
help: If you want to share code between tests, move it into a separate file and import it from there.
@ -31,7 +31,7 @@ expression: no_export
╭─[no_export.tsx:1:1]
1 │
2 │ export const myThing = 'invalid';
· ──────────────────────────
· ───────
3 │ test.only.each``('my code', () => {
╰────
help: If you want to share code between tests, move it into a separate file and import it from there.
@ -39,16 +39,7 @@ expression: no_export
⚠ eslint-plugin-jest(no-export): Do not export from a test file.
╭─[no_export.tsx:1:1]
1 │ export default function() {}; test('a test', () => { expect(1).toBe(1);});
· ─────────────
╰────
help: If you want to share code between tests, move it into a separate file and import it from there.
⚠ eslint-plugin-jest(no-export): Do not export from a test file.
╭─[no_export.tsx:5:1]
5 │
6 │ export {foo, bar};
· ───
7 │
· ───────
╰────
help: If you want to share code between tests, move it into a separate file and import it from there.
@ -61,4 +52,13 @@ expression: no_export
╰────
help: If you want to share code between tests, move it into a separate file and import it from there.
⚠ eslint-plugin-jest(no-export): Do not export from a test file.
╭─[no_export.tsx:5:1]
5 │
6 │ export {foo, bar};
· ───
7 │
╰────
help: If you want to share code between tests, move it into a separate file and import it from there.