collab/mermaid/packages/mermaid-layout-elk/src/__tests__/geometry.spec.tsblame
View source
6dd74de1import { describe, it, expect } from 'vitest';
6dd74de2import {
6dd74de3 intersection,
6dd74de4 ensureTrulyOutside,
6dd74de5 makeInsidePoint,
6dd74de6 tryNodeIntersect,
6dd74de7 replaceEndpoint,
6dd74de8 type RectLike,
6dd74de9 type P,
6dd74de10} from '../geometry.js';
6dd74de11
6dd74de12const approx = (a: number, b: number, eps = 1e-6) => Math.abs(a - b) < eps;
6dd74de13
6dd74de14describe('geometry helpers', () => {
6dd74de15 it('intersection: vertical approach hits bottom border', () => {
6dd74de16 const rect: RectLike = { x: 0, y: 0, width: 100, height: 50 };
6dd74de17 const h = rect.height / 2; // 25
6dd74de18 const outside: P = { x: 0, y: 100 };
6dd74de19 const inside: P = { x: 0, y: 0 };
6dd74de20 const res = intersection(rect, outside, inside);
6dd74de21 expect(approx(res.x, 0)).toBe(true);
6dd74de22 expect(approx(res.y, h)).toBe(true);
6dd74de23 });
6dd74de24
6dd74de25 it('ensureTrulyOutside nudges near-boundary point outward', () => {
6dd74de26 const rect: RectLike = { x: 0, y: 0, width: 100, height: 50 };
6dd74de27 // near bottom boundary (y ~ h)
6dd74de28 const near: P = { x: 0, y: rect.height / 2 - 0.2 };
6dd74de29 const out = ensureTrulyOutside(rect, near, 10);
6dd74de30 expect(out.y).toBeGreaterThan(rect.height / 2);
6dd74de31 });
6dd74de32
6dd74de33 it('makeInsidePoint keeps x for vertical and y from center', () => {
6dd74de34 const rect: RectLike = { x: 10, y: 5, width: 100, height: 50 };
6dd74de35 const outside: P = { x: 10, y: 40 };
6dd74de36 const center: P = { x: 99, y: -123 }; // center y should be used
6dd74de37 const inside = makeInsidePoint(rect, outside, center);
6dd74de38 expect(inside.x).toBe(outside.x);
6dd74de39 expect(inside.y).toBe(center.y);
6dd74de40 });
6dd74de41
6dd74de42 it('tryNodeIntersect returns null for wrong-side intersections', () => {
6dd74de43 const rect: RectLike = { x: 0, y: 0, width: 100, height: 50 };
6dd74de44 const outside: P = { x: -50, y: 0 };
6dd74de45 const node = { intersect: () => ({ x: 10, y: 0 }) } as any; // right side of center
6dd74de46 const res = tryNodeIntersect(node, rect, outside);
6dd74de47 expect(res).toBeNull();
6dd74de48 });
6dd74de49
6dd74de50 it('replaceEndpoint dedup removes end/start appropriately', () => {
6dd74de51 const pts: P[] = [
6dd74de52 { x: 0, y: 0 },
6dd74de53 { x: 1, y: 1 },
6dd74de54 ];
6dd74de55 // remove duplicate end
6dd74de56 replaceEndpoint(pts, 'end', { x: 1, y: 1 });
6dd74de57 expect(pts.length).toBe(1);
6dd74de58
6dd74de59 const pts2: P[] = [
6dd74de60 { x: 0, y: 0 },
6dd74de61 { x: 1, y: 1 },
6dd74de62 ];
6dd74de63 // remove duplicate start
6dd74de64 replaceEndpoint(pts2, 'start', { x: 0, y: 0 });
6dd74de65 expect(pts2.length).toBe(1);
6dd74de66 });
6dd74de67});