83 lines
3.6 KiB
JavaScript
83 lines
3.6 KiB
JavaScript
"use strict";
|
|
|
|
const test = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
const workflow = require("../../Web/legacy-batch-selection-workflow.js");
|
|
|
|
test("legacy pointer gestures preserve MainForm selection and anchor semantics", () => {
|
|
let selection = workflow.createSelection(8);
|
|
selection = workflow.applyPointerSelection(selection, 3);
|
|
assert.deepEqual(selection.selectedIndices, [3]);
|
|
assert.equal(selection.anchorIndex, 3);
|
|
|
|
selection = workflow.applyPointerSelection(selection, 5, { ctrlKey: true });
|
|
assert.deepEqual(selection.selectedIndices, [3, 5]);
|
|
assert.equal(selection.anchorIndex, 5);
|
|
|
|
selection = workflow.applyPointerSelection(selection, 2, { shiftKey: true });
|
|
assert.deepEqual(selection.selectedIndices, [2, 3, 4, 5]);
|
|
assert.equal(selection.anchorIndex, 2);
|
|
|
|
selection = workflow.applyPointerSelection(selection, 6, { ctrlKey: true, shiftKey: true });
|
|
assert.deepEqual(selection.selectedIndices, [2, 3, 4, 5, 6]);
|
|
assert.equal(selection.anchorIndex, 6);
|
|
|
|
selection = workflow.applyPointerSelection(selection, 4, { ctrlKey: true });
|
|
assert.deepEqual(selection.selectedIndices, [2, 3, 5, 6]);
|
|
assert.equal(selection.anchorIndex, 4);
|
|
});
|
|
|
|
test("shift without an existing anchor safely selects only the clicked row", () => {
|
|
const selection = workflow.applyPointerSelection(
|
|
workflow.createSelection(4),
|
|
2,
|
|
{ shiftKey: true });
|
|
assert.deepEqual(selection.selectedIndices, [2]);
|
|
assert.equal(selection.anchorIndex, 2);
|
|
});
|
|
|
|
test("double-click activation is allowed only for the single clicked selection", () => {
|
|
assert.equal(workflow.canActivateSingle(workflow.createSelection(5, [2], 2), 2), true);
|
|
assert.equal(workflow.canActivateSingle(workflow.createSelection(5, [2], 2), 1), false);
|
|
assert.equal(workflow.canActivateSingle(workflow.createSelection(5, [1, 2], 2), 2), false);
|
|
assert.equal(workflow.canActivateSingle(null, 0), false);
|
|
});
|
|
|
|
test("selection snapshots reject malformed or out-of-range state", () => {
|
|
assert.throws(() => workflow.createSelection(-1), RangeError);
|
|
assert.throws(() => workflow.createSelection(3, [3]), RangeError);
|
|
assert.throws(() => workflow.createSelection(3, [0], 3), RangeError);
|
|
assert.throws(() => workflow.applyPointerSelection(workflow.createSelection(3), -1), RangeError);
|
|
});
|
|
|
|
test("atomic batch materialization preserves source order and commits only after success", () => {
|
|
const source = [{ code: "A" }, { code: "B" }, { code: "C" }];
|
|
const playlist = [{ id: "existing" }];
|
|
const entries = workflow.materializeAtomicBatch(source, (item, index) => ({
|
|
id: `batch-${index}`,
|
|
code: item.code
|
|
}));
|
|
playlist.push(...entries);
|
|
assert.deepEqual(playlist.map(item => item.code || item.id), ["existing", "A", "B", "C"]);
|
|
|
|
const unchanged = [...playlist];
|
|
assert.throws(() => {
|
|
const failed = workflow.materializeAtomicBatch(source, (item, index) => {
|
|
if (index === 1) throw new Error("unsupported");
|
|
return { id: `failed-${index}`, code: item.code };
|
|
});
|
|
playlist.push(...failed);
|
|
}, /unsupported/u);
|
|
assert.deepEqual(playlist, unchanged);
|
|
});
|
|
|
|
test("atomic batches reject empty, malformed, unsafe, or duplicate entries", () => {
|
|
assert.throws(() => workflow.materializeAtomicBatch([], () => ({})), RangeError);
|
|
assert.throws(() => workflow.materializeAtomicBatch([1], null), TypeError);
|
|
assert.throws(() => workflow.materializeAtomicBatch([1], () => null), TypeError);
|
|
assert.throws(() => workflow.materializeAtomicBatch([1], () => ({ id: "unsafe id" })), TypeError);
|
|
assert.throws(
|
|
() => workflow.materializeAtomicBatch([1, 2], () => ({ id: "duplicate" })),
|
|
TypeError);
|
|
});
|