- C5: each member's options come from one table. Only the defaults (the 1단계 model) are selectable. The others show as disabled chips with 규칙 미정 (Q6). The member summary is built from the defaults. - C6: 전체 선택 acts only on visible, buildable piers; it reads 선택 해제 only when all of those are checked. A check survives a change of the type filter. The pier list scrolls past 300 px, for 20 piers. - Tests: defaults are the only choices; unknown options refused; the 20-pier mixed list with two failed piers; filter and check persistence. - Not verified in a browser. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { choose, defaultSummary, isSelectable, SHAPE_GROUPS, type MemberId } from '../src/core/shape-options';
|
|
|
|
const MEMBERS: MemberId[] = ['bearing', 'coping', 'column', 'footing', 'ground'];
|
|
|
|
describe('형상 선택지 (spec §5.2, plan C5)', () => {
|
|
it('every group has exactly one default, and it is the 1단계 model', () => {
|
|
for (const m of MEMBERS) {
|
|
for (const g of SHAPE_GROUPS[m]) {
|
|
expect(g.options.filter((o) => o.isDefault)).toHaveLength(1);
|
|
}
|
|
}
|
|
expect(defaultSummary('coping')).toBe('직각 · 직선');
|
|
expect(defaultSummary('column')).toBe('원형 · 중실');
|
|
expect(defaultSummary('footing')).toBe('직사각 · 없음 · 강관 · 없음');
|
|
expect(defaultSummary('ground')).toBe('육상');
|
|
});
|
|
|
|
it('only defaults are selectable; every other option is refused with the reason', () => {
|
|
for (const m of MEMBERS) {
|
|
SHAPE_GROUPS[m].forEach((g, gi) => {
|
|
for (const o of g.options) {
|
|
if (o.isDefault) {
|
|
expect(choose(m, gi, o.label)).toBe(o.label);
|
|
} else {
|
|
expect(isSelectable(o)).toBe(false);
|
|
expect(() => choose(m, gi, o.label)).toThrow('규칙 미정');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
it('an unknown option is refused', () => {
|
|
expect(() => choose('coping', 0, '없는선택')).toThrow('알 수 없는');
|
|
});
|
|
});
|