Files
Pier_v1/tests/abut-edit.test.ts
T
ypshimandClaude Haiku 5.5 1d31d2f3a9 feat(abut): 교대 형상·입력 패널과 교각 받침·솔플레이트 개편
- 교대 형상(src/core/abut, 3D 장면, 목록·카메라·맞춤)과 교대 입력 패널 추가
- 교각 받침 기준 카드 제거, 솔플레이트 규칙을 교각별 입력으로 변경
- 받침 ELEVATION·솔플레이트 TABLE을 모델값으로 연결
- 교대 입력값 카드: 형식 행에 시점·종점 표시, 제목을 "A1 입력값 [입력]"으로 변경
- 테스트 614건 통과, 타입 검사 통과

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-03 14:51:34 +09:00

61 lines
2.9 KiB
TypeScript

import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import * as XLSX from 'xlsx';
import { describe, expect, it } from 'vitest';
import { applyAbutEdit, applyBearingEdit, restoreAbutDefault, setWingForm } from '../src/core/abut/edit';
import { parseAbutments } from '../src/core/abut/parse';
const RAG = fileURLToPath(new URL('../../../RAG/운곡교P1입력.xlsx', import.meta.url));
const rec = parseAbutments(XLSX.read(readFileSync(RAG), { type: 'buffer' })).abutments[0];
describe('교대 입력 편집 (교대 편집 카드)', () => {
it('a valid change returns a new record and leaves the old one unchanged', () => {
const next = applyAbutEdit(rec, 'groundEl', 34.5);
expect(next.groundEl).toBe(34.5);
expect(rec.groundEl).toBeCloseTo(33.984, 3);
});
it('a non-number, a pile length of 0 or a skew out of range are refused with the field name', () => {
expect(() => applyAbutEdit(rec, 'seatEl', NaN)).toThrow('교좌면 EL');
expect(() => applyAbutEdit(rec, 'pileLengthMm', 0)).toThrow('말뚝길이');
expect(() => applyAbutEdit(rec, 'skewDeg', 200)).toThrow('skew');
});
it('the 교좌면 EL must stay above the 기초 하단 EL', () => {
expect(() => applyAbutEdit(rec, 'seatEl', rec.foundationBottomEl)).toThrow('기초 하단 EL보다 높아야');
});
it('a wing form change sets one side and keeps the other', () => {
const next = setWingForm(rec, 'left', 'short');
expect(next.wings).toEqual({ left: 'short', right: 'general' });
expect(rec.wings).toBeUndefined();
});
});
describe('교대 기본값 복원과 받침 편집', () => {
it('restores the imported defaults after several changes (a copy, not the same object)', () => {
const changed = setWingForm(applyAbutEdit(rec, 'groundEl', 34.5), 'left', 'none');
const back = restoreAbutDefault(rec);
expect(back).toEqual(rec);
expect(back).not.toBe(rec);
expect(changed.groundEl).toBe(34.5);
});
it('a bearing z change keeps the others; a 교좌면 override sets that bearing only', () => {
const z = applyBearingEdit(rec, 3, 'z', 44.7);
expect(z.bearings.find((b) => b.no === 3)!.z).toBe(44.7);
expect(z.bearings.find((b) => b.no === 1)!.z).toBe(rec.bearings[0].z);
const seat = applyBearingEdit(rec, 2, 'seatEl', 44.5);
expect(seat.bearings.find((b) => b.no === 2)!.seatEl).toBe(44.5);
const auto = applyBearingEdit(seat, 2, 'seatEl', undefined);
expect(auto.bearings.find((b) => b.no === 2)!.seatEl).toBeUndefined();
});
it('refuses an unknown bearing, a non-number z, and a 교좌면 at or below the 기초 하단', () => {
expect(() => applyBearingEdit(rec, 99, 'z', 44)).toThrow('받침 99번');
expect(() => applyBearingEdit(rec, 1, 'z', undefined)).toThrow('z는 숫자');
expect(() => applyBearingEdit(rec, 1, 'seatEl', rec.foundationBottomEl)).toThrow('기초 하단');
});
});