79 lines
3.6 KiB
JavaScript
79 lines
3.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
import test from "node:test";
|
|
import ts from "typescript";
|
|
|
|
const repoRoot = path.resolve(import.meta.dirname, "../../..");
|
|
const sourcePath = path.join(repoRoot, "web/protocol/grease-pencil-selection.ts");
|
|
const temporary = fs.mkdtempSync(path.join(os.tmpdir(), "grease-pencil-selection-unit-"));
|
|
const transpiled = ts.transpileModule(fs.readFileSync(sourcePath, "utf8"), {
|
|
compilerOptions: { module: ts.ModuleKind.ES2022, target: ts.ScriptTarget.ES2022 },
|
|
fileName: sourcePath,
|
|
reportDiagnostics: true,
|
|
});
|
|
assert.deepEqual(transpiled.diagnostics, []);
|
|
const modulePath = path.join(temporary, "grease-pencil-selection.mjs");
|
|
fs.writeFileSync(modulePath, transpiled.outputText);
|
|
const selection = await import(pathToFileURL(modulePath));
|
|
|
|
const drawing = {
|
|
dataId: "grease-pencil:Data",
|
|
layerId: "grease-pencil-layer:Data:Lines",
|
|
frame: 12,
|
|
drawingId: "grease-pencil-drawing:Data:4",
|
|
};
|
|
|
|
function point(strokeIndex, pointIndex) {
|
|
return {
|
|
...drawing,
|
|
strokeId: `grease-pencil-stroke:Data:4:${strokeIndex}`,
|
|
pointId: `grease-pencil-point:Data:4:${strokeIndex}:${pointIndex}`,
|
|
strokeIndex,
|
|
pointIndex,
|
|
};
|
|
}
|
|
|
|
function edit(baseSelectionRevision, source, operation, points) {
|
|
return { schemaVersion: 1, baseSelectionRevision, source, operation, points };
|
|
}
|
|
|
|
test("M9-07 serializes 2D canvas and 3D viewport edits through one selection revision", () => {
|
|
const initial = selection.createGreasePencilSelectionState(drawing);
|
|
const canvas = selection.applyGreasePencilSelectionEdit(initial, edit(0, "CANVAS_2D", "REPLACE", [point(0, 1)]), drawing);
|
|
assert.equal(canvas.revision, 1);
|
|
assert.equal(canvas.lastSource, "CANVAS_2D");
|
|
assert.deepEqual(canvas.selectedPoints.map((item) => item.pointId), [point(0, 1).pointId]);
|
|
|
|
const viewport = selection.applyGreasePencilSelectionEdit(canvas, edit(1, "VIEWPORT_3D", "ADD", [point(0, 0), point(1, 0)]), drawing);
|
|
assert.equal(viewport.revision, 2);
|
|
assert.equal(viewport.lastSource, "VIEWPORT_3D");
|
|
assert.deepEqual(viewport.selectedPoints.map((item) => item.pointId), [point(0, 0).pointId, point(0, 1).pointId, point(1, 0).pointId]);
|
|
|
|
const toggled = selection.applyGreasePencilSelectionEdit(viewport, edit(2, "CANVAS_2D", "TOGGLE", [point(0, 1)]), drawing);
|
|
assert.equal(toggled.revision, 3);
|
|
assert.deepEqual(toggled.selectedPoints.map((item) => item.pointId), [point(0, 0).pointId, point(1, 0).pointId]);
|
|
});
|
|
|
|
test("M9-07 rejects stale, foreign, duplicate and index-aliased selection edits", () => {
|
|
const initial = selection.createGreasePencilSelectionState(drawing);
|
|
assert.throws(
|
|
() => selection.applyGreasePencilSelectionEdit(initial, edit(1, "VIEWPORT_3D", "REPLACE", [point(0, 0)]), drawing),
|
|
(error) => error.code === "REVISION_CONFLICT",
|
|
);
|
|
assert.throws(
|
|
() => selection.applyGreasePencilSelectionEdit(initial, edit(0, "CANVAS_2D", "REPLACE", [{ ...point(0, 0), drawingId: "grease-pencil-drawing:Data:5" }]), drawing),
|
|
(error) => error.code === "GREASE_PENCIL_SELECTION_SCOPE_INVALID",
|
|
);
|
|
assert.throws(
|
|
() => selection.applyGreasePencilSelectionEdit(initial, edit(0, "CANVAS_2D", "REPLACE", [point(0, 0), point(0, 0)]), drawing),
|
|
(error) => error.code === "GREASE_PENCIL_SELECTION_INVALID",
|
|
);
|
|
assert.throws(
|
|
() => selection.applyGreasePencilSelectionEdit(initial, edit(0, "CANVAS_2D", "REPLACE", [point(0, 0), { ...point(0, 1), pointIndex: 0 }]), drawing),
|
|
(error) => error.code === "GREASE_PENCIL_SELECTION_INVALID",
|
|
);
|
|
});
|