feat: establish reproducible FreeCAD web compatibility baseline
This commit is contained in:
57
tests/camPipeline.test.ts
Normal file
57
tests/camPipeline.test.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
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/)
|
||||
})
|
||||
Reference in New Issue
Block a user