Files
Web_FreeCAD_Bitbybit/tests/camPipeline.test.ts

58 lines
3.0 KiB
TypeScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { createCamJob } from '../src/facade/cam'
import { CAM_PIPELINE_ORDER, camoticsSourceEvidence, prepareCamPipeline, submitCamPipelineToLinuxcnc } from '../src/facade/camPipeline'
import { OPEN_CAM_LIB_ARTIFACT_SHA256, OPEN_CAM_LIB_SOURCE_REVISION, type OpenCamLibDropCutterInput } from '../src/facade/camNativeSimulation'
const job = () => {
const cam = createCamJob('pipeline', 'CAD/OCL/CAMotics/LinuxCNC')
cam.addTool({ id: 'T1', name: 'end mill', diameter: 2, length: 20 })
cam.addOperation({ id: 'profile', kind: 'profile', toolId: 'T1', depth: 1, feed: 100 })
cam.generatePath('profile')
return cam
}
const openCamLibRunner = async (input: OpenCamLibDropCutterInput) => ({
backend: 'upstream-opencamlib-wasm' as const,
sourceRevision: OPEN_CAM_LIB_SOURCE_REVISION,
artifactSha256: OPEN_CAM_LIB_ARTIFACT_SHA256,
algorithm: 'path-drop-cutter' as const,
triangleCount: input.triangles.length,
points: input.path.map((point) => [...point] as [number, number, number]),
})
test('pipeline evidence pins CAMotics source and canonical LinuxCNC policy', () => {
assert.deepEqual(CAM_PIPELINE_ORDER, ['CAD', 'OCL', 'CAMotics', 'GCODE', 'LinuxCNC WASM'])
const evidence = camoticsSourceEvidence()
assert.equal(evidence.backend, 'camotics-source')
assert.equal(evidence.generator, 'camotics-source-stage')
assert.equal(evidence.workspaceNativeCli, 'verified-sidecar')
assert.equal(evidence.browserNativeExecutable, false)
assert.equal(evidence.parserAuthority, 'linuxcnc-wasm')
assert.equal(evidence.camoticsParsesCanonicalGcode, false)
assert.equal(evidence.sourceRevision.length, 40)
})
test('LinuxCNC WASM cannot be called before the OCL and G-code stages are prepared', async () => {
const prepared = await prepareCamPipeline(job(), 'profile', { openCamLib: { runner: openCamLibRunner } })
assert.equal(prepared.stage, 'GCODE')
assert.equal(prepared.openCamLib.backend, 'upstream-opencamlib-wasm')
assert.equal(prepared.openCamLib.inputPoints, 5)
assert.equal(prepared.openCamLib.outputPoints, 5)
const submitted = await submitCamPipelineToLinuxcnc(prepared, {
submit: async (program) => ({ backend: 'linuxcnc-wasm', status: 'dry-run', programSha256: String(program.length) }),
})
assert.equal(submitted.stage, 'LinuxCNC WASM')
assert.equal(submitted.linuxcnc?.status, 'dry-run')
assert.match(submitted.gcode, /G90/)
assert.match(submitted.camoticsMotionGcode, /G1 X/)
})
test('pipeline rejects non-LinuxCNC posts before any machine submission', async () => {
await assert.rejects(() => prepareCamPipeline(job(), 'profile', { postprocessor: 'grbl', openCamLib: { runner: openCamLibRunner } }), /requires the linuxcnc postprocessor/)
})
test('pipeline rejects an unpinned OCL result instead of bypassing the native stage', async () => {
await assert.rejects(() => prepareCamPipeline(job(), 'profile', { openCamLib: { runner: async (input) => ({ ...await openCamLibRunner(input), sourceRevision: '0'.repeat(40) }) } }), /pinned upstream WASM identity/)
})