2.2 KB68 lines
Blame
1import { describe, it, expect } from 'vitest';
2import {
3 intersection,
4 ensureTrulyOutside,
5 makeInsidePoint,
6 tryNodeIntersect,
7 replaceEndpoint,
8 type RectLike,
9 type P,
10} from '../geometry.js';
11
12const approx = (a: number, b: number, eps = 1e-6) => Math.abs(a - b) < eps;
13
14describe('geometry helpers', () => {
15 it('intersection: vertical approach hits bottom border', () => {
16 const rect: RectLike = { x: 0, y: 0, width: 100, height: 50 };
17 const h = rect.height / 2; // 25
18 const outside: P = { x: 0, y: 100 };
19 const inside: P = { x: 0, y: 0 };
20 const res = intersection(rect, outside, inside);
21 expect(approx(res.x, 0)).toBe(true);
22 expect(approx(res.y, h)).toBe(true);
23 });
24
25 it('ensureTrulyOutside nudges near-boundary point outward', () => {
26 const rect: RectLike = { x: 0, y: 0, width: 100, height: 50 };
27 // near bottom boundary (y ~ h)
28 const near: P = { x: 0, y: rect.height / 2 - 0.2 };
29 const out = ensureTrulyOutside(rect, near, 10);
30 expect(out.y).toBeGreaterThan(rect.height / 2);
31 });
32
33 it('makeInsidePoint keeps x for vertical and y from center', () => {
34 const rect: RectLike = { x: 10, y: 5, width: 100, height: 50 };
35 const outside: P = { x: 10, y: 40 };
36 const center: P = { x: 99, y: -123 }; // center y should be used
37 const inside = makeInsidePoint(rect, outside, center);
38 expect(inside.x).toBe(outside.x);
39 expect(inside.y).toBe(center.y);
40 });
41
42 it('tryNodeIntersect returns null for wrong-side intersections', () => {
43 const rect: RectLike = { x: 0, y: 0, width: 100, height: 50 };
44 const outside: P = { x: -50, y: 0 };
45 const node = { intersect: () => ({ x: 10, y: 0 }) } as any; // right side of center
46 const res = tryNodeIntersect(node, rect, outside);
47 expect(res).toBeNull();
48 });
49
50 it('replaceEndpoint dedup removes end/start appropriately', () => {
51 const pts: P[] = [
52 { x: 0, y: 0 },
53 { x: 1, y: 1 },
54 ];
55 // remove duplicate end
56 replaceEndpoint(pts, 'end', { x: 1, y: 1 });
57 expect(pts.length).toBe(1);
58
59 const pts2: P[] = [
60 { x: 0, y: 0 },
61 { x: 1, y: 1 },
62 ];
63 // remove duplicate start
64 replaceEndpoint(pts2, 'start', { x: 0, y: 0 });
65 expect(pts2.length).toBe(1);
66 });
67});
68