推进 INI 面板 run G-code workflow helper

This commit is contained in:
2026-06-14 21:38:37 +08:00
parent 8e8a319d78
commit 75818c1379
7 changed files with 412 additions and 66 deletions

View File

@@ -0,0 +1,149 @@
import assert from "node:assert/strict";
import {
runGcodeSessionWorkflow,
selectSessionGcodeProgram,
} from "../../../runtime/ui/ini-panel/run-workflow.js";
const defaultProgram = selectSessionGcodeProgram({
defaultFilename: "ui-session.ngc",
defaultOpfsPath: "linuxcnc/gcode/ui-session.ngc",
wasmPath: "/work/ui-session.ngc",
gcodeFilenameFromProgramPath: () => {
throw new Error("not used");
},
});
assert.deepEqual(defaultProgram, {
filename: "ui-session.ngc",
opfsPath: "linuxcnc/gcode/ui-session.ngc",
source: "default",
wasmPath: "/work/ui-session.ngc",
});
const snapshotProgram = selectSessionGcodeProgram({
snapshot: {
payload: {
files: {
gcode: "linuxcnc/gcode/snapshot-session.ngc",
},
},
},
defaultFilename: "ui-session.ngc",
defaultOpfsPath: "linuxcnc/gcode/ui-session.ngc",
wasmPath: "/work/ui-session.ngc",
gcodeFilenameFromProgramPath: (path) => path.split("/").at(-1),
});
assert.deepEqual(snapshotProgram, {
filename: "snapshot-session.ngc",
opfsPath: "linuxcnc/gcode/snapshot-session.ngc",
source: "snapshot",
wasmPath: "/work/ui-session.ngc",
});
const calls = [];
const workflow = await runGcodeSessionWorkflow({
interp: {
writeTextFile: (wasmPath, text) => {
calls.push(["writeTextFile", wasmPath, text]);
},
runFileWithIni: (programWasmPath, iniWasmPath) => {
calls.push(["runFileWithIni", programWasmPath, iniWasmPath]);
return [
"canon_event=STRAIGHT_FEED line=1 x=1 y=2",
"run_step phase=execute line=1 x=1 y=2 statement_uri=G1%20X1%20Y2",
"",
].join("\n");
},
},
loadedSession: {
ini: {
wasmPath: "/work/session-machine.ini",
},
},
snapshot: {
sessionId: "ui-machine-session",
metadata: {
workflow: "save-session-snapshot",
snapshotLabel: "ui-machine-session/ui-machine-session.json",
defaultGcodeOpfsPath: "linuxcnc/gcode/ui-session.ngc",
},
payload: {
files: {
gcode: "linuxcnc/gcode/snapshot-session.ngc",
},
},
},
defaultFilename: "ui-session.ngc",
defaultOpfsPath: "linuxcnc/gcode/ui-session.ngc",
wasmPath: "/work/ui-session.ngc",
gcodeFilenameFromProgramPath: (path) => path.split("/").at(-1),
loadGcodeProgram: async (filename) => {
calls.push(["loadGcodeProgram", filename]);
return "G1 X1 Y2\n";
},
snapshotLabel: "ui-machine-session/ui-machine-session.json",
summarizeRun: (resultText, programText) => {
calls.push(["summarizeRun", resultText, programText]);
return {
canonicalEventCount: 1,
motionSnapshotCount: 1,
motionSnapshots: [{ line: 1 }],
};
},
});
assert.deepEqual(calls, [
["loadGcodeProgram", "snapshot-session.ngc"],
["writeTextFile", "/work/ui-session.ngc", "G1 X1 Y2\n"],
["runFileWithIni", "/work/ui-session.ngc", "/work/session-machine.ini"],
[
"summarizeRun",
"canon_event=STRAIGHT_FEED line=1 x=1 y=2\nrun_step phase=execute line=1 x=1 y=2 statement_uri=G1%20X1%20Y2",
"G1 X1 Y2\n",
],
]);
assert.deepEqual(workflow.summary, {
runStatus: "ok",
programSource: "snapshot",
snapshotLabel: "ui-machine-session/ui-machine-session.json",
workflow: "save-session-snapshot",
programOpfsPath: "linuxcnc/gcode/snapshot-session.ngc",
programWasmPath: "/work/ui-session.ngc",
iniWasmPath: "/work/session-machine.ini",
canonicalEventCount: 1,
motionSnapshotCount: 1,
});
assert.deepEqual(workflow.fields, {
sessionGcode: "linuxcnc/gcode/snapshot-session.ngc",
runStatus: "ok",
runSource: "snapshot",
runSnapshot: "ui-machine-session/ui-machine-session.json",
runWorkflow: "save-session-snapshot",
runOpfsPath: "linuxcnc/gcode/snapshot-session.ngc",
runWasmPath: "/work/ui-session.ngc",
});
assert.deepEqual(workflow.motionSnapshots, [{ line: 1 }]);
assert.deepEqual(workflow.logLines, [
"Program: linuxcnc/gcode/snapshot-session.ngc -> /work/ui-session.ngc",
"Program source: snapshot",
"Snapshot: ui-machine-session/ui-machine-session.json",
"Workflow: save-session-snapshot",
"Default G-code: linuxcnc/gcode/ui-session.ngc",
"INI: /work/session-machine.ini",
"canon_event=STRAIGHT_FEED line=1 x=1 y=2\nrun_step phase=execute line=1 x=1 y=2 statement_uri=G1%20X1%20Y2",
]);
await assert.rejects(
() => runGcodeSessionWorkflow({
loadedSession: null,
}),
/Load a machine session before running G-code/,
);
console.log("ini_panel_run_workflow_node_smoke=ok");

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
node "$ROOT_DIR/tests/ui/node/verify_ini_panel_run_workflow.mjs"

View File

@@ -4,6 +4,7 @@ set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_run_summary.sh"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_run_workflow.sh"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_session_summary.sh"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_session_workflow.sh"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_machine_file_summary.sh"