import { describe, expect, it } from "vitest"; import { postProcessAllBrands } from "../../src/grl/post/index.js"; import { parseGrl } from "../../src/grl/parser/index.js"; import { compileSemanticProgram } from "../../src/grl/semantic/index.js"; const PROGRAM = `language grl 0.1 module PostDemo post_hint abb const speed vj = joint(50 %) const speed vl = linear(200 mm/s) const zone z10 = z(10 mm) target home = joint_target { joints: [0 deg] } target pick = pose_target { pose: pose(500 mm, 0 mm, 0 mm, 0 deg, 0 deg, 0 deg) } target mid = pose_target { pose: pose(550 mm, 50 mm, 0 mm, 0 deg, 0 deg, 0 deg) } target place = pose_target { pose: pose(600 mm, 0 mm, 0 mm, 0 deg, 0 deg, 0 deg) } proc main() set_speed vl set_zone z10 movej home speed vj zone fine movel pick speed vl zone z10 movec via mid target place speed vl zone fine io.do[1] = true wait io.di[1] == true timeout 1 s pulse io.do[2] duration 100 ms alarm DONE "done" end end `; function postAll() { const ir = compileSemanticProgram(parseGrl(PROGRAM), { startJoints: [0], sampleTime: 0.004 }); return postProcessAllBrands(ir); } describe("GRL multi-brand postprocessor", () => { it("emits stable ABB, FANUC, and KUKA golden text", () => { const result = postAll(); expect(result.outputs.abb.text).toBe(`MODULE PostDemo PROC main() MoveJ home,v50,fine,tool0; MoveL pick,v200,z10,tool0; MoveC mid,place,v200,fine,tool0; SetDO io.do[1],TRUE; WaitUntil io . di [ 1 ] == true; PulseDO io.do[2],0.100; ! unsupported ALARM ENDPROC ENDMODULE`); expect(result.outputs.fanuc.text).toBe(`/PROG MAIN /MN 1: J home 50% FINE ; 2: L pick 200mm/sec CNT10 ; 3: C mid place 200mm/sec FINE ; 4: DO[1]=TRUE ; 5: WAIT (io . di [ 1 ] == true) ; 6: PULSE DO[2] 100ms ; 7: ! unsupported ALARM ; /END`); expect(result.outputs.kuka.text).toBe(`DEF Main() PTP home Vel=50% LIN pick Vel=0.200m/s C_DIS CIRC mid, place Vel=0.200m/s $OUT[1] = TRUE WAIT FOR io . di [ 1 ] == true PULSE $OUT[2] 0.100 ! unsupported ALARM END`); }); it("reports unsupported semantics and ignored brand hints", () => { const result = postAll(); expect(result.outputs.abb.filename).toBe("PostDemo.mod"); expect(result.outputs.fanuc.filename).toBe("PostDemo.ls"); expect(result.outputs.kuka.filename).toBe("PostDemo.src"); expect(result.report).toEqual([ expect.objectContaining({ brand: "abb", code: "GRL_POST_UNSUPPORTED", message: expect.stringContaining("ALARM") }), expect.objectContaining({ brand: "fanuc", code: "GRL_POST_HINT_IGNORED" }), expect.objectContaining({ brand: "fanuc", code: "GRL_POST_UNSUPPORTED", message: expect.stringContaining("ALARM") }), expect.objectContaining({ brand: "kuka", code: "GRL_POST_HINT_IGNORED" }), expect.objectContaining({ brand: "kuka", code: "GRL_POST_UNSUPPORTED", message: expect.stringContaining("ALARM") }) ]); }); });