import { describe, expect, it } from 'vitest'; import { buildPier } from '../src/core/geometry'; import { DEFAULT_BEND, DEFAULT_MATERIAL, fyOf, isAssumedMaterial, materialFrom } from '../src/core/rebar/common'; import { rebarSummary } from '../src/core/rebar/summary'; import { loadP1 } from './helpers'; describe('③ 철근 강도: 규격 접두어별 입력 (승인 2026-10-23)', () => { it('defaults: D = SD300, H = SD400, S = SD500, the same as the P1 values', () => { expect(DEFAULT_MATERIAL.grade).toEqual({ D: 300, H: 400, S: 500 }); expect(fyOf(DEFAULT_MATERIAL, 'H19')).toBe(400); expect(fyOf(DEFAULT_MATERIAL, 'S32')).toBe(500); expect(fyOf(DEFAULT_MATERIAL, 'D22')).toBe(300); }); it('only fck is assumed now; the grades are confirmed inputs', () => { expect(isAssumedMaterial(DEFAULT_MATERIAL)).toBe(true); expect(isAssumedMaterial({ ...DEFAULT_MATERIAL, fck: 35 })).toBe(false); expect(isAssumedMaterial({ ...DEFAULT_MATERIAL, grade: { D: 300, H: 400, S: 400 } })).toBe(true); }); it('an older file that stored fyH / fyS is read into the grade map', () => { expect(materialFrom({ fck: 35, fyH: 400, fyS: 400 })).toEqual({ fck: 35, grade: { D: 300, H: 400, S: 400 }, bend: DEFAULT_BEND }); }); it('a value outside SD300 · SD400 · SD500 falls back to the default for its prefix', () => { expect(materialFrom({ fck: 27, grade: { S: 600 } }).grade.S).toBe(500); expect(materialFrom(undefined)).toEqual(DEFAULT_MATERIAL); }); it('the P1 values do not change with the defaults (S = SD500 gives the same C7 length)', () => { const model = buildPier(loadP1()); const base = rebarSummary(model).rows.find((r) => r.name === 'C7')!.length; const same = rebarSummary(model, materialFrom({ fck: 27, grade: { D: 300, H: 400, S: 500 } })).rows.find((r) => r.name === 'C7')!.length; expect(same).toBe(base); }); }); import { bendDeduction, bendRadius } from '../src/core/rebar/common'; describe('굽힘 반경 (승인 2026-10-23, 입력)', () => { it('centre-line radius = inner factor × d + d/2, by size class', () => { expect(bendRadius(25.4, DEFAULT_BEND)).toBeCloseTo(3 * 25.4 + 12.7, 6); // H25: main25 expect(bendRadius(28.6, DEFAULT_BEND)).toBeCloseTo(4 * 28.6 + 14.3, 6); // H29: main35 expect(bendRadius(15.9, DEFAULT_BEND)).toBeCloseTo(2 * 15.9 + 7.95, 6); // H16: small16 }); it('a 90° bend loses (2 − π/2)·R of centre line against the sharp corner', () => { const R = 100; expect(bendDeduction(Math.PI / 2, R)).toBeCloseTo((2 - Math.PI / 2) * R, 6); }); });