Files
Piik/tests/decoded-frame-proof.test.ts

90 lines
2.3 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { observeDecodedFrameProof } from "../src/client/media/decoded-frame-proof";
interface Deferred<T> {
promise: Promise<T>;
resolve: (value: T) => void;
}
function deferred<T>(): Deferred<T> {
let resolve!: (value: T) => void;
const promise = new Promise<T>((next) => {
resolve = next;
});
return { promise, resolve };
}
beforeEach(() => {
vi.useFakeTimers();
vi.stubGlobal("window", {
setTimeout,
clearTimeout,
});
});
afterEach(() => {
vi.clearAllTimers();
vi.useRealTimers();
vi.unstubAllGlobals();
});
describe("decoded frame proof observer", () => {
it("accepts the first cumulative frame on a fresh exact transport", async () => {
const readFramesDecoded = vi
.fn<() => Promise<number | null>>()
.mockResolvedValueOnce(0)
.mockResolvedValueOnce(1);
const onProof = vi.fn(() => true);
observeDecodedFrameProof({
readFramesDecoded,
owns: () => true,
onProof,
});
await vi.advanceTimersByTimeAsync(100);
expect(readFramesDecoded).toHaveBeenCalledTimes(2);
expect(onProof).toHaveBeenCalledOnce();
});
it("requires growth beyond a post-resume baseline", async () => {
const values = [7, 7, 8];
const onProof = vi.fn(() => true);
observeDecodedFrameProof({
readFramesDecoded: async () => values.shift() ?? 8,
owns: () => true,
requireProgress: true,
onProof,
});
await vi.advanceTimersByTimeAsync(100);
expect(onProof).not.toHaveBeenCalled();
await vi.advanceTimersByTimeAsync(100);
expect(onProof).toHaveBeenCalledOnce();
});
it("serializes reads and ignores an in-flight result after ownership ends", async () => {
const first = deferred<number | null>();
let owned = true;
const readFramesDecoded = vi.fn(() => first.promise);
const onProof = vi.fn(() => true);
const stop = observeDecodedFrameProof({
readFramesDecoded,
owns: () => owned,
onProof,
});
await vi.advanceTimersByTimeAsync(1_000);
expect(readFramesDecoded).toHaveBeenCalledOnce();
owned = false;
stop();
first.resolve(3);
await Promise.resolve();
await vi.runAllTimersAsync();
expect(onProof).not.toHaveBeenCalled();
expect(readFramesDecoded).toHaveBeenCalledOnce();
});
});