- 선택 줄 (타일): 좌우 같게(기본) / 따로 정하기, 편집할 측 (좌 · ① 쪽 / 우 · ⑤ 쪽), 형식 일반형(기본) / 단축형 / 없음 - 측별 치수 입력 (WingDims, 교대 기록 wingDims): 길이 6500, 두께 450, 끝 높이 1500(일반형), 헌치 300. 단축형 길이 기본 = 뒷굽 끝(1.807 m). 좌우 같게이면 양쪽에 함께 적용, 켤 때 좌측 값을 우측에 복사 - 연동: 두께 → 날개벽 3D · 접속슬래브 폭(geometry slabWidthMm) · 슬래브 평면, 헌치 → 연직 헌치 · 저판 상면 헌치 (0이면 없음) - 자동 값: 경사 (A1 = −i), 등단면 · 변화단면 경계(뒷굽 끝), 끝 EL 상단 / 하단 (가정), 단축형 하단 = 확대기초 상면 (뒷굽 밖은 AI02 안내) - 삽도 3개 (src/view/abut-wing-svg.ts): 평면(좌우 날개벽 · 접속슬래브, abutPlanOutline 공유), 측면(수평 단 · 뒷굽 끝), 날개벽–흉벽 모서리 모식도(헌치 · 브라켓 · 슬래브 모따기 · 간격) - "생성되는 날개벽" 줄과 시안 메모. 프로젝트 파일 검사에 wingDims · wingsLinked 추가 - 테스트 7건 추가 · 갱신. 전체 669건 통과, 타입 검사 · 빌드 통과. 브라우저 시각 확인은 미실시 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
73 lines
3.8 KiB
TypeScript
73 lines
3.8 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, setWingsLinked, applyWingDim } 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 both sides while 좌우 같게 (default), one side once it is off', () => {
|
|
expect(setWingForm(rec, 'left', 'short').wings).toEqual({ left: 'short', right: 'short' });
|
|
const apart = setWingsLinked(rec, false);
|
|
expect(setWingForm(apart, 'left', 'short').wings).toEqual({ left: 'short', right: 'general' });
|
|
expect(rec.wings).toBeUndefined();
|
|
});
|
|
|
|
it('wing dims: 좌우 같게 applies to both sides, off applies to one; turning it on copies the left side', () => {
|
|
const both = applyWingDim(rec, 'left', 'lengthMm', 6000);
|
|
expect(both.wingDims).toEqual({ left: { lengthMm: 6000 }, right: { lengthMm: 6000 } });
|
|
const apart = applyWingDim(setWingsLinked(rec, false), 'right', 'thicknessMm', 500);
|
|
expect(apart.wingDims).toEqual({ left: {}, right: { thicknessMm: 500 } });
|
|
const relinked = setWingsLinked(applyWingDim(apart, 'left', 'lengthMm', 5000), true);
|
|
expect(relinked.wingDims).toEqual({ left: { lengthMm: 5000 }, right: { lengthMm: 5000 } });
|
|
expect(() => applyWingDim(rec, 'left', 'thicknessMm', 0)).toThrow('두께');
|
|
expect(() => applyWingDim(rec, 'left', 'haunchMm', -1)).toThrow('헌치');
|
|
});
|
|
});
|
|
|
|
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('기초 하단');
|
|
});
|
|
});
|
|
|