99 lines
2.8 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { RoofSegmentNode } from '@pascal-app/core'
import { resolveRidgeSnap } from './ridge-snap'
describe('resolveRidgeSnap', () => {
test('snaps Dutch width-axis center clicks to the shortened top ridge', () => {
const segment = RoofSegmentNode.parse({
roofType: 'dutch',
width: 8,
depth: 6,
pitch: 40,
overhang: 0,
wallThickness: 0,
shingleThickness: 0,
})
const center = resolveRidgeSnap(segment, 0, 0)
expect(center?.localX).toBeCloseTo(0)
expect(center?.localZ).toBeCloseTo(0)
expect(center?.rotation).toBeCloseTo(0)
})
test('snaps Dutch depth-axis center clicks to the shortened top ridge', () => {
const segment = RoofSegmentNode.parse({
roofType: 'dutch',
width: 6,
depth: 8,
pitch: 40,
overhang: 0,
wallThickness: 0,
shingleThickness: 0,
})
const center = resolveRidgeSnap(segment, 0, 0)
expect(center?.localX).toBeCloseTo(0)
expect(center?.localZ).toBeCloseTo(0)
expect(center?.rotation).toBeCloseTo(Math.PI / 2)
})
test('snaps Dutch shoulder clicks onto the extended lower hip seam up to the rake end', () => {
const segment = RoofSegmentNode.parse({
roofType: 'dutch',
width: 8,
depth: 6,
pitch: 40,
overhang: 0,
wallThickness: 0,
shingleThickness: 0,
})
const snap = resolveRidgeSnap(segment, 3.8, 2.8)
expect(snap).not.toBeNull()
expect(snap?.localX).toBeCloseTo(3.84, 2)
expect(snap?.localZ).toBeCloseTo(2.77, 2)
expect(Math.abs(snap?.rotation ?? 0)).toBeGreaterThan(0.1)
expect(Math.abs(Math.abs(snap?.rotation ?? 0) - Math.PI / 2)).toBeGreaterThan(0.1)
})
test('snaps mansard center clicks to the upper top ridge', () => {
const segment = RoofSegmentNode.parse({
roofType: 'mansard',
width: 8,
depth: 6,
pitch: 40,
})
const center = resolveRidgeSnap(segment, 0, 0)
expect(center?.localX).toBeCloseTo(0)
expect(center?.localZ).toBe(0)
expect(center?.rotation).toBeCloseTo(0)
})
test('snaps mansard lower-slope clicks to the nearest lower-slope vent line', () => {
const segment = RoofSegmentNode.parse({
roofType: 'mansard',
width: 8,
depth: 6,
pitch: 40,
overhang: 0,
wallThickness: 0,
shingleThickness: 0,
})
const frontRight = resolveRidgeSnap(segment, 3.5, 2.5)
const frontLeft = resolveRidgeSnap(segment, -3.5, 2.5)
expect(frontRight?.localX).toBeGreaterThan(0)
expect(frontRight?.localZ).toBeGreaterThan(0)
expect(frontLeft?.localX).toBeLessThan(0)
expect(frontLeft?.localZ).toBeGreaterThan(0)
expect(Math.abs(frontRight?.rotation ?? 0)).toBeGreaterThan(0.1)
expect(Math.abs(frontRight?.rotation ?? 0)).toBeLessThan(Math.PI / 2 - 0.1)
})
})