- 부재별 복사 항목 대응표(MEMBER_COPY_ITEMS)를 core/copy-targets.ts에 두고 테스트 추가 코핑 → 폭·길이, 확대기초·말뚝 → 말뚝 길이·열별 본수, 지반 → 위치·지하수위, 기둥·받침 → 없음 - 항목은 선택된 부재(state.member) 기준으로 그려지고, 체크 상태는 부재를 바꿔도 유지 - 기둥·받침은 "복사 항목 없음"을 표시하고 적용 버튼을 비활성화 - ①은 복사 패널 안의 부재 선택으로, ②는 부재 목록으로 같은 부재를 고름 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { copyCandidates, copyItemsFor, selectedTargets, type CopyCandidate } from '../src/core/copy-targets';
|
|
|
|
const piers: CopyCandidate[] = [
|
|
{ name: 'P1', type: 'T형', hasModel: true },
|
|
{ name: 'P2', type: 'T형', hasModel: true },
|
|
{ name: 'P3', type: 'T형', hasModel: true },
|
|
{ name: 'P4', type: 'Y형', hasModel: true },
|
|
{ name: 'P5', type: 'T형', hasModel: false },
|
|
];
|
|
|
|
describe('copyCandidates (대상 후보)', () => {
|
|
it('excludes the source pier', () => {
|
|
expect(copyCandidates(piers, 'P3', false).map((c) => c.name)).not.toContain('P3');
|
|
});
|
|
|
|
it('keeps only the source type when 같은 형식만 is on', () => {
|
|
expect(copyCandidates(piers, 'P3', true).map((c) => c.name)).toEqual(['P1', 'P2', 'P5']);
|
|
});
|
|
|
|
it('marks a pier without a model as not selectable', () => {
|
|
const p5 = copyCandidates(piers, 'P3', false).find((c) => c.name === 'P5');
|
|
expect(p5?.selectable).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('selectedTargets (선택한 대상만)', () => {
|
|
it('is empty when nothing is ticked', () => {
|
|
expect(selectedTargets(piers, 'P3', false, new Set())).toEqual([]);
|
|
});
|
|
|
|
it('returns only ticked, selectable piers', () => {
|
|
const picked = new Set(['P1', 'P4', 'P5']);
|
|
expect(selectedTargets(piers, 'P3', false, picked)).toEqual(['P1', 'P4']);
|
|
});
|
|
|
|
it('ignores a tick on a pier hidden by the same-type filter', () => {
|
|
const picked = new Set(['P4']);
|
|
expect(selectedTargets(piers, 'P3', true, picked)).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('copyItemsFor (부재 선택에 해당하는 복사 항목)', () => {
|
|
it('coping copies only the coping items', () => {
|
|
expect(copyItemsFor('coping')).toEqual(['coping-width', 'coping-length']);
|
|
});
|
|
|
|
it('확대기초 · 말뚝 copies only the pile items', () => {
|
|
expect(copyItemsFor('footing')).toEqual(['pile-length', 'pile-rows']);
|
|
});
|
|
|
|
it('지반 copies only the ground position', () => {
|
|
expect(copyItemsFor('ground')).toEqual(['ground-position']);
|
|
});
|
|
|
|
it('기둥 and 받침 have no copy items yet', () => {
|
|
expect(copyItemsFor('column')).toEqual([]);
|
|
expect(copyItemsFor('bearing')).toEqual([]);
|
|
});
|
|
|
|
it('every copy item belongs to exactly one member', () => {
|
|
const all = (['bearing', 'coping', 'column', 'footing', 'ground'] as const).flatMap((m) => copyItemsFor(m));
|
|
expect([...all].sort()).toEqual(['coping-length', 'coping-width', 'ground-position', 'pile-length', 'pile-rows']);
|
|
});
|
|
});
|