Files
MajoorWaldi-ComfyUI-Majoor-…/ui/tests/use_grid_selection.vitest.ts
T
Ewald 85a82f130a test: migrate ui/tests from .mjs to .ts
- Rename 132 *.vitest.mjs -> *.vitest.ts
- Rename vitest.setup.mjs -> vitest.setup.ts
- Rename helpers/vitestEnvironment.mjs -> vitestEnvironment.ts
- Delete settings_store.test.mjs (Node test runner, superseded by .vitest.ts)
- Fix .mjs imports in vitest.setup.ts and grid_loader_adaptive_paging.vitest.ts

Config updates:
- vitest.config.mjs: setupFiles, include, coverage.include -> .ts
- tsconfig.test.json: new dedicated config for test files (strict:false)
- knip.json: update project pattern for tests
- package.json: add typecheck:tests script (audit-only)
2026-05-26 13:04:05 +02:00

123 lines
4.1 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
function createGridContainer() {
const bus = new EventTarget();
return {
dataset: {},
children: [],
addEventListener: (...args) => bus.addEventListener(...args),
removeEventListener: (...args) => bus.removeEventListener(...args),
dispatchEvent: (...args) => bus.dispatchEvent(...args),
appendChild(child) {
this.children.push(child);
},
querySelector(selector) {
const match = selector.match(/data-mjr-asset-id="([^"]+)"/);
if (!match) return null;
const wantedId = String(match[1] || "").replace(/\\([:])/g, "$1");
return (
this.children.find(
(child) =>
child?.className === "mjr-asset-card" &&
String(child?.dataset?.mjrAssetId || "") === wantedId,
) || null
);
},
};
}
describe("useGridSelection", () => {
beforeEach(() => {
vi.restoreAllMocks();
globalThis.CustomEvent =
globalThis.CustomEvent ||
class extends Event {
constructor(type, init = {}) {
super(type);
this.detail = init.detail;
}
};
});
it("syncs selection events back to panel state writers", async () => {
const { bindGridSelectionState } = await import("../vue/composables/useGridSelection.js");
const gridContainer = createGridContainer();
const writeSelectedAssetIds = vi.fn();
const writeActiveAssetId = vi.fn();
const onSelectionChanged = vi.fn();
bindGridSelectionState({
gridContainer,
writeSelectedAssetIds,
writeActiveAssetId,
onSelectionChanged,
});
gridContainer.dispatchEvent(
new CustomEvent("mjr:selection-changed", {
detail: {
selectedIds: [12, "34", "", null],
activeId: "34",
},
}),
);
expect(writeSelectedAssetIds).toHaveBeenCalledWith(["12", "34"]);
expect(writeActiveAssetId).toHaveBeenCalledWith("34");
expect(onSelectionChanged).toHaveBeenCalledWith(
expect.objectContaining({
selectedIds: [12, "34", "", null],
activeId: "34",
}),
);
});
it("restores persisted selection and scroll target on the grid", async () => {
const { bindGridSelectionState } = await import("../vue/composables/useGridSelection.js");
const gridContainer = createGridContainer();
gridContainer._mjrSetSelection = vi.fn();
gridContainer._mjrScrollToAssetId = vi.fn();
const binding = bindGridSelectionState({
gridContainer,
readSelectedAssetIds: () => ["asset-1", "asset-2"],
readActiveAssetId: () => "asset-2",
});
binding.restoreSelectionState({ scrollTop: 0 });
expect(gridContainer._mjrSetSelection).toHaveBeenCalledWith(
["asset-1", "asset-2"],
"asset-2",
);
expect(gridContainer._mjrScrollToAssetId).toHaveBeenCalledWith("asset-2");
});
it("falls back to scrolling the matching DOM card into view when needed", async () => {
const { bindGridSelectionState } = await import("../vue/composables/useGridSelection.js");
const gridContainer = createGridContainer();
const card = {
className: "mjr-asset-card",
dataset: { mjrAssetId: "asset:2" },
scrollIntoView: vi.fn(),
};
gridContainer.appendChild(card);
const binding = bindGridSelectionState({
gridContainer,
readSelectedAssetIds: () => ["asset:2"],
readActiveAssetId: () => "asset:2",
});
binding.restoreSelectionState({ scrollTop: 0 });
expect(card.scrollIntoView).toHaveBeenCalledWith({
block: "nearest",
behavior: "instant",
});
});
});