From c9367820efbee7042e2acb6dd3dc9b4f87514736 Mon Sep 17 00:00:00 2001 From: cinchen Date: Tue, 23 Jul 2024 21:50:45 +0800 Subject: [PATCH 1/7] feat(linter): eslint-plugin-vitest/no-conditional-expect (#4425) support [eslint-plugin-vitest/no-conditional-expect](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md) --- .../src/rules/jest/no_conditional_expect.rs | 121 ++++++++++++- .../src/snapshots/no_conditional_expect.snap | 165 +++++++++++++----- crates/oxc_linter/src/utils/mod.rs | 1 + 3 files changed, 238 insertions(+), 49 deletions(-) diff --git a/crates/oxc_linter/src/rules/jest/no_conditional_expect.rs b/crates/oxc_linter/src/rules/jest/no_conditional_expect.rs index e07902bf66b19..7d4427f4900b4 100644 --- a/crates/oxc_linter/src/rules/jest/no_conditional_expect.rs +++ b/crates/oxc_linter/src/rules/jest/no_conditional_expect.rs @@ -50,6 +50,17 @@ declare_oxc_lint!( // await foo().catch(error => expect(error).toBeInstanceOf(error)); // }); /// ``` + /// + /// This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md), + /// to use it, add the following configuration to your `.eslintrc.json`: + /// + /// ```json + /// { + /// "rules": { + /// "vitest/no-conditional-expect": "error" + /// } + /// } + /// ``` NoConditionalExpect, correctness ); @@ -163,7 +174,7 @@ fn check_parents<'a>( fn test() { use crate::tester::Tester; - let pass = vec![ + let mut pass = vec![ ( " it('foo', () => { @@ -431,7 +442,7 @@ fn test() { ), ]; - let fail = vec![ + let mut fail = vec![ ( " it('foo', () => { @@ -886,5 +897,109 @@ fn test() { ), ]; - Tester::new(NoConditionalExpect::NAME, pass, fail).with_jest_plugin(true).test_and_snapshot(); + let pass_vitest = vec![ + " + it('foo', () => { + process.env.FAIL && setNum(1); + + expect(num).toBe(2); + }); + ", + " + function getValue() { + let num = 2; + + process.env.FAIL && setNum(1); + + return num; + } + + it('foo', () => { + expect(getValue()).toBe(2); + }); + ", + " + function getValue() { + let num = 2; + + process.env.FAIL || setNum(1); + + return num; + } + + it('foo', () => { + expect(getValue()).toBe(2); + }); + ", + " + it('foo', () => { + const num = process.env.FAIL ? 1 : 2; + + expect(num).toBe(2); + }); + ", + " + function getValue() { + return process.env.FAIL ? 1 : 2 + } + + it('foo', () => { + expect(getValue()).toBe(2); + }); + ", + ]; + + let fail_vitest = vec![ + " + it('foo', () => { + something && expect(something).toHaveBeenCalled(); + }) + ", + " + it('foo', () => { + a || (b && expect(something).toHaveBeenCalled()); + }) + ", + " + it.each``('foo', () => { + something || expect(something).toHaveBeenCalled(); + }); + ", + " + it.each()('foo', () => { + something || expect(something).toHaveBeenCalled(); + }) + ", + " + function getValue() { + something || expect(something).toHaveBeenCalled(); + } + it('foo', getValue); + ", + " + it('foo', () => { + something ? expect(something).toHaveBeenCalled() : noop(); + }) + ", + " + function getValue() { + something ? expect(something).toHaveBeenCalled() : noop(); + } + + it('foo', getValue); + ", + " + it('foo', () => { + something ? noop() : expect(something).toHaveBeenCalled(); + }) + ", + ]; + + pass.extend(pass_vitest.into_iter().map(|x| (x, None))); + fail.extend(fail_vitest.into_iter().map(|x| (x, None))); + + Tester::new(NoConditionalExpect::NAME, pass, fail) + .with_jest_plugin(true) + .with_vitest_plugin(true) + .test_and_snapshot(); } diff --git a/crates/oxc_linter/src/snapshots/no_conditional_expect.snap b/crates/oxc_linter/src/snapshots/no_conditional_expect.snap index 3f9f45a5fb6e7..eda016b57254d 100644 --- a/crates/oxc_linter/src/snapshots/no_conditional_expect.snap +++ b/crates/oxc_linter/src/snapshots/no_conditional_expect.snap @@ -1,7 +1,8 @@ --- source: crates/oxc_linter/src/tester.rs +assertion_line: 216 --- - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:34] 2 │ it('foo', () => { 3 │ something && expect(something).toHaveBeenCalled(); @@ -10,7 +11,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:31] 2 │ it('foo', () => { 3 │ a || b && expect(something).toHaveBeenCalled(); @@ -19,7 +20,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:33] 2 │ it('foo', () => { 3 │ (a || b) && expect(something).toHaveBeenCalled(); @@ -28,7 +29,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:32] 2 │ it('foo', () => { 3 │ a || (b && expect(something).toHaveBeenCalled()); @@ -37,7 +38,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:31] 2 │ it('foo', () => { 3 │ a && b && expect(something).toHaveBeenCalled(); @@ -46,7 +47,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:31] 2 │ it('foo', () => { 3 │ a && b || expect(something).toHaveBeenCalled(); @@ -55,7 +56,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:33] 2 │ it('foo', () => { 3 │ (a && b) || expect(something).toHaveBeenCalled(); @@ -64,7 +65,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:34] 2 │ function getValue() { 3 │ something && expect(something).toHaveBeenCalled(); @@ -73,7 +74,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:34] 2 │ it('foo', () => { 3 │ something || expect(something).toHaveBeenCalled(); @@ -82,7 +83,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:34] 2 │ it.each``('foo', () => { 3 │ something || expect(something).toHaveBeenCalled(); @@ -91,7 +92,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:34] 2 │ it.each()('foo', () => { 3 │ something || expect(something).toHaveBeenCalled(); @@ -100,7 +101,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:34] 2 │ function getValue() { 3 │ something || expect(something).toHaveBeenCalled(); @@ -109,7 +110,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:33] 2 │ it('foo', () => { 3 │ something ? expect(something).toHaveBeenCalled() : noop(); @@ -118,7 +119,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:33] 2 │ function getValue() { 3 │ something ? expect(something).toHaveBeenCalled() : noop(); @@ -127,7 +128,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:42] 2 │ it('foo', () => { 3 │ something ? noop() : expect(something).toHaveBeenCalled(); @@ -136,7 +137,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:42] 2 │ it.each``('foo', () => { 3 │ something ? noop() : expect(something).toHaveBeenCalled(); @@ -145,7 +146,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:42] 2 │ it.each()('foo', () => { 3 │ something ? noop() : expect(something).toHaveBeenCalled(); @@ -154,7 +155,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:42] 2 │ function getValue() { 3 │ something ? noop() : expect(something).toHaveBeenCalled(); @@ -163,7 +164,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:7:25] 6 │ default: 7 │ expect(something).toHaveBeenCalled(); @@ -172,7 +173,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:5:25] 4 │ case 'value': 5 │ expect(something).toHaveBeenCalled(); @@ -181,7 +182,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:5:25] 4 │ case 'value': 5 │ expect(something).toHaveBeenCalled(); @@ -190,7 +191,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:5:25] 4 │ case 'value': 5 │ expect(something).toHaveBeenCalled(); @@ -199,7 +200,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:7:25] 6 │ default: 7 │ expect(something).toHaveBeenCalled(); @@ -208,7 +209,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:4:25] 3 │ if(doSomething) { 4 │ expect(something).toHaveBeenCalled(); @@ -217,7 +218,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:25] 5 │ } else { 6 │ expect(something).toHaveBeenCalled(); @@ -226,7 +227,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:25] 5 │ } else { 6 │ expect(something).toHaveBeenCalled(); @@ -235,7 +236,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:25] 5 │ } else { 6 │ expect(something).toHaveBeenCalled(); @@ -244,7 +245,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:4:25] 3 │ if(doSomething) { 4 │ expect(something).toHaveBeenCalled(); @@ -253,7 +254,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:21] 5 │ } else { 6 │ expect(something).toHaveBeenCalled(); @@ -262,7 +263,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:21] 5 │ } catch (err) { 6 │ expect(err).toMatch('Error'); @@ -271,7 +272,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:21] 5 │ } catch (err) { 6 │ expect(err).toMatch('Error'); @@ -280,7 +281,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:25] 5 │ } catch (err) { 6 │ expect(err).toMatch('Error'); @@ -289,7 +290,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:25] 5 │ } catch (err) { 6 │ expect(err).toMatch('Error'); @@ -298,7 +299,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:25] 5 │ } catch (err) { 6 │ expect(err).toMatch('Error'); @@ -307,7 +308,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:21] 5 │ } catch { 6 │ expect(something).toHaveBeenCalled(); @@ -316,7 +317,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:5:37] 4 │ .then(() => { throw new Error('oh noes!'); }) 5 │ .catch(error => expect(error).toBeInstanceOf(Error)); @@ -325,7 +326,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:9:37] 8 │ .then(() => { throw new Error('oh noes!'); }) 9 │ .catch(error => expect(error).toBeInstanceOf(Error)); @@ -334,7 +335,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:7:37] 6 │ .then(() => { throw new Error('oh noes!'); }) 7 │ .catch(error => expect(error).toBeInstanceOf(Error)) @@ -343,7 +344,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:5:37] 4 │ .then(() => { throw new Error('oh noes!'); }) 5 │ .catch(error => expect(error).toBeInstanceOf(Error)) @@ -352,7 +353,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:6:32] 5 │ .catch(error => expect(error).toBeInstanceOf(Error)) 6 │ .catch(error => expect(error).toBeInstanceOf(Error)); @@ -361,7 +362,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:5:32] 4 │ .catch(error => expect(error).toBeInstanceOf(Error)) 5 │ .catch(error => expect(error).toBeInstanceOf(Error)) @@ -370,7 +371,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:4:32] 3 │ await Promise.resolve() 4 │ .catch(error => expect(error).toBeInstanceOf(Error)) @@ -379,7 +380,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:4:37] 3 │ await Promise.resolve() 4 │ .catch(error => expect(error).toBeInstanceOf(Error)) @@ -388,7 +389,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:5:37] 4 │ .then(() => { throw new Error('oh noes!'); }) 5 │ .catch(error => expect(error).toBeInstanceOf(Error)); @@ -397,7 +398,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:3:54] 2 │ it('works', async () => { 3 │ await somePromise.catch(error => expect(error).toBeInstanceOf(Error)); @@ -406,7 +407,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Avoid calling `expect` conditionally` - ⚠ eslint-plugin-jest(no-conditional-expect): Unexpected conditional expect + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect ╭─[no_conditional_expect.tsx:7:25] 6 │ if (vnode._nextDom) { 7 │ expect.fail('vnode should not have _nextDom:' + vnode._nextDom); @@ -414,3 +415,75 @@ source: crates/oxc_linter/src/tester.rs 8 │ } ╰──── help: Avoid calling `expect` conditionally` + + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect + ╭─[no_conditional_expect.tsx:3:30] + 2 │ it('foo', () => { + 3 │ something && expect(something).toHaveBeenCalled(); + · ────── + 4 │ }) + ╰──── + help: Avoid calling `expect` conditionally` + + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect + ╭─[no_conditional_expect.tsx:3:28] + 2 │ it('foo', () => { + 3 │ a || (b && expect(something).toHaveBeenCalled()); + · ────── + 4 │ }) + ╰──── + help: Avoid calling `expect` conditionally` + + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect + ╭─[no_conditional_expect.tsx:3:30] + 2 │ it.each``('foo', () => { + 3 │ something || expect(something).toHaveBeenCalled(); + · ────── + 4 │ }); + ╰──── + help: Avoid calling `expect` conditionally` + + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect + ╭─[no_conditional_expect.tsx:3:30] + 2 │ it.each()('foo', () => { + 3 │ something || expect(something).toHaveBeenCalled(); + · ────── + 4 │ }) + ╰──── + help: Avoid calling `expect` conditionally` + + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect + ╭─[no_conditional_expect.tsx:3:30] + 2 │ function getValue() { + 3 │ something || expect(something).toHaveBeenCalled(); + · ────── + 4 │ } + ╰──── + help: Avoid calling `expect` conditionally` + + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect + ╭─[no_conditional_expect.tsx:3:29] + 2 │ it('foo', () => { + 3 │ something ? expect(something).toHaveBeenCalled() : noop(); + · ────── + 4 │ }) + ╰──── + help: Avoid calling `expect` conditionally` + + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect + ╭─[no_conditional_expect.tsx:3:29] + 2 │ function getValue() { + 3 │ something ? expect(something).toHaveBeenCalled() : noop(); + · ────── + 4 │ } + ╰──── + help: Avoid calling `expect` conditionally` + + ⚠ eslint-plugin-vitest(no-conditional-expect): Unexpected conditional expect + ╭─[no_conditional_expect.tsx:3:38] + 2 │ it('foo', () => { + 3 │ something ? noop() : expect(something).toHaveBeenCalled(); + · ────── + 4 │ }) + ╰──── + help: Avoid calling `expect` conditionally` diff --git a/crates/oxc_linter/src/utils/mod.rs b/crates/oxc_linter/src/utils/mod.rs index 149008b7e6fdd..75efafd061a42 100644 --- a/crates/oxc_linter/src/utils/mod.rs +++ b/crates/oxc_linter/src/utils/mod.rs @@ -18,6 +18,7 @@ pub fn is_jest_rule_adapted_to_vitest(rule_name: &str) -> bool { "consistent-test-it", "expect-expect", "no-alias-methods", + "no-conditional-expect", "no-commented-out-tests", "no-disabled-tests", "no-focused-tests", From 269151d7f020fa622f461522bfbe391b21a2dcd4 Mon Sep 17 00:00:00 2001 From: Boshen Date: Tue, 23 Jul 2024 21:51:08 +0800 Subject: [PATCH 2/7] ci: use bot account with PAT in `reusable_prepare_release` --- .github/workflows/reusable_prepare_release.yml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/reusable_prepare_release.yml b/.github/workflows/reusable_prepare_release.yml index 01154ffa2deeb..1f2244a58fdaf 100644 --- a/.github/workflows/reusable_prepare_release.yml +++ b/.github/workflows/reusable_prepare_release.yml @@ -13,15 +13,6 @@ on: version: value: ${{ jobs.run.outputs.version }} -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-D warnings" - -permissions: - pull-requests: write - contents: write - actions: write - jobs: run: name: Prepare Release @@ -56,10 +47,10 @@ jobs: - uses: peter-evans/create-pull-request@v6 id: pr with: - token: ${{ secrets.GITHUB_TOKEN }} + # bot account with PAT required for triggering workflow runs + # See https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs + token: ${{ secrets.OXC_BOT_PAT }} commit-message: Release ${{ inputs.name }} - committer: Boshen - author: Boshen branch: release/${{ inputs.name }} branch-suffix: timestamp base: main From 6beef7414c0ba57cd96de21c19740d61d0f3ce2a Mon Sep 17 00:00:00 2001 From: Boshen Date: Tue, 23 Jul 2024 22:05:21 +0800 Subject: [PATCH 3/7] ci: add check job (publish --dry-run) in prepare_release_crates --- .github/workflows/prepare_release_crates.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/prepare_release_crates.yml b/.github/workflows/prepare_release_crates.yml index c1841073c1add..b25765bd537f1 100644 --- a/.github/workflows/prepare_release_crates.yml +++ b/.github/workflows/prepare_release_crates.yml @@ -8,7 +8,19 @@ concurrency: cancel-in-progress: true jobs: - prepare_release: + check: + name: Check + runs-on: ubuntu-latest + steps: + - uses: taiki-e/checkout-action@v1 + - uses: Boshen/setup-rust@main + with: + cache-key: warm + tools: cargo-release-oxc + - run: cargo release-oxc publish --release crates --dry-run + + prepare: + needs: check name: Prepare Release Crates uses: ./.github/workflows/reusable_prepare_release.yml with: From fb15a19040681a3feb16b96e57f8dc07e7797937 Mon Sep 17 00:00:00 2001 From: Boshen Date: Tue, 23 Jul 2024 22:13:13 +0800 Subject: [PATCH 4/7] chore: fix cyclic dependencies by moving mangler tests to `oxc_minifier` --- Cargo.lock | 4 --- crates/oxc_mangler/Cargo.toml | 7 ---- crates/oxc_mangler/tests/integration/main.rs | 24 ------------- .../oxc_mangler/tests/integration/tester.rs | 14 -------- crates/oxc_minifier/tests/mangler/mod.rs | 36 +++++++++++++++++++ .../tests/mangler}/snapshots/mangler.snap | 0 crates/oxc_minifier/tests/mod.rs | 1 + 7 files changed, 37 insertions(+), 49 deletions(-) delete mode 100644 crates/oxc_mangler/tests/integration/main.rs delete mode 100644 crates/oxc_mangler/tests/integration/tester.rs create mode 100644 crates/oxc_minifier/tests/mangler/mod.rs rename crates/{oxc_mangler/tests/integration => oxc_minifier/tests/mangler}/snapshots/mangler.snap (100%) diff --git a/Cargo.lock b/Cargo.lock index 1c37b43f79237..a0122e94c9516 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1563,13 +1563,9 @@ dependencies = [ name = "oxc_mangler" version = "0.21.0" dependencies = [ - "insta", "itertools 0.13.0", - "oxc_allocator", "oxc_ast", - "oxc_codegen", "oxc_index", - "oxc_parser", "oxc_semantic", "oxc_span", ] diff --git a/crates/oxc_mangler/Cargo.toml b/crates/oxc_mangler/Cargo.toml index e5717b71d7068..3a8d3819cc8c2 100644 --- a/crates/oxc_mangler/Cargo.toml +++ b/crates/oxc_mangler/Cargo.toml @@ -26,10 +26,3 @@ oxc_ast = { workspace = true } oxc_semantic = { workspace = true } oxc_index = { workspace = true } itertools = { workspace = true } - -[dev-dependencies] -oxc_codegen = { workspace = true } -oxc_parser = { workspace = true } -oxc_span = { workspace = true } -oxc_allocator = { workspace = true } -insta = { workspace = true } diff --git a/crates/oxc_mangler/tests/integration/main.rs b/crates/oxc_mangler/tests/integration/main.rs deleted file mode 100644 index c746940bf172b..0000000000000 --- a/crates/oxc_mangler/tests/integration/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -mod tester; - -use std::fmt::Write; - -use tester::mangle; - -#[test] -fn mangler() { - let cases = [ - "function foo(a) {a}", - "function foo(a) { let _ = { x } }", - "function foo(a) { let { x } = y }", - "var x; function foo(a) { ({ x } = y) }", - ]; - - let snapshot = cases.into_iter().fold(String::new(), |mut w, case| { - write!(w, "{case}\n{}\n", mangle(case)).unwrap(); - w - }); - - insta::with_settings!({ prepend_module_to_snapshot => false, omit_expression => true }, { - insta::assert_snapshot!("mangler", snapshot); - }); -} diff --git a/crates/oxc_mangler/tests/integration/tester.rs b/crates/oxc_mangler/tests/integration/tester.rs deleted file mode 100644 index cdfdcc82cabce..0000000000000 --- a/crates/oxc_mangler/tests/integration/tester.rs +++ /dev/null @@ -1,14 +0,0 @@ -use oxc_allocator::Allocator; -use oxc_codegen::CodeGenerator; -use oxc_mangler::ManglerBuilder; -use oxc_parser::Parser; -use oxc_span::SourceType; - -pub fn mangle(source_text: &str) -> String { - let allocator = Allocator::default(); - let source_type = SourceType::default().with_module(true); - let ret = Parser::new(&allocator, source_text, source_type).parse(); - let program = ret.program; - let mangler = ManglerBuilder::default().build(&program); - CodeGenerator::new().with_mangler(Some(mangler)).build(&program).source_text -} diff --git a/crates/oxc_minifier/tests/mangler/mod.rs b/crates/oxc_minifier/tests/mangler/mod.rs new file mode 100644 index 0000000000000..55728f1177414 --- /dev/null +++ b/crates/oxc_minifier/tests/mangler/mod.rs @@ -0,0 +1,36 @@ +use std::fmt::Write; + +use oxc_allocator::Allocator; +use oxc_codegen::{CodeGenerator, CodegenOptions}; +use oxc_mangler::ManglerBuilder; +use oxc_minifier::{CompressOptions, Minifier, MinifierOptions}; +use oxc_parser::Parser; +use oxc_span::SourceType; + +fn mangle(source_text: &str) -> String { + let allocator = Allocator::default(); + let source_type = SourceType::default().with_module(true); + let ret = Parser::new(&allocator, source_text, source_type).parse(); + let program = ret.program; + let mangler = ManglerBuilder::default().build(&program); + CodeGenerator::new().with_mangler(Some(mangler)).build(&program).source_text +} + +#[test] +fn mangler() { + let cases = [ + "function foo(a) {a}", + "function foo(a) { let _ = { x } }", + "function foo(a) { let { x } = y }", + "var x; function foo(a) { ({ x } = y) }", + ]; + + let snapshot = cases.into_iter().fold(String::new(), |mut w, case| { + write!(w, "{case}\n{}\n", mangle(case)).unwrap(); + w + }); + + insta::with_settings!({ prepend_module_to_snapshot => false, omit_expression => true }, { + insta::assert_snapshot!("mangler", snapshot); + }); +} diff --git a/crates/oxc_mangler/tests/integration/snapshots/mangler.snap b/crates/oxc_minifier/tests/mangler/snapshots/mangler.snap similarity index 100% rename from crates/oxc_mangler/tests/integration/snapshots/mangler.snap rename to crates/oxc_minifier/tests/mangler/snapshots/mangler.snap diff --git a/crates/oxc_minifier/tests/mod.rs b/crates/oxc_minifier/tests/mod.rs index 4eae2c93d970d..805ac7b9980d3 100644 --- a/crates/oxc_minifier/tests/mod.rs +++ b/crates/oxc_minifier/tests/mod.rs @@ -1,6 +1,7 @@ #![allow(unused)] // mod closure; // mod esbuild; +mod mangler; mod oxc; // mod tdewolff; // mod terser; From f005416bc3d2172aedc5c7fadf5ec73e0216d036 Mon Sep 17 00:00:00 2001 From: Boshen Date: Tue, 23 Jul 2024 22:18:46 +0800 Subject: [PATCH 5/7] ci: run `cargo check` in `prepare_release_crates` --- .github/workflows/prepare_release_crates.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/prepare_release_crates.yml b/.github/workflows/prepare_release_crates.yml index b25765bd537f1..29928d5c3bd6c 100644 --- a/.github/workflows/prepare_release_crates.yml +++ b/.github/workflows/prepare_release_crates.yml @@ -17,6 +17,7 @@ jobs: with: cache-key: warm tools: cargo-release-oxc + - run: cargo ck - run: cargo release-oxc publish --release crates --dry-run prepare: From 52f65e976d59831ebbd46284a2e9e5aa77caee61 Mon Sep 17 00:00:00 2001 From: Boshen Date: Tue, 23 Jul 2024 22:22:29 +0800 Subject: [PATCH 6/7] ci: remove top level `env` --- .github/workflows/ci.yml | 4 ---- .github/workflows/release_crates.yml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22292f5fb93d1..b6951994df4f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,10 +23,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: ${{ github.ref_name != 'main' }} -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-D warnings" - jobs: test: name: Test diff --git a/.github/workflows/release_crates.yml b/.github/workflows/release_crates.yml index 91a1c71ff5048..19174aff5b9a1 100644 --- a/.github/workflows/release_crates.yml +++ b/.github/workflows/release_crates.yml @@ -16,10 +16,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-D warnings" - jobs: release: name: Release crates From 4246a21c6d43f51f24ee6da633bdbea6a5059c0d Mon Sep 17 00:00:00 2001 From: Boshen Date: Tue, 23 Jul 2024 22:25:40 +0800 Subject: [PATCH 7/7] ci: run `cargo check` before `cargo release-oxc` --- .github/workflows/reusable_prepare_release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/reusable_prepare_release.yml b/.github/workflows/reusable_prepare_release.yml index 1f2244a58fdaf..1bce2737c718c 100644 --- a/.github/workflows/reusable_prepare_release.yml +++ b/.github/workflows/reusable_prepare_release.yml @@ -33,6 +33,7 @@ jobs: - name: Run id: run run: | + cargo ck cargo release-oxc update --release ${{ inputs.name }} echo "VERSION=$(cat ./target/OXC_VERSION)" >> $GITHUB_OUTPUT {