mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 18:52:48 +00:00
test: close the wait-deadline review gaps
- doctorCancellation measured from the signal, after the probe had started, so a probe stopped by its own deadline could still pass. The fake probe now records its start, and the check runs from there. - rea/project-wait-deadline missed literal computed `timeout` keys and spread options. It now reports both, as well as computed keys it cannot read. - The testing guide notes that a long-running test's expect.poll keeps its project budget, while waitFor follows the tag's deadline. Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
This commit is contained in:
1 parent
4baf1b6193
commit
55c9e8e546
4 files changed
+26
-8
No files matched your search
@@ -324,6 +324,8 @@ Waits follow the same policy; Vitest's one-second `expect.poll` and
|
||||
test may run, less the reporting reserve: projects configure `expect.poll`
|
||||
that way, and `waitFor` from `tests/support/testWait.ts` replaces `vi.waitFor`.
|
||||
Fixture waits such as `awaitAcknowledgement` default to the same deadline.
|
||||
`expect.poll` keeps its project's budget in a `long-running` test, while
|
||||
`waitFor` follows the deadline the tag applies.
|
||||
`rea/project-wait-deadline` rejects `vi.waitFor` and explicit poll timeouts. When promptness is the behavior under test, such as
|
||||
cancellation that must preempt a slower production deadline, a wait timeout is
|
||||
not its oracle: order the condition before releasing the gate that would
|
||||
|
||||
@@ -47,15 +47,26 @@ const isVitestMethod = (sourceCode, callee, receiver, method) => {
|
||||
);
|
||||
};
|
||||
|
||||
/** A wait timeout written at the call: a number, or an options `timeout`. */
|
||||
const keyName = (property) => {
|
||||
if (!property.computed) return property.key.name ?? property.key.value;
|
||||
return property.key.type === "Literal" ? property.key.value : undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* A wait timeout the call may set: a number or other non-literal options, an
|
||||
* options `timeout` (including a literal computed key), or a spread whose
|
||||
* properties the rule cannot see.
|
||||
*/
|
||||
const explicitTimeout = (options) => {
|
||||
if (options === undefined) return undefined;
|
||||
if (options.type !== "ObjectExpression") return options;
|
||||
return options.properties.find(
|
||||
(property) =>
|
||||
property.type === "Property" &&
|
||||
!property.computed &&
|
||||
(property.key.name ?? property.key.value) === "timeout",
|
||||
property.type === "SpreadElement" ||
|
||||
(property.type === "Property" &&
|
||||
(property.computed && property.key.type !== "Literal"
|
||||
? true
|
||||
: keyName(property) === "timeout")),
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ cliTest.skipIf(!["darwin", "linux"].includes(process.platform)).for(
|
||||
executable,
|
||||
`#!${process.execPath}
|
||||
if (!process.argv.slice(2).includes(${JSON.stringify(probeArgument)})) process.exit(7);
|
||||
require("node:fs").writeFileSync(${JSON.stringify(ready)}, JSON.stringify({pid: process.pid, runId: process.env.REA_PROCESS_RUN_ID}));
|
||||
require("node:fs").writeFileSync(${JSON.stringify(ready)}, JSON.stringify({pid: process.pid, runId: process.env.REA_PROCESS_RUN_ID, at: Date.now()}));
|
||||
process.on("SIGTERM", () => {});
|
||||
setInterval(() => { if (require("node:fs").existsSync(${JSON.stringify(release)})) process.exit(0); }, 25).unref();
|
||||
setTimeout(() => process.exit(99), 20000);
|
||||
@@ -104,12 +104,14 @@ setTimeout(() => process.exit(99), 20000);
|
||||
.strictObject({
|
||||
pid: z.number().int().positive(),
|
||||
runId: z.string().uuid(),
|
||||
at: z.number(),
|
||||
})
|
||||
.parse(readyRecord)
|
||||
: z
|
||||
.strictObject({
|
||||
pid: z.number().int().positive(),
|
||||
runId: z.string().min(1),
|
||||
at: z.number(),
|
||||
})
|
||||
.parse(readyRecord);
|
||||
if (provider === "jadx") {
|
||||
@@ -119,12 +121,11 @@ setTimeout(() => process.exit(99), 20000);
|
||||
runId: observed.runId,
|
||||
};
|
||||
}
|
||||
const signalled = performance.now();
|
||||
child.kill(signal);
|
||||
await expect.poll(() => child.exitCode).not.toBeNull();
|
||||
// Without cancellation, doctor would end when the probe's own deadline
|
||||
// (JadxJavaProbe and KunaInstallation: 10 s) stopped the probe.
|
||||
expect(performance.now() - signalled).toBeLessThan(PROBE_DEADLINE_MS);
|
||||
// (JadxJavaProbe and KunaInstallation: 10 s from its start) stopped it.
|
||||
expect(Date.now() - observed.at).toBeLessThan(PROBE_DEADLINE_MS);
|
||||
const result = await closed;
|
||||
expect(JSON.parse(stdout)).toMatchObject({ code: "cancelled" });
|
||||
if (ownership !== undefined) {
|
||||
|
||||
@@ -17,6 +17,7 @@ tester.run("project-wait-deadline", rule, {
|
||||
`${vitest} await expect.poll(() => ready).toBe(true);`,
|
||||
`${vitest} await expect.poll(() => ready, { interval: 10 }).toBe(true);`,
|
||||
`${vitest} await expect.poll(() => ready, { message: "ready" }).toBe(true);`,
|
||||
`${vitest} await expect.poll(() => ready, { ["interval"]: 10 }).toBe(true);`,
|
||||
`import { waitFor } from "../support/testWait.js"; await waitFor(() => ready, { interval: 10 });`,
|
||||
// Same names that are not Vitest's: a fixture method, or a shadowed local.
|
||||
`${vitest} await fixture.vi.waitFor(() => ready, { timeout: 5_000 });`,
|
||||
@@ -40,6 +41,9 @@ tester.run("project-wait-deadline", rule, {
|
||||
`${vitest} await expect.poll(() => ready, options).toBe(true);`,
|
||||
`import { expect as assert } from "vitest"; await assert.poll(() => ready, { timeout: 5 }).toBe(true);`,
|
||||
`import * as vitest from "vitest"; await vitest.expect.poll(() => ready, { "timeout": 5 }).toBe(true);`,
|
||||
`${vitest} await expect.poll(() => ready, { ["timeout"]: 5 }).toBe(true);`,
|
||||
`${vitest} await expect.poll(() => ready, { ...{ timeout: 5 } }).toBe(true);`,
|
||||
`${vitest} await expect.poll(() => ready, { [key]: 5 }).toBe(true);`,
|
||||
].map((code) => ({
|
||||
code,
|
||||
filename,
|
||||
|
||||
Reference in new issue
Block a user