import * as THREE from 'three'; import { L33tGeometryUtil } from '../server/L33tGeometryUtil'; describe('L33tGeometryUtil', () => { let util: L33tGeometryUtil; beforeEach(() => { util = new L33tGeometryUtil(); }); describe('lineToBox', () => { test('should detect intersection when line passes through box', () => { const line = new THREE.Line3( new THREE.Vector3(0, 0, 0), new THREE.Vector3(10, 10, 10) ); const box = new THREE.Box3( new THREE.Vector3(5, 5, 5), new THREE.Vector3(15, 15, 15) ); expect(util.lineToBox(line, box)).toBe(true); }); test('should return false when line is completely outside box', () => { const line = new THREE.Line3( new THREE.Vector3(0, 0, 0), new THREE.Vector3(4, 4, 4) ); const box = new THREE.Box3( new THREE.Vector3(5, 5, 5), new THREE.Vector3(15, 15, 15) ); expect(util.lineToBox(line, box)).toBe(false); }); }); describe('boxToBox', () => { test('should detect intersection of overlapping boxes', () => { const box1 = new THREE.Box3( new THREE.Vector3(0, 0, 0), new THREE.Vector3(10, 10, 10) ); const box2 = new THREE.Box3( new THREE.Vector3(5, 5, 5), new THREE.Vector3(15, 15, 15) ); const result = util.boxToBox(box1, box2); expect(result.intersects).toBe(true); expect(result.contained).toBe(false); }); test('should detect when one box contains another', () => { const outer = new THREE.Box3( new THREE.Vector3(0, 0, 0), new THREE.Vector3(20, 20, 20) ); const inner = new THREE.Box3( new THREE.Vector3(5, 5, 5), new THREE.Vector3(15, 15, 15) ); const result = util.boxToBox(outer, inner); expect(result.intersects).toBe(true); expect(result.contained).toBe(true); }); test('should return false for separate boxes', () => { const box1 = new THREE.Box3( new THREE.Vector3(0, 0, 0), new THREE.Vector3(5, 5, 5) ); const box2 = new THREE.Box3( new THREE.Vector3(6, 6, 6), new THREE.Vector3(10, 10, 10) ); const result = util.boxToBox(box1, box2); expect(result.intersects).toBe(false); expect(result.contained).toBe(false); }); }); describe('lineToLine', () => { test('should detect intersection of crossing lines', () => { const line1 = new THREE.Line3( new THREE.Vector3(-1, 0, 0), new THREE.Vector3(1, 0, 0) ); const line2 = new THREE.Line3( new THREE.Vector3(0, -1, 0), new THREE.Vector3(0, 1, 0) ); const result = util.lineToLine(line1, line2); expect(result).toBeInstanceOf(THREE.Vector3); if (result instanceof THREE.Vector3) { expect(result.x).toBeCloseTo(0); expect(result.y).toBeCloseTo(0); expect(result.z).toBeCloseTo(0); } }); test('should return false for parallel lines', () => { const line1 = new THREE.Line3( new THREE.Vector3(0, 0, 0), new THREE.Vector3(1, 0, 0) ); const line2 = new THREE.Line3( new THREE.Vector3(0, 1, 0), new THREE.Vector3(1, 1, 0) ); expect(util.lineToLine(line1, line2)).toBe(false); }); }); describe('polygonToLine', () => { test('should detect intersection when line crosses polygon boundary', () => { const polygon = [ new THREE.Vector3(-1, -1, 0), new THREE.Vector3(1, -1, 0), new THREE.Vector3(0, 1, 0) ]; const line = new THREE.Line3( new THREE.Vector3(0, -2, 0), new THREE.Vector3(0, 2, 0) ); expect(util.polygonToLine(polygon, line)).toBe(true); }); test('should return false when line is clearly outside polygon', () => { const polygon = [ new THREE.Vector3(-1, -1, 0), new THREE.Vector3(1, -1, 0), new THREE.Vector3(0, 1, 0) ]; const line = new THREE.Line3( new THREE.Vector3(-20, 20, 0), new THREE.Vector3(20, 20, 0) ); expect(util.polygonToLine(polygon, line)).toBe(false); }); test('should throw error for invalid polygon', () => { const invalidPolygon = [ new THREE.Vector3(0, 0, 0), new THREE.Vector3(1, 0, 0) ]; const line = new THREE.Line3( new THREE.Vector3(0, 0, 0), new THREE.Vector3(1, 1, 0) ); expect(() => util.polygonToLine(invalidPolygon, line)).toThrow(); }); }); describe('polygonToPolygon', () => { test('should detect intersection of overlapping polygons', () => { const poly1 = [ new THREE.Vector3(-1, -1, 0), new THREE.Vector3(1, -1, 0), new THREE.Vector3(0, 1, 0) ]; const poly2 = [ new THREE.Vector3(0, -2, 0), new THREE.Vector3(2, 0, 0), new THREE.Vector3(0, 2, 0), new THREE.Vector3(-2, 0, 0) ]; expect(util.polygonToPolygon(poly1, poly2)).toBe(true); }); test('should return false for clearly separate polygons', () => { const poly1 = [ new THREE.Vector3(-1, -1, 0), new THREE.Vector3(0, -1, 0), new THREE.Vector3(-0.5, 0, 0) ]; const poly2 = [ new THREE.Vector3(1, 1, 0), new THREE.Vector3(2, 1, 0), new THREE.Vector3(1.5, 2, 0) ]; expect(util.polygonToPolygon(poly1, poly2)).toBe(false); }); test('should throw error for invalid polygons', () => { const invalidPolygon = [ new THREE.Vector3(0, 0, 0), new THREE.Vector3(1, 0, 0) ]; const validPolygon = [ new THREE.Vector3(0, 0, 0), new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 1, 0) ]; expect(() => util.polygonToPolygon(invalidPolygon, validPolygon)).toThrow(); }); }); });