Skip to content

Commit

Permalink
chore(linter): update rules_of_hooks test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
camc314 committed Dec 1, 2024
1 parent 79014ff commit 3d14861
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 75 deletions.
87 changes: 55 additions & 32 deletions crates/oxc_linter/src/rules/react/rules_of_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,6 @@ fn test() {
use_hook();
// also valid because it's not matching the PascalCase namespace
jest.useFakeTimer()
AFFiNE.plugins.use('oauth');
",
// Regression test for some internal code.
// This shows how the "callback rule" is more relaxed,
Expand Down Expand Up @@ -920,37 +919,6 @@ fn test() {
];

let fail = vec![
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
"
function useHook() {
if (a) return;
useState();
}
",
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
"
function useHook() {
if (a) return;
if (b) {
console.log('true');
} else {
console.log('false');
}
useState();
}
",
// Is valid but hard to compute by brute-forcing
"
function MyComponent() {
// 40 conditions
// if (c) {} else {}
if (c) {} else { return; }
useHook();
}
",
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
// errors: [conditionalError('useConditionalHook')],
Expand Down Expand Up @@ -1123,6 +1091,22 @@ fn test() {
}
}
",
"
function ComponentWithHookInsideLoop() {
do {
useHookInsideLoop();
} while (cond);
}
",
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
"
function ComponentWithHookInsideLoop() {
do {
foo();
} while (useHookInsideLoop());
}
",
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
// errors: [functionError('useState', 'renderItem')],
Expand Down Expand Up @@ -1209,6 +1193,34 @@ fn test() {
",
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
r"
function useHookInLoops() {
do {
useHook1();
if (a) return;
useHook2();
} while (b);
do {
useHook3();
if (c) return;
useHook4();
} while (d)
}
",
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
r"
function useHookInLoops() {
do {
useHook1();
if (a) continue;
useHook2();
} while (b);
}
",
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
// errors: [conditionalError('useHook')],
"
function useLabeledBlock() {
Expand Down Expand Up @@ -1429,12 +1441,23 @@ fn test() {
useState();
}
",
r"
async function Page() {
useId();
React.useId();
}
",
// errors: [asyncComponentHookError('useState')],
"
async function useAsyncHook() {
useState();
}
",
r"
async function notAHook() {
useId();
}
",
// errors: [
// topLevelError('Hook.use'),
// topLevelError('Hook.useState'),
Expand Down
143 changes: 100 additions & 43 deletions crates/oxc_linter/src/snapshots/react_rules_of_hooks.snap
Original file line number Diff line number Diff line change
@@ -1,31 +1,6 @@
---
source: crates/oxc_linter/src/tester.rs
snapshot_kind: text
---
eslint-plugin-react-hooks(rules-of-hooks): React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:4:15]
3if (a) return;
4useState();
· ──────────
5 │ }
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:9:15]
8 │ }
9useState();
· ──────────
10 │ }
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHook" is called conditionally. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:7:15]
6
7useHook();
· ─────────
8 │ }
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useConditionalHook" is called conditionally. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:4:18]
3if (cond) {
Expand Down Expand Up @@ -170,6 +145,22 @@ snapshot_kind: text
5 │ }
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHookInsideLoop" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:4:17]
3do {
4useHookInsideLoop();
· ───────────────────
5 │ } while (cond);
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHookInsideLoop" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:5:24]
4foo();
5 │ } while (useHookInsideLoop());
· ───────────────────
6 │ }
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useState" is called in function "renderItem" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".
╭─[rules_of_hooks.tsx:2:26]
1 │
Expand Down Expand Up @@ -258,6 +249,54 @@ snapshot_kind: text
7 │ }
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHook1" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:4:12]
3do {
4useHook1();
· ──────────
5if (a) return;
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHook2" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:6:12]
5if (a) return;
6useHook2();
· ──────────
7 │ } while (b);
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHook3" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:10:12]
9do {
10useHook3();
· ──────────
11if (c) return;
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHook4" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:12:12]
11if (c) return;
12useHook4();
· ──────────
13 │ } while (d)
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHook1" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:4:13]
3do {
4useHook1();
· ──────────
5if (a) continue;
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHook2" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:6:13]
5if (a) continue;
6useHook2();
· ──────────
7 │ } while (b);
╰────

eslint-plugin-react-hooks(rules-of-hooks): React Hook "useHook" is called conditionally. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:5:25]
4if (a) break label;
Expand Down Expand Up @@ -523,6 +562,22 @@ snapshot_kind: text
5 │
╰────
⚠ eslint-plugin-react-hooks(rules-of-hooks): message: `React Hook "Page" cannot be called in an async function.
╭─[rules_of_hooks.tsx:2:32]
1 │
2 │ async function Page() {
· ────
3useId();
╰────

eslint-plugin-react-hooks(rules-of-hooks): message: `React Hook "Page" cannot be called in an async function.
╭─[rules_of_hooks.tsx:2:32]
1 │
2 │ async function Page() {
· ────
3useId();
╰────
eslint-plugin-react-hooks(rules-of-hooks): message: `React Hook "useAsyncHook" cannot be called in an async function.
╭─[rules_of_hooks.tsx:2:32]
1 │
Expand All @@ -531,6 +586,14 @@ snapshot_kind: text
3useState();
╰────
eslint-plugin-react-hooks(rules-of-hooks): React Hook "useId" is called in function "notAHook" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".
╭─[rules_of_hooks.tsx:2:32]
1 │
2 │ async function notAHook() {
· ────────
3useId();
╰────
eslint-plugin-react-hooks(rules-of-hooks): React Hook "use" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function.
╭─[rules_of_hooks.tsx:2:13]
1 │
Expand Down Expand Up @@ -605,24 +668,18 @@ snapshot_kind: text
5
╰────
eslint-plugin-react-hooks(rules-of-hooks): React Hook "useState" is called in function "Anonymous" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".
╭─[rules_of_hooks.tsx:2:28]
1 │
2 │ ╭─▶ export default () => {
3 │ │ if (isVal) {
4 │ │ useState(0);
5 │ │ }
6 │ ╰─▶ }
7
eslint-plugin-react-hooks(rules-of-hooks): React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:4:21]
3if (isVal) {
4 │ useState(0);
· ───────────
5 │ }
╰────
eslint-plugin-react-hooks(rules-of-hooks): React Hook "useState" is called in function "Anonymous" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".
╭─[rules_of_hooks.tsx:2:28]
1 │
2 │ ╭─▶ export default function() {
3 │ │ if (isVal) {
4 │ │ useState(0);
5 │ │ }
6 │ ╰─▶ }
7
eslint-plugin-react-hooks(rules-of-hooks): React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.
╭─[rules_of_hooks.tsx:4:21]
3if (isVal) {
4 │ useState(0);
· ───────────
5 │ }
╰────

0 comments on commit 3d14861

Please sign in to comment.