usePolled reports when a request is in flight (through a new onBusy of the poller) and holds it on for at least 0.4 seconds, so a quick answer still reads as a refresh. The picker swaps its clock for the spinner, in the same box so its width stays, and the spinner stands still where motion is off. Every page with a picker passes it; a page with several polled requests shows it while any of them runs. The Jobs page fetches through shared components and has none yet.
77 lines
2 KiB
JavaScript
77 lines
2 KiB
JavaScript
// What the refresh spinner shows: on at once, off only after a minimum time.
|
|
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import { createBusyHold } from "../src/ui/polled/busy-hold.ts";
|
|
|
|
// A clock and a timer the test moves by hand.
|
|
function rig() {
|
|
let t = 0;
|
|
const timers = [];
|
|
const shown = [];
|
|
const hold = createBusyHold({
|
|
show: (s) => shown.push(s),
|
|
minMs: 400,
|
|
now: () => t,
|
|
after: (fn, ms) => {
|
|
const timer = { fn, at: t + ms, live: true };
|
|
timers.push(timer);
|
|
return timer;
|
|
},
|
|
cancel: (timer) => {
|
|
timer.live = false;
|
|
},
|
|
});
|
|
const advance = (ms) => {
|
|
t += ms;
|
|
for (const timer of timers) {
|
|
if (timer.live && timer.at <= t) {
|
|
timer.live = false;
|
|
timer.fn();
|
|
}
|
|
}
|
|
};
|
|
return { hold, shown, advance };
|
|
}
|
|
|
|
test("it turns on at once and, for a quick answer, off only after the minimum", () => {
|
|
const { hold, shown, advance } = rig();
|
|
hold.busy(true);
|
|
assert.deepEqual(shown, [true]);
|
|
advance(50);
|
|
hold.busy(false);
|
|
assert.deepEqual(shown, [true]);
|
|
advance(349);
|
|
assert.deepEqual(shown, [true]);
|
|
advance(1);
|
|
assert.deepEqual(shown, [true, false]);
|
|
});
|
|
|
|
test("a slow answer turns it off as soon as it arrives", () => {
|
|
const { hold, shown, advance } = rig();
|
|
hold.busy(true);
|
|
advance(900);
|
|
hold.busy(false);
|
|
assert.deepEqual(shown, [true, false]);
|
|
});
|
|
|
|
test("a new request while it is held keeps it on and cancels the pending off", () => {
|
|
const { hold, shown, advance } = rig();
|
|
hold.busy(true);
|
|
advance(100);
|
|
hold.busy(false);
|
|
hold.busy(true);
|
|
advance(1000);
|
|
assert.deepEqual(shown, [true]);
|
|
hold.busy(false);
|
|
assert.deepEqual(shown, [true, false]);
|
|
});
|
|
|
|
test("stop drops a pending off, and busy(false) with nothing shown does nothing", () => {
|
|
const { hold, shown, advance } = rig();
|
|
hold.busy(false);
|
|
hold.busy(true);
|
|
hold.busy(false);
|
|
hold.stop();
|
|
advance(1000);
|
|
assert.deepEqual(shown, [true]);
|
|
});
|