150 lines
4.7 KiB
TypeScript
150 lines
4.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { postProcessBrand } from "../../src/grl/post/index.js";
|
|
import { parseGrl } from "../../src/grl/parser/index.js";
|
|
import { compileSemanticProgram } from "../../src/grl/semantic/index.js";
|
|
import { pathOperationToGrl, sampleOlpProject } from "../../src/olp/index.js";
|
|
import {
|
|
calibrationSummary,
|
|
createValidationReport,
|
|
exportCustomerDeliveryPackage,
|
|
exportValidationReportHtml,
|
|
serializeDeliveryPackage,
|
|
validateReportSchema
|
|
} from "../../src/reports/index.js";
|
|
|
|
const NOW = "2026-06-27T00:00:00.000Z";
|
|
|
|
describe("validation reports and customer delivery", () => {
|
|
it("creates stable validation report sections for reachability, cycle, IO/Wait, post, import, and calibration", () => {
|
|
const project = sampleOlpProject();
|
|
const report = createValidationReport({
|
|
id: "demo_validation",
|
|
project,
|
|
generatedAt: NOW,
|
|
pathValidation: {
|
|
ok: true,
|
|
reachable: true,
|
|
cycleTime: 4.2,
|
|
segmentReports: [],
|
|
diagnostics: []
|
|
},
|
|
ioWaitDiagnostics: [],
|
|
postDiagnostics: [],
|
|
importDiagnostics: [
|
|
{
|
|
severity: "info",
|
|
code: "IMPORT_OK",
|
|
message: "ABB import mapped to OLP",
|
|
sourceMap: { file: "imports/PickPlace.mod", line: 8 }
|
|
}
|
|
]
|
|
});
|
|
|
|
expect(validateReportSchema(report)).toEqual({ ok: true, issues: [] });
|
|
expect(report.status).toBe("pass");
|
|
expect(report.sections.map((section) => section.name)).toEqual([
|
|
"reachability",
|
|
"cycle_time",
|
|
"io_wait",
|
|
"post",
|
|
"import",
|
|
"collision",
|
|
"calibration"
|
|
]);
|
|
expect(report.sections.find((section) => section.name === "cycle_time")?.summary).toEqual({
|
|
cycleTime: 4.2,
|
|
trajectories: 0
|
|
});
|
|
expect(report.sourceMap).toEqual([
|
|
{
|
|
kind: "IMPORT_OK",
|
|
id: "IMPORT_OK-0",
|
|
file: "imports/PickPlace.mod",
|
|
line: 8
|
|
}
|
|
]);
|
|
});
|
|
|
|
it("exports openable HTML with summary, details, and source map payload", () => {
|
|
const report = createValidationReport({
|
|
id: "demo_validation",
|
|
project: sampleOlpProject(),
|
|
generatedAt: NOW,
|
|
diagnostics: [
|
|
{
|
|
severity: "info",
|
|
code: "REACH_OK",
|
|
message: "pick target reachable",
|
|
sourceMap: { file: "source/DemoCell.grl", line: 20 }
|
|
}
|
|
]
|
|
});
|
|
const html = exportValidationReportHtml(report);
|
|
|
|
expect(html).toContain("<!doctype html>");
|
|
expect(html).toContain("Status: warn");
|
|
expect(html).toContain("reachability");
|
|
expect(html).toContain("source/DemoCell.grl");
|
|
expect(html).toContain("validation-report-json");
|
|
});
|
|
|
|
it("exports customer delivery package with source, brand programs, IO map, reports, calibration, and trace", () => {
|
|
const project = sampleOlpProject();
|
|
const grl = pathOperationToGrl(project, "pick_op", { moduleName: "DemoCell" });
|
|
project.programs.push(grl.program);
|
|
const ir = compileSemanticProgram(parseGrl(grl.text), {
|
|
startJoints: [0, 0, 0, 0, 0, 0],
|
|
sampleTime: 0.004
|
|
});
|
|
const abb = postProcessBrand(ir, "abb");
|
|
const report = createValidationReport({
|
|
id: "demo_validation",
|
|
project,
|
|
generatedAt: NOW,
|
|
postDiagnostics: abb.report.map((issue) => ({
|
|
severity: issue.severity,
|
|
code: issue.code,
|
|
message: issue.message
|
|
})),
|
|
pathValidation: {
|
|
ok: true,
|
|
reachable: true,
|
|
cycleTime: 4.2,
|
|
segmentReports: [],
|
|
diagnostics: []
|
|
}
|
|
});
|
|
|
|
const pkg = exportCustomerDeliveryPackage({
|
|
project,
|
|
report,
|
|
trace: { samples: ["t=0 movej home"] },
|
|
brandPrograms: { [abb.filename]: abb.text },
|
|
ioMap: { "io.do[1]": "vacuum" }
|
|
});
|
|
const serialized = serializeDeliveryPackage(pkg);
|
|
|
|
expect(pkg.manifest).toEqual({
|
|
sourcePrograms: ["source/pick_op_grl.grl"],
|
|
brandPrograms: ["post/DemoCell.mod"],
|
|
reports: ["reports/demo_validation.html", "reports/demo_validation.json"],
|
|
calibrationFiles: ["calibration/calibrations.json"],
|
|
traceFiles: ["trace/trace.json"],
|
|
ioMaps: ["io/io_map.json"]
|
|
});
|
|
expect(pkg.files.map((file) => file.path)).toEqual([
|
|
"calibration/calibrations.json",
|
|
"io/io_map.json",
|
|
"post/DemoCell.mod",
|
|
"project/project.json",
|
|
"reports/demo_validation.html",
|
|
"reports/demo_validation.json",
|
|
"source/pick_op_grl.grl",
|
|
"trace/trace.json"
|
|
]);
|
|
expect(serialized).toContain("\"format\": \"customer-delivery/0.1\"");
|
|
expect(serialized).toContain("fnv1a32:");
|
|
expect(calibrationSummary(project.calibrations)).toEqual({ tcp: 1 });
|
|
});
|
|
});
|