mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-11-09 07:23:14 +00:00
Preserve renderer state through mute and export transitions, gate hover previews on a composed frame, and align timeline bounds with authored zoom intervals. Improve settings, cursor and webcam controls, inline recording countdown, project recovery and safe library cleanup.
56 lines
2.2 KiB
TypeScript
56 lines
2.2 KiB
TypeScript
import { afterEach, beforeEach, expect, it, vi } from "vitest";
|
|
import { createCountdownController } from "./countdownController";
|
|
|
|
beforeEach(() => vi.useFakeTimers());
|
|
afterEach(() => vi.useRealTimers());
|
|
|
|
it("emits 3, 2, 1 from the main-process timer and settles without a window", async () => {
|
|
const state = vi.fn();
|
|
const controller = createCountdownController(state);
|
|
const pending = controller.start(3);
|
|
expect(state).toHaveBeenLastCalledWith(3);
|
|
await vi.advanceTimersByTimeAsync(3000);
|
|
await expect(pending).resolves.toEqual({ success: true });
|
|
expect(state.mock.calls).toEqual([[3], [2], [1], [null]]);
|
|
expect(vi.getTimerCount()).toBe(0);
|
|
});
|
|
|
|
it("cancels immediately, releases the timer and allows another start", async () => {
|
|
const state = vi.fn();
|
|
const controller = createCountdownController(state);
|
|
const pending = controller.start(3);
|
|
controller.cancel();
|
|
await expect(pending).resolves.toEqual({ success: false, cancelled: true });
|
|
expect(state).toHaveBeenLastCalledWith(null);
|
|
expect(vi.getTimerCount()).toBe(0);
|
|
const next = controller.start(1);
|
|
await vi.advanceTimersByTimeAsync(1000);
|
|
await expect(next).resolves.toEqual({ success: true });
|
|
});
|
|
|
|
it("does not let a concurrent start replace the active recording countdown", async () => {
|
|
const state = vi.fn();
|
|
const controller = createCountdownController(state);
|
|
const pending = controller.start(2);
|
|
await expect(controller.start(3)).resolves.toMatchObject({ success: false });
|
|
await vi.advanceTimersByTimeAsync(2000);
|
|
await expect(pending).resolves.toEqual({ success: true });
|
|
expect(state.mock.calls).toEqual([[2], [1], [null]]);
|
|
});
|
|
|
|
it.each([-1, Number.NaN, Number.POSITIVE_INFINITY])("rejects invalid delay %s", async (delay) => {
|
|
const state = vi.fn();
|
|
await expect(createCountdownController(state).start(delay)).resolves.toMatchObject({
|
|
success: false,
|
|
});
|
|
expect(state).not.toHaveBeenCalled();
|
|
expect(vi.getTimerCount()).toBe(0);
|
|
});
|
|
|
|
it("settles zero delay immediately without adding a timer", async () => {
|
|
const state = vi.fn();
|
|
await expect(createCountdownController(state).start(0)).resolves.toEqual({ success: true });
|
|
expect(state.mock.calls).toEqual([[null]]);
|
|
expect(vi.getTimerCount()).toBe(0);
|
|
});
|