import { describe, expect, it } from 'vitest'; import { buildPier } from '../src/core/geometry'; import { assemblyJs, gridPositions } from '../src/core/rebar/footing'; import { DEFAULT_FOOTING_REBAR, FOOTING_REBAR_RANGES, footingSettingsIssues } from '../src/core/rebar/footing-settings'; import { rebarSummary } from '../src/core/rebar/summary'; import { loadP1 } from './helpers'; describe('확대기초 배근 입력 (승인 2026-10-26, 시안 ③ 확대기초)', () => { it('the defaults are inside every range and raise no issue', () => { expect(footingSettingsIssues(DEFAULT_FOOTING_REBAR)).toEqual([]); for (const [key, [lo, hi]] of Object.entries(FOOTING_REBAR_RANGES)) { const v = DEFAULT_FOOTING_REBAR[key as keyof typeof DEFAULT_FOOTING_REBAR]; expect(v >= lo && v <= hi, key).toBe(true); } }); it('a value outside its range gives FT01; a non-integer n gives FT02', () => { expect(footingSettingsIssues({ ...DEFAULT_FOOTING_REBAR, cTop: 151 })).toEqual([expect.objectContaining({ code: 'FT01', key: 'cTop' })]); expect(footingSettingsIssues({ ...DEFAULT_FOOTING_REBAR, n: 2.5 })).toEqual([expect.objectContaining({ code: 'FT02', key: 'n' })]); }); it('the grid spacing s reaches the grid positions and the rebar table', () => { const m = buildPier({ ...loadP1(), footingRebar: { s: 150 } }); expect(m.footingRebar.s).toBe(150); const xs = gridPositions(8000, m.footingRebar); expect(xs[1] - xs[0]).toBeCloseTo(150, 6); const b4 = rebarSummary(m).rows.find((r) => r.name === 'B4')!; const b4Default = rebarSummary(buildPier(loadP1())).rows.find((r) => r.name === 'B4')!; expect(b4.count).not.toBe(b4Default.count); }); it('the 조립 단 배수 n reaches the assembly levels', () => { const H = 2000; const base = assemblyJs(H, DEFAULT_FOOTING_REBAR); const wider = assemblyJs(H, { ...DEFAULT_FOOTING_REBAR, n: 3 }); expect(wider.length).toBeLessThan(base.length); expect(wider.every((j) => j % 3 === 0)).toBe(true); }); });