Files
cnc_wams/wasm-port/tests/opfs/node/verify_file_service.mjs
wangdequan 84bdc819b4 按建议,继续完成后续工作
结论:已新增 OPFS host-side 路径模型,覆盖 INI、tool table、parameter、G-code、preview cache 与 session snapshot 存储目标,并让 file-service 和浏览器 smoke 复用该模型;聚合 smoke 验证通过。
2026-06-08 03:26:39 +08:00

117 lines
2.9 KiB
JavaScript

import assert from "node:assert/strict";
import {
getOpfsRoot,
loadTextFile,
saveTextFile,
} from "../../../runtime/opfs/file-service.js";
import {
defaultMachinePaths,
gcodeProgramPath,
machineIniPath,
normalizeOpfsPath,
parameterFilePath,
previewCachePath,
sessionSnapshotPath,
toolTablePath,
} from "../../../runtime/opfs/path-model.js";
class MockFileHandle {
constructor(name) {
this.name = name;
this.textValue = "";
}
async createWritable() {
return {
write: async (text) => {
this.textValue = String(text);
},
close: async () => {},
};
}
async getFile() {
return {
text: async () => this.textValue,
};
}
}
class MockDirectoryHandle {
constructor(name = "") {
this.name = name;
this.dirs = new Map();
this.files = new Map();
}
async getDirectoryHandle(name, options = {}) {
if (!this.dirs.has(name)) {
if (!options.create) {
throw new Error(`missing directory: ${name}`);
}
this.dirs.set(name, new MockDirectoryHandle(name));
}
return this.dirs.get(name);
}
async getFileHandle(name, options = {}) {
if (!this.files.has(name)) {
if (!options.create) {
throw new Error(`missing file: ${name}`);
}
this.files.set(name, new MockFileHandle(name));
}
return this.files.get(name);
}
}
const root = new MockDirectoryHandle();
const storage = {
getDirectory: async () => root,
};
assert.equal(await getOpfsRoot(storage), root);
assert.equal(normalizeOpfsPath("linuxcnc/machines/xyzab.ini"), "linuxcnc/machines/xyzab.ini");
assert.equal(machineIniPath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/machine.ini");
assert.equal(toolTablePath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/tool.tbl");
assert.equal(parameterFilePath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/linuxcnc.var");
assert.equal(gcodeProgramPath("fixture.ngc"), "linuxcnc/gcode/fixture.ngc");
assert.equal(previewCachePath("fixture"), "linuxcnc/preview-cache/fixture/preview.json");
assert.equal(sessionSnapshotPath("session-1"), "linuxcnc/sessions/session-1/snapshot.json");
assert.deepEqual(defaultMachinePaths("xyzab-tdr"), {
ini: "linuxcnc/machines/xyzab-tdr/machine.ini",
toolTable: "linuxcnc/machines/xyzab-tdr/tool.tbl",
parameters: "linuxcnc/machines/xyzab-tdr/linuxcnc.var",
});
await saveTextFile(
"linuxcnc/machines/xyzab.ini",
"[EMC]\nMACHINE = opfs-smoke\n",
storage,
);
assert.equal(
await loadTextFile("linuxcnc/machines/xyzab.ini", storage),
"[EMC]\nMACHINE = opfs-smoke\n",
);
await assert.rejects(
() => loadTextFile("linuxcnc/machines/missing.ini", storage),
/missing file/,
);
await assert.rejects(
() => saveTextFile("../escape.ini", "", storage),
/Invalid OPFS path/,
);
assert.throws(
() => machineIniPath("../escape"),
/Invalid machine id/,
);
await assert.rejects(
() => getOpfsRoot({}),
/OPFS is not available/,
);
console.log("opfs_file_service_node_smoke=ok");