import { describe, expect, it } from 'vitest'; import { buildPier } from '../src/core/geometry'; import { DEFAULT_MATERIAL, isAssumedMaterial } from '../src/core/rebar/common'; import { columnRebar } from '../src/core/rebar/column'; import { rebarSummary } from '../src/core/rebar/summary'; import { loadP1 } from './helpers'; describe('③ 공통 설정: fck · fy 입력 (spec §6.2)', () => { const model = buildPier(loadP1()); it('defaults are assumed (I02); changed values are not', () => { expect(isAssumedMaterial(DEFAULT_MATERIAL)).toBe(true); expect(isAssumedMaterial({ ...DEFAULT_MATERIAL, fck: 35 })).toBe(false); }); it('a higher fck shortens the laps: P3 lap scales with 1/√fck (27 → 35)', () => { const base = columnRebar(); const high = columnRebar(undefined, { ...DEFAULT_MATERIAL, fck: 35 }); expect(high.lapP3 / base.lapP3).toBeCloseTo(Math.sqrt(27 / 35), 3); expect(high.zTop2).toBeLessThan(base.zTop2); }); it('the rebar summary follows the material: the C7 splice piece changes with fck', () => { const base = rebarSummary(model).rows.find((r) => r.name === 'C7')!.length!; const high = rebarSummary(model, { ...DEFAULT_MATERIAL, fck: 35 }).rows.find((r) => r.name === 'C7')!.length!; expect(high).toBeLessThan(base); }); it('a non-default material drops the I02 warning', () => { const codes = rebarSummary(model, { ...DEFAULT_MATERIAL, fyS: 600 }).warnings.map((w) => w.code); expect(codes).not.toContain('I02'); }); });