Repository Public
1// UQO Éval — Métré : tests du lecteur DXF (LINE, LWPOLYLINE, POLYLINE/VERTEX, CIRCLE, $INSUNITS, projection, SVG).2import { describe, expect, it } from "vitest";3import { dxfToSvg, parseDxf, projectDxf } from "./sources/dxf";45const pairs = (...xs: (string | number)[]) => xs.map(String).join("\n") + "\n";6const DXF = pairs(0, "SECTION", 2, "HEADER", 9, "$INSUNITS", 70, 6, 0, "ENDSEC",7 0, "SECTION", 2, "ENTITIES",8 0, "LINE", 8, "MURS", 10, 0, 20, 0, 11, 10, 21, 0,9 0, "LWPOLYLINE", 8, "PIECES", 90, 4, 70, 1, 10, 0, 20, 0, 10, 10, 20, 0, 10, 10, 20, 8, 10, 0, 20, 8,10 0, "POLYLINE", 8, "DALLE", 70, 1, 0, "VERTEX", 10, 20, 20, 0, 0, "VERTEX", 10, 25, 20, 0, 0, "VERTEX", 10, 25, 20, 5, 0, "SEQEND",11 0, "CIRCLE", 8, "0", 10, 2, 20, 2, 40, 1,12 0, "ARC", 8, "0", 10, 0, 20, 0, 40, 1, 50, 0, 51, 90,13 0, "TEXT", 8, "0", 1, "note",14 0, "ENDSEC", 0, "EOF");1516describe("DXF", () => {17 it("lit les entités utiles, les calques, les unités et compte les entités ignorées", () => {18 const d = parseDxf(DXF);19 expect(d.unit).toBe("m"); expect(d.insunits).toBe(6);20 expect(d.entities.map((e) => e.type)).toEqual(["line", "polyline", "polyline", "circle"]);21 expect(d.entities[1].closed).toBe(true); expect(d.entities[1].points).toHaveLength(4);22 expect(d.entities[2].points).toEqual([{ x: 20, y: 0 }, { x: 25, y: 0 }, { x: 25, y: 5 }]); expect(d.entities[2].closed).toBe(true);23 expect(d.entities[3].points).toHaveLength(32);24 expect(d.layers.sort()).toEqual(["0", "DALLE", "MURS", "PIECES"]);25 expect(d.skipped).toEqual({ ARC: 1, TEXT: 1 });26 expect(d.bounds).toEqual({ minX: 0, minY: 0, maxX: 25, maxY: 8 });27 });28 it("projette sur une page (Y inversé, marge) avec une calibration exacte et produit un SVG", () => {29 const d = parseDxf(DXF);30 const p = projectDxf(d, 1000, 50);31 expect(p.widthPx).toBe(1000); // la largeur (25) domine : (1000 − 100) / 25 = 36 px/unité32 expect(p.pxPerUnit).toBeCloseTo(36, 6);33 expect(p.heightPx).toBe(Math.ceil(8 * 36 + 100));34 // le coin (0,0) DXF est en bas à gauche → y page = marge + (maxY − 0) × 3635 expect(p.entities[0].points[0]).toEqual({ x: 50, y: 50 + 8 * 36 });36 expect(p.calibration).toEqual({ p1: { x: 50, y: 50 + 8 * 36 }, p2: { x: 50 + 10 * 36, y: 50 + 8 * 36 }, realLength: 10 });37 const svg = dxfToSvg(p);38 expect(svg.startsWith("<svg")).toBe(true); expect((svg.match(/<polygon/g) ?? []).length).toBe(3); expect((svg.match(/<polyline/g) ?? []).length).toBe(1);39 });40 it("sans $INSUNITS : unité nulle (calibration manuelle requise) ; fichier vide : aucune entité", () => {41 const d = parseDxf(pairs(0, "SECTION", 2, "ENTITIES", 0, "LINE", 10, 0, 20, 0, 11, 1, 21, 1, 0, "ENDSEC", 0, "EOF"));42 expect(d.unit).toBeNull(); expect(d.entities).toHaveLength(1);43 expect(parseDxf("garbage").entities).toHaveLength(0);44 expect(projectDxf(parseDxf("garbage")).calibration).toBeNull();45 });46});47