import test from "node:test"; import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import { packGcode } from "../src/lib/packed-gcode.js"; import { samplePacked, targetsAt } from "../src/lib/packed-playback.js"; test("相对挤出与抬升不增加切片层", () => { const { metadata, buffer } = packGcode( "G90\nM83\nM104 S220\n;LAYER_CHANGE\n;Z:0.2\nG1 Z0.2 F600\nG1 X10 E1\nG1 Z0.6\nG1 Z0.2\n;LAYER_CHANGE\n;Z:0.4\nG1 Z0.4\nG1 X20 E1\nM104 S0", "测试", ); const data = { ...metadata, buffer }; assert.equal(data.layers.length, 2); assert.equal(data.deposited, 2); assert.equal(data.extrusionCount, 2); assert.equal(targetsAt(data, 0).nozzle, 220); assert.equal(targetsAt(data, data.duration + 1).nozzle, 0); assert.equal(samplePacked(data, data.duration).position.x, 20); assert.equal(samplePacked(data, data.duration).layer, 2); }); test("真实文件层数、耗材、模型尺寸与完整路径", async () => { const metadata = JSON.parse( await readFile("public/data/print-job.json", "utf8"), ); const bytes = await readFile("public/data/print-job.bin"); const buffer = new Float32Array( bytes.buffer, bytes.byteOffset, bytes.byteLength / 4, ); const data = { ...metadata, buffer }; assert.equal(data.layers.length, 714); assert.equal(data.layers.at(-1).z, 142.8); assert.equal(data.estimatedSeconds, 19205); assert.equal(data.material, "PLA"); assert.equal(data.weight, 134.9); assert.ok(Math.abs(data.deposited - data.filamentMm) < 0.01); assert.equal(buffer.length, data.count * data.stride); assert.equal(data.count, 936561); assert.equal(samplePacked(data, data.duration).index, data.count - 1); assert.equal(samplePacked(data, data.duration).layer, 714); for (let i = 1; i < data.count; i++) assert.ok(buffer[i * data.stride + 6] >= buffer[(i - 1) * data.stride + 6]); for (let i = 0; i < data.layers.length; i++) { const end = (data.layers[i + 1]?.segment ?? data.count) - 1; assert.equal( samplePacked(data, buffer[end * data.stride + 6]).layer, i + 1, ); } }); test("拒绝静默丢失未支持的圆弧", () => { assert.throws(() => packGcode("G2 X10 I5", "圆弧"), /圆弧/); }); test("抽样原始 G1 指令与二进制轨迹端点一致", async () => { const lines = (await readFile("public/data/print-job.gcode", "utf8")).split(/\r?\n/); const bytes = await readFile("public/data/print-job.bin"); const buffer = new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4); let checked = 0; for (let index = 0; index < buffer.length / 12; index += 997) { const offset = index * 12; const source = lines[buffer[offset + 11] - 1]; assert.match(source, /^G[01]\s/); for (const [axis, coordinate] of [["X", 3], ["Y", 4], ["Z", 5]]) { const match = source.match(new RegExp(`(?:^|\\s)${axis}(-?[\\d.]+)`)); if (match) { assert.ok(Math.abs(buffer[offset + coordinate] - Number(match[1])) < .0001); checked++; } } } assert.ok(checked > 1500); });