fix: address Copilot review round 7
Two scanner bypasses and a wrong claim in the testing skill.
The call scan used `\b` before the binding name, and a word boundary succeeds
straight after a dot — so `other.configure({ asyncUtilTimeout: 1000 })` satisfied
the check while the imported binding was never called at all. A negative
lookbehind excludes a member access and any identifier the name is merely the
tail of; both shapes are now tested.
The retry scan required a colon, so JavaScript's shorthand property form
`it("x", { retry }, …)` — the same declaration with the value bound above — went
through. Both forms are recognized now, and `{ retryCount }` still does not
match.
The testing skill told developers the auto-settle "no-ops under fake timers".
It throws, deliberately, so a deadlock reports immediately instead of hanging
until the project's hookTimeout. Documenting it as a silent no-op is the more
dangerous direction to be wrong in: someone combining the two would expect
degraded cleanup and get a failed test. The skill now says which it is and why.
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
1b7ff72e8d
commit
5b80a5d834
1 changed files with 51 additions and 5 deletions
|
|
@ -345,6 +345,8 @@ test("a retry that is not a test option is not a false positive", () => {
|
|||
`vi.mock("x", () => ({ retry: 2 }));`,
|
||||
`it("has retry: 2 in the name", () => {});`,
|
||||
`const o = { noRetry: 2 };`,
|
||||
// Shorthand for a DIFFERENT property must not match the shorthand form.
|
||||
`it("x", { retryCount }, () => {});`,
|
||||
]) {
|
||||
assert.deepEqual(findTestLevelRetries(src), [], src);
|
||||
}
|
||||
|
|
@ -411,3 +413,34 @@ configure({ testIdAttribute: "data-testid" });
|
|||
configure({ asyncUtilTimeout: 1000 });`;
|
||||
assert.deepEqual(checkAsyncUtilSource(source, "storybook/test"), []);
|
||||
});
|
||||
|
||||
test("the shorthand property form is caught", () => {
|
||||
// `{ retry }` is the same declaration as `{ retry: 2 }` with the value bound
|
||||
// above, and a colon-requiring pattern misses it entirely (Copilot).
|
||||
assert.deepEqual(
|
||||
findTestLevelRetries('const retry = 2; it("x", { retry }, () => {});'),
|
||||
["retry (shorthand)"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
findTestLevelRetries('it("x", { timeout: 100, retry }, () => {});'),
|
||||
["retry (shorthand)"],
|
||||
);
|
||||
});
|
||||
|
||||
test("a member call is not mistaken for the imported binding", () => {
|
||||
// `\\b` succeeds straight after a dot, so `other.configure(…)` satisfied the
|
||||
// check while the imported binding was never called at all (Copilot).
|
||||
const source = `import { configure } from "storybook/test";
|
||||
other.configure({ asyncUtilTimeout: 1000 });`;
|
||||
assert.deepEqual(checkAsyncUtilSource(source, "storybook/test"), [
|
||||
"does not call configure()",
|
||||
]);
|
||||
});
|
||||
|
||||
test("a longer identifier ending in the binding name is not a call to it", () => {
|
||||
const source = `import { configure } from "storybook/test";
|
||||
reconfigure({ asyncUtilTimeout: 1000 });`;
|
||||
assert.deepEqual(checkAsyncUtilSource(source, "storybook/test"), [
|
||||
"does not call configure()",
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue