Skip to content

Commit

Permalink
feat(linter): add vitest/no-standalone-expect rule (#8986)
Browse files Browse the repository at this point in the history
Since this rule and tests already existed under the jest directory, I
simply created a directory for `no_standalone_expect` and migrated the
jest rule, jest tests, and vitest tests there.

I didn't need to modify any existing logic for this rule to pass. 

I added `no-standalone-expect` to the sorted set of
`VITEST_COMPATIBLE_JEST_RULES`.
  • Loading branch information
taearls authored Feb 10, 2025
1 parent cac5545 commit a870526
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -231,163 +231,3 @@ fn is_var_declarator_or_test_block<'a>(

false
}

#[test]
fn test() {
use crate::tester::Tester;

let pass = vec![
("expect.any(String)", None),
("expect.extend({})", None),
("describe('a test', () => { it('an it', () => {expect(1).toBe(1); }); });", None),
(
"describe('a test', () => { it('an it', () => { const func = () => { expect(1).toBe(1); }; }); });",
None,
),
("describe('a test', () => { const func = () => { expect(1).toBe(1); }; });", None),
("describe('a test', () => { function func() { expect(1).toBe(1); }; });", None),
("describe('a test', () => { const func = function(){ expect(1).toBe(1); }; });", None),
("it('an it', () => expect(1).toBe(1))", None),
("const func = function(){ expect(1).toBe(1); };", None),
("const func = () => expect(1).toBe(1);", None),
("{}", None),
("it.each([1, true])('trues', value => { expect(value).toBe(true); });", None),
(
"it.each([1, true])('trues', value => { expect(value).toBe(true); }); it('an it', () => { expect(1).toBe(1) });",
None,
),
(
"
it.each`
num | value
${1} | ${true}
`('trues', ({ value }) => {
expect(value).toBe(true);
});
",
None,
),
("it.only('an only', value => { expect(value).toBe(true); });", None),
("it.concurrent('an concurrent', value => { expect(value).toBe(true); });", None),
(
"describe.each([1, true])('trues', value => { it('an it', () => expect(value).toBe(true) ); });",
None,
),
(
"
describe('scenario', () => {
const t = Math.random() ? it.only : it;
t('testing', () => expect(true));
});
",
Some(serde_json::json!([{ "additionalTestBlockFunctions": ['t'] }])),
),
(
r"
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
",
Some(serde_json::json!([{ "additionalTestBlockFunctions": ["each.test"] }])),
),
];

let fail = vec![
("(() => {})('testing', () => expect(true).toBe(false))", None),
("expect.hasAssertions()", None),
("expect().hasAssertions()", None),
(
"
describe('scenario', () => {
const t = Math.random() ? it.only : it;
t('testing', () => expect(true).toBe(false));
});
",
None,
),
(
"
describe('scenario', () => {
const t = Math.random() ? it.only : it;
t('testing', () => expect(true).toBe(false));
});
",
None,
),
(
"
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
",
None,
),
(
"
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
",
Some(serde_json::json!([{ "additionalTestBlockFunctions": ["each"] }])),
),
(
"
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
",
Some(serde_json::json!([{ "additionalTestBlockFunctions": ["test"] }])),
),
("describe('a test', () => { expect(1).toBe(1); });", None),
("describe('a test', () => expect(1).toBe(1));", None),
(
"describe('a test', () => { const func = () => { expect(1).toBe(1); }; expect(1).toBe(1); });",
None,
),
(
"describe('a test', () => { it(() => { expect(1).toBe(1); }); expect(1).toBe(1); });",
None,
),
("expect(1).toBe(1);", None),
("{expect(1).toBe(1)}", None),
(
"it.each([1, true])('trues', value => { expect(value).toBe(true); }); expect(1).toBe(1);",
None,
),
("describe.each([1, true])('trues', value => { expect(value).toBe(true); });", None),
(
"
import { expect as pleaseExpect } from '@jest/globals';
describe('a test', () => { pleaseExpect(1).toBe(1); });
",
None,
),
(
"
import { expect as pleaseExpect } from '@jest/globals';
beforeEach(() => pleaseExpect.hasAssertions());
",
None,
),
];

Tester::new(NoStandaloneExpect::NAME, NoStandaloneExpect::PLUGIN, pass, fail)
.with_jest_plugin(true)
.test_and_snapshot();
}
161 changes: 161 additions & 0 deletions crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/jest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#[test]
fn test() {
use super::PreferLowercaseTitle;
use crate::rule::RuleMeta;
use crate::tester::Tester;

let pass = vec![
("expect.any(String)", None),
("expect.extend({})", None),
("describe('a test', () => { it('an it', () => {expect(1).toBe(1); }); });", None),
(
"describe('a test', () => { it('an it', () => { const func = () => { expect(1).toBe(1); }; }); });",
None,
),
("describe('a test', () => { const func = () => { expect(1).toBe(1); }; });", None),
("describe('a test', () => { function func() { expect(1).toBe(1); }; });", None),
("describe('a test', () => { const func = function(){ expect(1).toBe(1); }; });", None),
("it('an it', () => expect(1).toBe(1))", None),
("const func = function(){ expect(1).toBe(1); };", None),
("const func = () => expect(1).toBe(1);", None),
("{}", None),
("it.each([1, true])('trues', value => { expect(value).toBe(true); });", None),
(
"it.each([1, true])('trues', value => { expect(value).toBe(true); }); it('an it', () => { expect(1).toBe(1) });",
None,
),
(
"
it.each`
num | value
${1} | ${true}
`('trues', ({ value }) => {
expect(value).toBe(true);
});
",
None,
),
("it.only('an only', value => { expect(value).toBe(true); });", None),
("it.concurrent('an concurrent', value => { expect(value).toBe(true); });", None),
(
"describe.each([1, true])('trues', value => { it('an it', () => expect(value).toBe(true) ); });",
None,
),
(
"
describe('scenario', () => {
const t = Math.random() ? it.only : it;
t('testing', () => expect(true));
});
",
Some(serde_json::json!([{ "additionalTestBlockFunctions": ['t'] }])),
),
(
r"
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
",
Some(serde_json::json!([{ "additionalTestBlockFunctions": ["each.test"] }])),
),
];

let fail = vec![
("(() => {})('testing', () => expect(true).toBe(false))", None),
("expect.hasAssertions()", None),
("expect().hasAssertions()", None),
(
"
describe('scenario', () => {
const t = Math.random() ? it.only : it;
t('testing', () => expect(true).toBe(false));
});
",
None,
),
(
"
describe('scenario', () => {
const t = Math.random() ? it.only : it;
t('testing', () => expect(true).toBe(false));
});
",
None,
),
(
"
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
",
None,
),
(
"
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
",
Some(serde_json::json!([{ "additionalTestBlockFunctions": ["each"] }])),
),
(
"
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
",
Some(serde_json::json!([{ "additionalTestBlockFunctions": ["test"] }])),
),
("describe('a test', () => { expect(1).toBe(1); });", None),
("describe('a test', () => expect(1).toBe(1));", None),
(
"describe('a test', () => { const func = () => { expect(1).toBe(1); }; expect(1).toBe(1); });",
None,
),
(
"describe('a test', () => { it(() => { expect(1).toBe(1); }); expect(1).toBe(1); });",
None,
),
("expect(1).toBe(1);", None),
("{expect(1).toBe(1)}", None),
(
"it.each([1, true])('trues', value => { expect(value).toBe(true); }); expect(1).toBe(1);",
None,
),
("describe.each([1, true])('trues', value => { expect(value).toBe(true); });", None),
(
"
import { expect as pleaseExpect } from '@jest/globals';
describe('a test', () => { pleaseExpect(1).toBe(1); });
",
None,
),
(
"
import { expect as pleaseExpect } from '@jest/globals';
beforeEach(() => pleaseExpect.hasAssertions());
",
None,
),
];

Tester::new(NoStandaloneExpect::NAME, NoStandaloneExpect::PLUGIN, pass, fail)
.with_jest_plugin(true)
.test_and_snapshot();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod jest;
mod vitest;

use super::NoStandaloneExpect;
Loading

0 comments on commit a870526

Please sign in to comment.