54 lines
3.0 KiB
JavaScript
54 lines
3.0 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 root = path.resolve(import.meta.dirname, "../../..");
|
|
const temporary = fs.mkdtempSync(path.join(os.tmpdir(), "io-format-ui-gate-unit-"));
|
|
const sourcePath = path.join(root, "web/protocol/io-format-ui-gate.ts");
|
|
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, []);
|
|
fs.writeFileSync(path.join(temporary, "io-format-ui-gate.mjs"), transpiled.outputText);
|
|
const gate = await import(pathToFileURL(path.join(temporary, "io-format-ui-gate.mjs")));
|
|
const registry = JSON.parse(fs.readFileSync(path.join(root, "web/app/src/capabilities/io-format-ui-registry.json"), "utf8"));
|
|
|
|
test("M12-05C keeps only matrix-declared executable routes in UI", () => {
|
|
const parsed = gate.parseIOFormatUIRegistry(registry);
|
|
assert.deepEqual(parsed.importRoutes, []);
|
|
assert.deepEqual(parsed.exportRoutes.map((route) => route.format), ["GLB"]);
|
|
const commands = [
|
|
{ id: "file.export-glb", ioFormat: { format: "GLB", operation: "EXPORT", execution: "LOCAL" } },
|
|
{ id: "file.import-obj", ioFormat: { format: "OBJ", operation: "IMPORT", execution: "LOCAL" } },
|
|
{ id: "file.export-usd", ioFormat: { format: "USD", operation: "EXPORT", execution: "SERVER" } },
|
|
{ id: "edit.undo" },
|
|
];
|
|
assert.deepEqual(gate.filterIOFormatOperatorCommands(commands, parsed).map((command) => command.id), ["file.export-glb", "edit.undo"]);
|
|
});
|
|
|
|
test("M12-05C file selection is project-only while import routes are blocked", () => {
|
|
const parsed = gate.parseIOFormatUIRegistry(registry);
|
|
assert.equal(gate.ioFormatUIAccept(parsed), ".blend,application/octet-stream");
|
|
assert.deepEqual(gate.gateIOFormatFileSelection("scene.blend", parsed), { status: "READY", kind: "BLEND" });
|
|
assert.deepEqual(gate.gateIOFormatFileSelection("mesh.obj", parsed), { status: "BLOCKED", code: "IO_FORMAT_UNSUPPORTED", extension: ".obj" });
|
|
assert.deepEqual(gate.gateIOFormatFileSelection("scene.glb", parsed), { status: "BLOCKED", code: "IO_FORMAT_UNSUPPORTED", extension: ".glb" });
|
|
});
|
|
|
|
test("M12-05C rejects malformed route metadata", () => {
|
|
const bad = structuredClone(registry);
|
|
bad.importRoutes = [{ format: "OBJ", operation: "IMPORT", execution: "LOCAL", extensions: [".obj"] }];
|
|
assert.doesNotThrow(() => gate.parseIOFormatUIRegistry(bad));
|
|
const parsed = gate.parseIOFormatUIRegistry(bad);
|
|
assert.equal(gate.filterIOFormatOperatorCommands([{ id: "import-obj", ioFormat: { format: "OBJ", operation: "IMPORT", execution: "LOCAL" } }], parsed).length, 1);
|
|
bad.importRoutes[0].extensions = [".not-obj"];
|
|
assert.throws(() => gate.parseIOFormatUIRegistry(bad), { code: "IO_FORMAT_UNSUPPORTED" });
|
|
});
|
|
|
|
test.after(() => fs.rmSync(temporary, { recursive: true, force: true }));
|