release: bump version to 0.50.0
This commit is contained in:
101
frontend/public/earth/js/cruise-sequencer.test.js
Normal file
101
frontend/public/earth/js/cruise-sequencer.test.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import { CruiseSequencer } from "./cruise-sequencer.js";
|
||||
|
||||
function installWindow() {
|
||||
globalThis.window = {
|
||||
requestAnimationFrame: (callback) => setTimeout(callback, 0),
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
};
|
||||
}
|
||||
|
||||
function wait(ms = 8) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function createSequencer(options = {}) {
|
||||
installWindow();
|
||||
const calls = [];
|
||||
let active = true;
|
||||
let items = options.items || [{ id: "one" }, { id: "two" }];
|
||||
const sequencer = new CruiseSequencer({
|
||||
isActive: () => active,
|
||||
getItems: () => items,
|
||||
getItemId: (item) => item.id,
|
||||
dwellMs: options.dwellMs ?? 1,
|
||||
transitionGapMs: options.transitionGapMs ?? 1,
|
||||
presentationMode: options.presentationMode,
|
||||
clearCurrent: () => calls.push("clear"),
|
||||
focusItem: async (item) => calls.push(`focus:${item.id}`),
|
||||
presentItem: async (item) => {
|
||||
calls.push(`present:${item.id}`);
|
||||
return true;
|
||||
},
|
||||
hideItem: async (item) => {
|
||||
calls.push(`hide:${item.id}`);
|
||||
if (options.stopAfterHide) active = false;
|
||||
},
|
||||
});
|
||||
return {
|
||||
calls,
|
||||
items,
|
||||
sequencer,
|
||||
setItems: (nextItems) => {
|
||||
items = nextItems;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("CruiseSequencer presentation modes", () => {
|
||||
test("auto_advance keeps existing dwell, hide, and advance behavior", async () => {
|
||||
const { calls, sequencer } = createSequencer({ stopAfterHide: true });
|
||||
|
||||
await sequencer.advance();
|
||||
await wait();
|
||||
|
||||
expect(calls).toContain("focus:one");
|
||||
expect(calls).toContain("present:one");
|
||||
expect(calls).toContain("hide:one");
|
||||
});
|
||||
|
||||
test("pinned mode presents without auto hiding or advancing", async () => {
|
||||
const { calls, sequencer } = createSequencer({ presentationMode: "pinned" });
|
||||
|
||||
await sequencer.advance();
|
||||
await wait();
|
||||
|
||||
expect(calls).toEqual(["clear", "focus:one", "present:one"]);
|
||||
expect(sequencer.isPresentationPinned()).toBe(true);
|
||||
});
|
||||
|
||||
test("presentSpecificItem directly presents the requested item", async () => {
|
||||
const { calls, items, sequencer } = createSequencer({ presentationMode: "pinned" });
|
||||
|
||||
const presented = await sequencer.presentSpecificItem(items[1], { interrupt: true });
|
||||
|
||||
expect(presented).toBe(true);
|
||||
expect(calls).toEqual(["clear", "focus:two", "present:two"]);
|
||||
expect(sequencer.getCurrentItemId()).toBe("two");
|
||||
});
|
||||
|
||||
test("pinned mode keeps the presented item even when the live queue no longer contains it", async () => {
|
||||
const { items, sequencer, setItems } = createSequencer({ presentationMode: "pinned" });
|
||||
|
||||
await sequencer.presentSpecificItem(items[1], { interrupt: true });
|
||||
setItems([]);
|
||||
|
||||
expect(sequencer.getCurrentItem()).toEqual({ id: "two" });
|
||||
});
|
||||
|
||||
test("stop can preserve or clear a pinned presentation", async () => {
|
||||
const { sequencer } = createSequencer({ presentationMode: "pinned" });
|
||||
|
||||
await sequencer.advance();
|
||||
sequencer.stop({ preservePresentation: true });
|
||||
expect(sequencer.isPresentationPinned()).toBe(true);
|
||||
|
||||
sequencer.stop();
|
||||
expect(sequencer.isPresentationPinned()).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user