Files
matrix-screen-controller/核桃派软件源代码/tests/test_current_display_playback_ui.mjs
T

86 lines
3.0 KiB
JavaScript

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import test from "node:test";
import {
CURRENT_DISPLAY_SPEEDS,
LatestSeekDispatcher,
formatPlaybackTime,
projectPlaybackPosition,
} from "../app/static/current-display-playback.js";
const staticRoot = new URL("../app/static/", import.meta.url);
test("formats and projects looping playback without moving paused content", () => {
assert.deepEqual(CURRENT_DISPLAY_SPEEDS, [0.5, 1, 1.5, 2]);
assert.equal(formatPlaybackTime(65032), "1:05.03");
assert.equal(projectPlaybackPosition({
active: true,
position_ms: 900,
total_duration_ms: 1000,
paused: false,
speed: 2,
}, 100), 100);
assert.equal(projectPlaybackPosition({
active: true,
position_ms: 450,
total_duration_ms: 1000,
paused: true,
speed: 2,
}, 100), 450);
});
test("seek dispatcher keeps one request in flight and flushes the newest position", async () => {
let now = 0;
let releaseFirst;
const sent = [];
const timers = new Map();
let timerSequence = 0;
const dispatcher = new LatestSeekDispatcher((position) => {
sent.push(position);
if (sent.length === 1) return new Promise((resolve) => { releaseFirst = resolve; });
return Promise.resolve();
}, {
now: () => now,
setTimer: (callback) => {
const id = ++timerSequence;
timers.set(id, callback);
return id;
},
clearTimer: (id) => timers.delete(id),
});
dispatcher.enqueue(10);
await Promise.resolve();
await Promise.resolve();
dispatcher.enqueue(20);
dispatcher.enqueue(30);
dispatcher.enqueue(40, { flush: true });
assert.deepEqual(sent, [10]);
releaseFirst();
await new Promise((resolve) => setImmediate(resolve));
assert.deepEqual(sent, [10, 40]);
assert.equal(timers.size, 0);
});
test("topbar current display dialog exposes static close and animation controls", async () => {
const [html, device, style] = await Promise.all([
readFile(new URL("index.html", staticRoot), "utf8"),
readFile(new URL("views/device.js", staticRoot), "utf8"),
readFile(new URL("style.css", staticRoot), "utf8"),
]);
assert.match(html, /id="topbar-current-content"[^>]*type="button"[^>]*aria-controls="current-display-dialog"/);
assert.match(html, /id="current-display-dialog"[^>]*aria-labelledby="current-display-dialog-title"/);
assert.match(html, /id="current-display-preview-image"/);
assert.match(html, /id="current-display-progress"[^>]*type="range"/);
assert.equal((html.match(/data-playback-speed=/g) || []).length, 4);
assert.match(device, /event\.target === currentDisplayDialog/);
assert.match(device, /currentDisplayPlaybackControls\.hidden/);
assert.match(device, /intervalMs: 100/);
assert.match(device, /currentDisplayFinalSeekPosition/);
assert.match(device, /document\.visibilityState === "visible"/);
assert.match(style, /\.current-display-preview-surface[\s\S]*aspect-ratio:\s*1/);
assert.match(style, /@media \(max-width: 30rem\)[\s\S]*\.current-display-playback-actions[\s\S]*grid-template-columns:\s*1fr/);
});