import { describe, expect, it } from 'vitest'; import { allVisibleChecked, checkedCount, selectableVisible, setVisibleChecked, type Selectable } from '../src/core/selection'; import type { PierType } from '../src/core/types'; const TYPES: PierType[] = ['T형', '2주형', '3주형']; /** 20 piers: mixed types, and two that failed to build (model null). */ function twenty(): (Selectable & { name: string })[] { return Array.from({ length: 20 }, (_, i) => ({ name: `P${i + 1}`, input: { type: TYPES[i % 3] }, model: i === 4 || i === 13 ? null : {}, checked: false, })); } describe('교각 목록 다중 선택 (spec §9, plan C6)', () => { it('전체 선택 acts on visible, buildable piers only', () => { const next = setVisibleChecked(twenty(), 'all', true); expect(checkedCount(next)).toBe(18); expect(next.find((p) => p.name === 'P5')!.checked).toBe(false); }); it('the type filter limits 전체 선택 to that type', () => { const next = setVisibleChecked(twenty(), 'T형', true); const t = next.filter((p) => p.input.type === 'T형' && p.model !== null); expect(t.every((p) => p.checked)).toBe(true); expect(checkedCount(next)).toBe(t.length); }); it('checks made under one filter survive a change of filter', () => { let piers = setVisibleChecked(twenty(), '2주형', true); const before = checkedCount(piers); piers = setVisibleChecked(piers, 'T형', false); expect(checkedCount(piers)).toBe(before); }); it('the button reads 선택 해제 only when all selectable visible piers are checked', () => { let piers = setVisibleChecked(twenty(), '3주형', true); expect(allVisibleChecked(piers, '3주형')).toBe(true); expect(allVisibleChecked(piers, 'all')).toBe(false); piers = setVisibleChecked(piers, '3주형', false); expect(allVisibleChecked(piers, '3주형')).toBe(false); }); it('a list of 20 piers keeps every selectable one', () => { expect(selectableVisible(twenty(), 'all')).toHaveLength(18); }); });