115 lines
3.4 KiB
TypeScript
115 lines
3.4 KiB
TypeScript
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";
|
|
import {
|
|
applyPatch,
|
|
pathOperationToGrl,
|
|
sampleOlpProject,
|
|
validateOlpProject,
|
|
type OlpProjectModel
|
|
} from "../../src/olp/index.js";
|
|
|
|
describe("OLP project model", () => {
|
|
it("creates a serializable station/resource/path/operation sample", () => {
|
|
const project = sampleOlpProject();
|
|
const restored = JSON.parse(JSON.stringify(project)) as OlpProjectModel;
|
|
const report = validateOlpProject(restored);
|
|
|
|
expect(restored.schemaVersion).toBe("olp/0.1");
|
|
expect(report).toEqual({ ok: true, issues: [] });
|
|
expect(restored.resources.robots[0]).toMatchObject({
|
|
id: "robot_1",
|
|
kind: "robot",
|
|
brand: "abb"
|
|
});
|
|
expect(restored.externalAxes[0]).toMatchObject({
|
|
id: "track_1",
|
|
axisKind: "linear"
|
|
});
|
|
expect(restored.motionGroups[0]).toMatchObject({
|
|
robotIds: ["robot_1"],
|
|
externalAxisIds: ["track_1"],
|
|
coordination: "synchronized"
|
|
});
|
|
});
|
|
|
|
it("applies brand import style object patches and validates references", () => {
|
|
const patched = applyPatch(sampleOlpProject(), [
|
|
{
|
|
op: "add",
|
|
path: "/targets/-",
|
|
value: {
|
|
id: "inspect",
|
|
name: "inspect",
|
|
kind: "pose",
|
|
robotId: "robot_1",
|
|
pose: [650, 25, 0, 0, 0, 0],
|
|
toolId: "tool_gripper",
|
|
frameId: "frame_fixture"
|
|
}
|
|
},
|
|
{
|
|
op: "add",
|
|
path: "/paths/0/points/-",
|
|
value: {
|
|
id: "p03",
|
|
name: "p03",
|
|
motion: "movel",
|
|
targetId: "inspect",
|
|
speedId: "v_linear",
|
|
zoneId: "z10"
|
|
}
|
|
}
|
|
]);
|
|
|
|
expect(validateOlpProject(patched).ok).toBe(true);
|
|
expect(patched.paths[0]?.points.map((point) => point.name)).toEqual(["p00", "p01", "p02", "p03"]);
|
|
});
|
|
|
|
it("generates stable parseable GRL from Path and Operation", () => {
|
|
const result = pathOperationToGrl(sampleOlpProject(), "pick_op", {
|
|
moduleName: "DemoCell",
|
|
style: "expanded"
|
|
});
|
|
const ast = parseGrl(result.text);
|
|
const ir = compileSemanticProgram(ast, {
|
|
startJoints: [0, 0, 0, 0, 0, 0],
|
|
sampleTime: 0.004
|
|
});
|
|
const post = postProcessAllBrands(ir);
|
|
|
|
expect(result.stableIds).toEqual({
|
|
targets: ["home", "pick", "place"],
|
|
points: ["p00", "p01", "p02"],
|
|
path: "pick_path",
|
|
operation: "pick_op"
|
|
});
|
|
expect(result.text).toContain("path pick_path");
|
|
expect(result.text).toContain("operation pick_op");
|
|
expect(result.program).toMatchObject({
|
|
id: "pick_op_grl",
|
|
language: "grl",
|
|
entryOperationIds: ["pick_op"]
|
|
});
|
|
expect(ir.operations[0]).toMatchObject({
|
|
operationId: "pick_op",
|
|
kind: "handling",
|
|
pathId: "pick_path"
|
|
});
|
|
expect(post.outputs.abb.text).toContain("MODULE DemoCell");
|
|
expect(post.outputs.fanuc.text).toContain("/PROG MAIN");
|
|
expect(post.outputs.kuka.text).toContain("DEF Main()");
|
|
});
|
|
|
|
it("reports broken schema references with stable issue codes", () => {
|
|
const project = sampleOlpProject();
|
|
project.operations[0]!.pathId = "missing_path";
|
|
|
|
expect(validateOlpProject(project)).toMatchObject({
|
|
ok: false,
|
|
issues: [expect.objectContaining({ code: "OLP_REF_PATH_MISSING" })]
|
|
});
|
|
});
|
|
});
|