Files
MajoorWaldi-ComfyUI-Majoor-…/ui/tests/grid_selection_manager.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

114 lines
3.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
getSelectedIdSet,
reconcileSelectionIds,
safeEscapeId,
setSelectionIds,
syncSelectionClasses,
} from "../features/grid/GridSelectionManager.js";
function makeCard(id) {
const classSet = new Set();
const attrs = new Map();
return {
dataset: { mjrAssetId: String(id) },
classList: {
add(v) {
classSet.add(v);
},
remove(v) {
classSet.delete(v);
},
has(v) {
return classSet.has(v);
},
},
setAttribute(k, v) {
attrs.set(k, v);
},
getAttribute(k) {
return attrs.get(k);
},
};
}
describe("GridSelectionManager", () => {
it("supports single and multi selection dataset keys", () => {
const g1 = { dataset: { mjrSelectedAssetIds: JSON.stringify([1, "2"]) } };
expect(Array.from(getSelectedIdSet(g1)).sort()).toEqual(["1", "2"]);
const g2 = { dataset: { mjrSelectedAssetId: "9" } };
expect(Array.from(getSelectedIdSet(g2))).toEqual(["9"]);
});
it("updates cards and emits event when selection changes", () => {
const cards = [makeCard(1), makeCard(2), makeCard(3)];
const events = [];
globalThis.CustomEvent = class {
constructor(type, init) {
this.type = type;
this.detail = init?.detail;
}
};
globalThis.window = {
dispatchEvent(evt) {
events.push(evt);
},
};
const grid = {
dataset: {},
dispatchEvent(evt) {
events.push(evt);
},
};
syncSelectionClasses(grid, new Set(["2"]), () => cards);
expect(cards[1].classList.has("is-selected")).toBe(true);
expect(cards[0].getAttribute("aria-selected")).toBe("false");
const selected = setSelectionIds(grid, ["1", 3, "3"], { activeId: "3" }, () => cards);
expect(selected.sort()).toEqual(["1", "3"]);
expect(grid.dataset.mjrSelectedAssetId).toBe("3");
expect(events.length).toBeGreaterThanOrEqual(1);
});
it("falls back when CSS.escape is unavailable", () => {
globalThis.CSS = undefined;
expect(safeEscapeId('a"b\\c')).toBe('a\\"b\\\\c');
});
it("reconciles selection against visible assets and reports pruned items", () => {
const cards = [makeCard(1), makeCard(2), makeCard(3)];
const events = [];
globalThis.CustomEvent = class {
constructor(type, init) {
this.type = type;
this.detail = init?.detail;
}
};
globalThis.window = {
dispatchEvent(evt) {
events.push(evt);
},
};
const grid = {
dataset: {
mjrSelectedAssetIds: JSON.stringify(["1", "2", "9"]),
mjrSelectedAssetId: "2",
},
dispatchEvent(evt) {
events.push(evt);
},
};
const result = reconcileSelectionIds(grid, ["2", "3"], { activeId: "2" }, () => cards);
expect(result.pruned).toBe(2);
expect(result.selectedIds).toEqual(["2"]);
expect(grid.dataset.mjrSelectedAssetIds).toBe(JSON.stringify(["2"]));
expect(grid.dataset.mjrSelectedAssetId).toBe("2");
expect(events.some((evt) => evt.type === "mjr:selection-changed")).toBe(true);
});
});