91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
// SimpleSyrup - workflow-focused ComfyUI extensions for image generation
|
|
// Copyright (C) 2026 Artificial Sweetener and contributors
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import {
|
|
OrderedMediaPreviewTransaction,
|
|
type OrderedMediaPreviewItem
|
|
} from "../src/orderedMediaPreviewTransaction";
|
|
import type { NativePreviewSlot } from "../src/orderedMediaPreviewAffordances";
|
|
|
|
describe("OrderedMediaPreviewTransaction", () => {
|
|
it("reorders the captured native surface without creating DOM elements", async () => {
|
|
let ready = false;
|
|
let rendered = items("one.png", "two.png");
|
|
const apply = vi.fn((next: OrderedMediaPreviewItem[]) => {
|
|
rendered = [...next];
|
|
});
|
|
const release = vi.fn();
|
|
const transaction = new OrderedMediaPreviewTransaction({
|
|
captureSurface: () => ({
|
|
items: rendered,
|
|
slots: [() => slot(0), () => slot(100)],
|
|
apply,
|
|
release
|
|
}),
|
|
authoritativeReady: () => ready,
|
|
stateChanged: vi.fn()
|
|
});
|
|
const childCount = document.body.childElementCount;
|
|
|
|
expect(transaction.move(0, 1)).toBe(true);
|
|
|
|
expect(rendered.map((item) => file(item.sourceUrl))).toEqual([
|
|
"two.png",
|
|
"one.png"
|
|
]);
|
|
expect(document.body.childElementCount).toBe(childCount);
|
|
transaction.authoritativePublished();
|
|
await new Promise((resolve) => setTimeout(resolve, 30));
|
|
expect(release).not.toHaveBeenCalled();
|
|
ready = true;
|
|
await vi.waitFor(() => {
|
|
expect(release).toHaveBeenCalledOnce();
|
|
});
|
|
transaction.dispose();
|
|
});
|
|
|
|
it("compacts removals through the same native surface", () => {
|
|
let rendered = items("one.png", "two.png", "three.png");
|
|
const transaction = new OrderedMediaPreviewTransaction({
|
|
captureSurface: () => ({
|
|
items: rendered,
|
|
slots: [() => slot(0), () => slot(100), () => slot(200)],
|
|
apply: (next) => {
|
|
rendered = [...next];
|
|
},
|
|
release: vi.fn()
|
|
}),
|
|
authoritativeReady: () => false,
|
|
stateChanged: vi.fn()
|
|
});
|
|
|
|
expect(transaction.remove(1)).toBe(true);
|
|
|
|
expect(rendered.map((item) => file(item.sourceUrl))).toEqual([
|
|
"one.png",
|
|
"three.png"
|
|
]);
|
|
expect(transaction.activeSlots()).toEqual([slot(0), slot(100)]);
|
|
transaction.dispose();
|
|
});
|
|
});
|
|
|
|
function items(...files: string[]): OrderedMediaPreviewItem[] {
|
|
return files.map((name) => {
|
|
const image = document.createElement("img");
|
|
image.src = `http://localhost/${name}`;
|
|
return { sourceUrl: image.src, image };
|
|
});
|
|
}
|
|
|
|
function slot(left: number): NativePreviewSlot {
|
|
return { left, top: 20, width: 80, height: 90 };
|
|
}
|
|
|
|
function file(sourceUrl: string): string {
|
|
return new URL(sourceUrl).pathname.slice(1);
|
|
}
|