| 1 | import { afterEach, beforeEach, describe, expect, it, vi } from "vite-plus/test"; |
| 2 | |
| 3 | import { |
| 4 | createDelayedStatus, |
| 5 | STATUS_MIN_VISIBLE_MS, |
| 6 | STATUS_SHOW_DELAY_MS, |
| 7 | type ShownStatus, |
| 8 | } from "./delayedStatus.ts"; |
| 9 | |
| 10 | function track() { |
| 11 | const changes: Array<ShownStatus<string> | null> = []; |
| 12 | const status = createDelayedStatus<string>((shown) => changes.push(shown)); |
| 13 | return { changes, status }; |
| 14 | } |
| 15 | |
| 16 | describe("createDelayedStatus", () => { |
| 17 | beforeEach(() => { |
| 18 | vi.useFakeTimers(); |
| 19 | }); |
| 20 | afterEach(() => { |
| 21 | vi.useRealTimers(); |
| 22 | }); |
| 23 | |
| 24 | it("never shows a status that clears before the show delay", () => { |
| 25 | const { changes, status } = track(); |
| 26 | status.update("a", "syncing"); |
| 27 | vi.advanceTimersByTime(STATUS_SHOW_DELAY_MS - 1); |
| 28 | status.update("a", null); |
| 29 | vi.runAllTimers(); |
| 30 | |
| 31 | expect(changes).toEqual([]); |
| 32 | }); |
| 33 | |
| 34 | it("holds each shown status for the minimum time, then hides it at once", () => { |
| 35 | const { changes, status } = track(); |
| 36 | status.update("a", "loading"); |
| 37 | vi.advanceTimersByTime(STATUS_SHOW_DELAY_MS); |
| 38 | expect(changes).toEqual([{ key: "a", value: "loading" }]); |
| 39 | |
| 40 | // A new label gets its own full hold, even during the first label's hold. |
| 41 | vi.advanceTimersByTime(1); |
| 42 | status.update("a", "syncing"); |
| 43 | status.update("a", null); |
| 44 | vi.advanceTimersByTime(STATUS_MIN_VISIBLE_MS - 1); |
| 45 | expect(changes.at(-1)).toEqual({ key: "a", value: "syncing" }); |
| 46 | vi.advanceTimersByTime(1); |
| 47 | expect(changes.at(-1)).toBeNull(); |
| 48 | |
| 49 | status.update("a", "syncing"); |
| 50 | vi.advanceTimersByTime(STATUS_SHOW_DELAY_MS + STATUS_MIN_VISIBLE_MS); |
| 51 | status.update("a", null); |
| 52 | expect(changes.at(-1)).toBeNull(); |
| 53 | }); |
| 54 | |
| 55 | it("drops the shown status at once when the key changes", () => { |
| 56 | const { changes, status } = track(); |
| 57 | status.update("a", "syncing"); |
| 58 | vi.advanceTimersByTime(STATUS_SHOW_DELAY_MS); |
| 59 | status.update("b", "syncing"); |
| 60 | expect(changes.at(-1)).toBeNull(); |
| 61 | |
| 62 | vi.advanceTimersByTime(STATUS_SHOW_DELAY_MS); |
| 63 | expect(changes.at(-1)).toEqual({ key: "b", value: "syncing" }); |
| 64 | }); |
| 65 | }); |