按规划持续工作

This commit is contained in:
2026-06-09 06:13:28 +08:00
parent 902c6ecaea
commit 2658ee3b72
255 changed files with 12487 additions and 150 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
import assert from "node:assert/strict";
import { createLinuxCncInterpSdk } from "../../../runtime/sdk/src/index.js";
function verifyExpectedOutput(fixtureName, output, expectedText) {
const expectedLines = expectedText.split("\n").filter(Boolean);
for (const expectedLine of expectedLines) {
if (expectedLine.startsWith("absent=")) {
const forbidden = expectedLine.slice("absent=".length);
assert.equal(
output.includes(forbidden),
false,
`${fixtureName}: unexpected ${forbidden}`,
);
continue;
}
assert.equal(
output.includes(expectedLine),
true,
`${fixtureName}: ${expectedLine}`,
);
}
}
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = resolve(__dirname, "../../..");
const wasmPath = resolve(rootDir, "build/wasm/core/linuxcnc_interp.wasm");
const ncFilesDir = resolve(rootDir, "vendor/linuxcnc/nc_files");
const interp = await createLinuxCncInterpSdk({
wasmBinary: readFileSync(wasmPath),
print() {},
printErr(message) {
console.error(message);
},
});
function runVendorNcFile(filename) {
const wasmPath = `/work/nc-files/${filename}`;
interp.writeTextFile(wasmPath, readFileSync(resolve(ncFilesDir, filename), "utf8"));
return interp.runFile(wasmPath);
}
verifyExpectedOutput(
"nc_files_arcspiral_wasm",
runVendorNcFile("arcspiral.ngc"),
[
"file_open=0",
"file_read_count=1008",
"file_execute_count=1008",
"file_saw_error=0",
"canon_event=STRAIGHT_TRAVERSE line=3 x=0 y=0 z=1",
"canon_event=STRAIGHT_FEED line=6 x=1.72464 y=-1.01273 z=-0.1",
"canon_event=PROGRAM_END",
"absent=file_error_text=",
].join("\n"),
);
verifyExpectedOutput(
"nc_files_hole_circle_wasm",
runVendorNcFile("hole-circle.ngc"),
[
"file_open=0",
"file_read_count=12",
"file_execute_count=12",
"file_saw_error=0",
"canon_event=STRAIGHT_TRAVERSE line=7 x=1.5 y=0 z=0",
"canon_event=STRAIGHT_FEED line=10 x=0.75 y=1.29904 z=-0.4",
"canon_event=PROGRAM_END",
"absent=file_error_text=",
].join("\n"),
);
verifyExpectedOutput(
"nc_files_factorial_wasm",
runVendorNcFile("factorial.ngc"),
[
"file_open=0",
"file_read_count=11",
"file_execute_count=11",
"file_saw_error=0",
"canon_event=PROGRAM_END",
"absent=file_error_text=",
].join("\n"),
);
verifyExpectedOutput(
"nc_files_m6demo_wasm",
runVendorNcFile("m6demo.ngc"),
[
"file_open=0",
"file_read_count=88",
"file_execute_count=88",
"file_saw_error=0",
"canon_event=SET_G5X_OFFSET index=1",
"canon_event=STOP_SPINDLE_TURNING spindle=0",
"canon_event=PROGRAM_END",
"absent=file_error_text=",
].join("\n"),
);
console.log("nc_files_wasm_node_smoke=ok");

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
if [[ "${SKIP_INTERP_BUILD:-0}" != "1" ]]; then
"$ROOT_DIR/tools/build_wasm_core.sh"
fi
node "$ROOT_DIR/tests/wasm/node/verify_nc_files_wasm.mjs"

View File

@@ -0,0 +1,161 @@
import { readFileSync, statSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
import assert from "node:assert/strict";
import { createLinuxCncInterpSdk } from "../../../runtime/sdk/src/index.js";
function verifyExpectedOutput(fixtureName, output, expectedText) {
const expectedLines = expectedText.split("\n").filter(Boolean);
for (const expectedLine of expectedLines) {
if (expectedLine.startsWith("absent=")) {
const forbidden = expectedLine.slice("absent=".length);
assert.equal(
output.includes(forbidden),
false,
`${fixtureName}: unexpected ${forbidden}`,
);
continue;
}
assert.equal(
output.includes(expectedLine),
true,
`${fixtureName}: ${expectedLine}`,
);
}
}
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = resolve(__dirname, "../../..");
const wasmPath = resolve(rootDir, "build/wasm/core/linuxcnc_interp.wasm");
const vendorRoot = resolve(rootDir, "vendor/linuxcnc");
const interp = await createLinuxCncInterpSdk({
wasmBinary: readFileSync(wasmPath),
print() {},
printErr(message) {
console.error(message);
},
});
function vendorFile(sourceRel, wasmPath) {
const sourcePath = resolve(vendorRoot, sourceRel);
return {
path: wasmPath,
text: readFileSync(sourcePath, "utf8"),
executable: (statSync(sourcePath).mode & 0o111) !== 0,
};
}
function simMachine(machineRel, files) {
const wasmDir = `/work/sim/${machineRel}`;
return {
wasmDir,
files: files.map((file) =>
vendorFile(`configs/sim/${machineRel}/${file}`, `${wasmDir}/${file}`),
),
};
}
const foam = simMachine("axis/foam", [
"axis_foam.ini",
"foam.ngc",
]);
verifyExpectedOutput(
"sim_axis_foam_uv_wasm",
interp.runSimConfigProgram({
files: foam.files,
programPath: `${foam.wasmDir}/foam.ngc`,
iniPath: `${foam.wasmDir}/axis_foam.ini`,
}),
[
"file_open=0",
"file_saw_error=0",
"canon_event=PROGRAM_END",
"absent=Bad character 'u' used",
"absent=Bad character 'v' used",
].join("\n"),
);
const bridgeMill = simMachine("axis/vismach/5axis/bridgemill", [
"5axis.ini",
"5axis.tbl",
"5axisgui.ngc",
"remap_subs/428remap.ngc",
"remap_subs/429remap.ngc",
"remap_subs/430remap.ngc",
]);
verifyExpectedOutput(
"sim_axis_bridgemill_w_wasm",
interp.runSimConfigProgram({
files: bridgeMill.files,
programPath: `${bridgeMill.wasmDir}/5axisgui.ngc`,
iniPath: `${bridgeMill.wasmDir}/5axis.ini`,
executionMode: "fiveAxisRemap",
}),
[
"fiveaxis_ini_open=1",
"fiveaxis_tool_table_load=0",
"fiveaxis_parse_remap_1=0",
"fiveaxis_parse_remap_2=0",
"fiveaxis_parse_remap_3=0",
"fiveaxis_parsed_remap_count=3",
"fiveaxis_remaps_ready=1",
"fiveaxis_file_open=0",
"fiveaxis_file_read_count=2197",
"fiveaxis_file_execute_count=2197",
"fiveaxis_file_finish_count=137",
"fiveaxis_file_reached_exit=1",
"fiveaxis_hal_switchkins: rc=0 found=1 value=0",
"fiveaxis_linuxcnc_remap_file_execute=1",
"absent=Bad character 'w' used",
].join("\n"),
);
const geometry = simMachine("axis/geometry", [
"M110",
"xyzc.ini",
"xyzc.ngc",
]);
verifyExpectedOutput(
"sim_axis_geometry_xyzc_user_m110_wasm",
interp.runSimConfigProgram({
files: geometry.files,
programPath: `${geometry.wasmDir}/xyzc.ngc`,
iniPath: `${geometry.wasmDir}/xyzc.ini`,
}),
[
"file_open=0",
"file_saw_error=0",
"canon_event=USER_M_COMMAND code=M110",
"canon_event=PROGRAM_END",
"absent=Unknown m code used: M110",
"absent=Bad character 'c' used",
].join("\n"),
);
const externalOffsets = simMachine("axis/external_offsets", [
"M111",
"dyn_demo.ngc",
"dynamic_offsets.ini",
]);
verifyExpectedOutput(
"sim_axis_external_offsets_user_m111_wasm",
interp.runSimConfigProgram({
files: externalOffsets.files,
programPath: `${externalOffsets.wasmDir}/dyn_demo.ngc`,
iniPath: `${externalOffsets.wasmDir}/dynamic_offsets.ini`,
}),
[
"file_open=0",
"file_saw_error=0",
"canon_event=USER_M_COMMAND code=M111",
"canon_event=PROGRAM_END",
"absent=Unknown m code used: M111",
].join("\n"),
);
console.log("sim_configs_wasm_node_smoke=ok");

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
if [[ "${SKIP_INTERP_BUILD:-0}" != "1" ]]; then
"$ROOT_DIR/tools/build_wasm_core.sh"
fi
node "$ROOT_DIR/tests/wasm/node/verify_sim_configs_wasm.mjs"