import { jointPositions } from '../src/core/abut/joints'; import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import * as XLSX from 'xlsx'; import { describe, expect, it } from 'vitest'; import { buildAbut } from '../src/core/abut/geometry'; import { parseAbutments, toAbutInput } from '../src/core/abut/parse'; import { buildMembers } from '../src/core/abut/members'; import { abutWallElevationSvg, abutWallSectionSvg, type AbutWallDrawing } from '../src/view/abut-wall-svg'; const RAG = fileURLToPath(new URL('../../../RAG/운곡교P1입력.xlsx', import.meta.url)); const rec = parseAbutments(XLSX.read(readFileSync(RAG), { type: 'buffer' })).abutments[0]; const input = toAbutInput(rec); const model = buildAbut(input); const m = buildMembers(model, { bottomEl: input.foundationBottomEl, pileLengthMm: input.pileLengthMm }); const d: AbutWallDrawing = { lengthM: model.length, segments: m.wallSegments, bearings: model.bearings, footingTopEl: m.footingTopEl, footingBottomEl: m.footingBottomEl!, parapetTopStartEl: m.parapetTopStartEl, parapetTopEndEl: m.parapetTopEndEl, wallFrontM: m.shape.wallFrontM, parapetBackM: m.shape.parapetBackM, wallBackM: m.shape.wallBackM, footingFrontM: m.shape.footingFrontM, footingBackM: m.shape.footingBackM, bracketHeightM: m.shape.bracketHeightM, shrinkJointsS: jointPositions(model.length, model.bearings.map((b) => b.s)), bracketWidthMm: 300, parapetThicknessMm: 500, seatWidthMm: 1600, }; describe('교대 벽체·흉벽 삽도 (시안 ② 벽체·흉벽 카드)', () => { it('단면 (① 구간): the width line and the levels of the generated model', () => { const svg = abutWallSectionSvg(d); for (const s of ['300 + 500 + 1600 = 2400', '교좌면 EL.44.367', '벽체 2.372', '상면 EL.41.995', '기초 하단 EL.40.895', '교대축', '← 배면', '전면 →']) { expect(svg).toContain(s); } expect(svg).toMatch(/흉벽 상단 EL\.4[78]\.\d{3}/); expect(svg).toMatch(/브라켓 상면 EL\.4[56]\.\d{3}/); }); it('정면·배면도: five steps, five bearings, the sloped 흉벽 top (IP3 47.661 → IP1 48.006) and the 수축줄눈', () => { const svg = abutWallElevationSvg(d); for (const s of ['IP3', 'IP1', `${model.length.toFixed(3)} m`, '수축줄눈 1', 'EL.47.661', 'EL.48.006', '①', '⑤']) expect(svg).toContain(s); expect(svg).toContain('H_w 3326'); // 받침 ① 기준선의 벽체 높이 (사용자 도면 2026-11-04) expect(svg).toContain('교좌면 계단 5구간'); }); it('the 수축줄눈 count follows the input', () => { const svg = abutWallElevationSvg({ ...d, shrinkJointsS: jointPositions(model.length, model.bearings.map((b) => b.s), 2) }); expect(svg).toContain('수축줄눈 2'); expect(svg.match(/stroke-dasharray="5 3"/g)).toHaveLength(2); }); });