import { describe, expect, it } from 'vitest'; import { buildPier } from '../src/core/geometry'; import { DEFAULT_MATERIAL } from '../src/core/rebar/common'; import { buildQuantity, quantityRows, unitWeight } from '../src/core/rebar/quantity'; import { rebarSummary } from '../src/core/rebar/summary'; import { loadP1 } from './helpers'; const model = buildPier(loadP1()); const rows = rebarSummary(model).rows; describe('철근재료표 (승인 2026-10-23)', () => { it('unit weight is 0.00617 · d² on the nominal diameter (H19 19.1 → 2.25 kg/m)', () => { expect(unitWeight(19.1)).toBeCloseTo(2.25, 2); }); it('groups by 강종 then diameter; the group totals add up to the total', () => { const q = buildQuantity(rows, DEFAULT_MATERIAL); expect(q.groups.map((g) => g.grade)).toEqual([300, 400, 500].filter((g) => q.groups.some((x) => x.grade === g))); expect(q.groups.reduce((s, g) => s + g.kg, 0)).toBeCloseTo(q.kg, 6); for (const g of q.groups) { expect(g.diameters.reduce((s, d) => s + d.kg, 0)).toBeCloseTo(g.kg, 6); } }); it('a row with several lengths is totalled from its pieces, not left out', () => { const q = buildQuantity(rows, DEFAULT_MATERIAL); expect(q.missing).toEqual([]); expect(q.groups.flatMap((g) => g.diameters.flatMap((d) => d.lines.map((l) => l.name)))).toContain('C9'); }); it('couplers are counted, not weighed', () => { const q = buildQuantity(rows, DEFAULT_MATERIAL); expect(q.couplers.find((c) => c.name === '주철근 커플러')!.count).toBe(368); expect(q.couplers.find((c) => c.name === '띠철근 커플러')!.count).toBe(35); }); it('할증 is 0% by default and multiplies the total when set', () => { const q0 = buildQuantity(rows, DEFAULT_MATERIAL); expect(q0.kgWithWaste).toBeCloseTo(q0.kg, 6); const q10 = buildQuantity(rows, { ...DEFAULT_MATERIAL, waste: 10 }); expect(q10.kgWithWaste).toBeCloseTo(q0.kg * 1.1, 6); expect(q10.ton).toBeCloseTo(q0.kg * 1.1 / 1000, 9); }); it('the Excel rows start with the header and end with the couplers', () => { const aoa = quantityRows(buildQuantity(rows, DEFAULT_MATERIAL)); expect(aoa[0][0]).toBe('강종'); expect(aoa[aoa.length - 1][0]).toBe('커플러 (개수만)'); }); });