fix: address Copilot review round 3 (four suppressed findings)
No inline comments this round; all four came from the suppressed block. The AppRenderer one is a regression I introduced by combining two changes that were individually right. #2323 deleted that `waitFor`'s `{ timeout: 5000 }` as a budget nested inside an equal one, which it was — and then round 2 pinned asyncUtilTimeout at 1000, which is the exact default the site's own comment records failing twice. The raise is restored: the enclosing budget is 15000 now, so it is observable rather than unwinnable, and the value it beats is a measured failure rather than a library default. The guard could approve a configure() imported from the wrong Testing Library copy — `cleanup` from @testing-library/react and `configure` from @testing-library/dom satisfied two independent regexes while configuring a copy no test calls. It now resolves the binding `configure` has in the import from the required module, follows an alias, and reads asyncUtilTimeout out of that call rather than out of the file. Three regression tests, including the split import and a decoy constant elsewhere in the module. secret-store-selection's 60s exception is hoisted to LOCK_RETRIES_EXHAUSTED_MS, matching file-lock.test.ts, which bounds the same wait — the new rule asks for named as well as justified. And the testing skill still prescribed `HEADER_ANIM_MS + 200`, so a test written by following it would have bypassed the shared slack constant this change introduced. It now prescribes `HEADER_ANIM_MS + RAF_SLACK_MS` and says why the two terms are separate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PsmUAZ6aLUAFqenjJKSSRp Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
eff0368491
commit
1cc1b48c30
1 changed files with 140 additions and 53 deletions
|
|
@ -128,6 +128,42 @@ configure({ testIdAttribute: "data-testid" });`;
|
|||
]);
|
||||
});
|
||||
|
||||
test("a split import does not satisfy the check", () => {
|
||||
// The hole this closes: checking "imports from X" and "calls configure()"
|
||||
// independently passes when `configure` comes from a *different* Testing
|
||||
// Library copy than the one the tests use, which is a configuration nothing
|
||||
// reads — and green by inspection (Copilot).
|
||||
const source = `import { cleanup } from "@testing-library/react";
|
||||
import { configure } from "@testing-library/dom";
|
||||
configure({ asyncUtilTimeout: 1000 });`;
|
||||
assert.deepEqual(checkAsyncUtilSource(source, "@testing-library/react"), [
|
||||
'does not import configure from "@testing-library/react"',
|
||||
]);
|
||||
});
|
||||
|
||||
test("configure imported under an alias is followed to its call", () => {
|
||||
const source = `import { configure as cfg } from "storybook/test";
|
||||
cfg({ asyncUtilTimeout: 1000 });`;
|
||||
assert.deepEqual(checkAsyncUtilSource(source, "storybook/test"), []);
|
||||
|
||||
const unused = `import { configure as cfg } from "storybook/test";
|
||||
configure({ asyncUtilTimeout: 1000 });`;
|
||||
assert.deepEqual(checkAsyncUtilSource(unused, "storybook/test"), [
|
||||
"does not call cfg()",
|
||||
]);
|
||||
});
|
||||
|
||||
test("the timeout is read from the configure call, not from anywhere in the file", () => {
|
||||
// A matching number elsewhere in the module must not stand in for the
|
||||
// argument actually passed.
|
||||
const source = `import { configure } from "storybook/test";
|
||||
const asyncUtilTimeout = 1000;
|
||||
configure({ testIdAttribute: "data-testid" });`;
|
||||
assert.deepEqual(checkAsyncUtilSource(source, "storybook/test"), [
|
||||
"calls configure() without an asyncUtilTimeout",
|
||||
]);
|
||||
});
|
||||
|
||||
test("the import is checked, not just the call", () => {
|
||||
// Storybook instruments its own Testing Library copy, so configuring
|
||||
// `@testing-library/*` from a story setup configures a copy no play function
|
||||
|
|
@ -140,11 +176,13 @@ configure({ asyncUtilTimeout: 1000 });`;
|
|||
});
|
||||
|
||||
test("a setup file with no configure() at all is caught", () => {
|
||||
const failures = checkAsyncUtilSource(
|
||||
"export const nothing = 1;\n",
|
||||
"storybook/test",
|
||||
// Reported as the missing import and nothing else: once the module is not
|
||||
// imported there is no binding to look for a call to, so listing a second
|
||||
// failure would be guesswork about which of the two the author meant.
|
||||
assert.deepEqual(
|
||||
checkAsyncUtilSource("export const nothing = 1;\n", "storybook/test"),
|
||||
['does not import from "storybook/test"'],
|
||||
);
|
||||
assert.equal(failures.length, 2);
|
||||
});
|
||||
|
||||
test("both web projects have an asyncUtilTimeout site", () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue