feat(rebar): 기둥 배근 입력 8개 (피복·띠철근 K3/K5/K4·K6·커플러·Δz·n_div), CL01·CL02 검사
- core/rebar/column-settings.ts: 입력 정의, 기본값(기둥철근 (1).md), 범위(제안), 검사 (CL01 범위, CL02 n_div 홀수) - 주철근 하단 갈고리는 고정 (입력 없음) - 기둥 탭 패널: 적용 버튼으로 반영, 계산 결과(K2 내측 r, 주철근·커플러 수량) 표시 - P1·P2 등분 수, P3·P5·P4·P6 간격, 커플러 간격·상승을 철근표 간격·비고와 근거(기본값/입력)에 연동 - 3D 주철근 개수도 n_div 입력을 사용 (COLUMN_P1 하드코딩 제거) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
496e0ea4e5
commit
f619b9ea20
9 files changed
+215
-20
No files matched your search
@@ -0,0 +1,44 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildPier } from '../src/core/geometry';
|
||||
import { columnInputFor, columnRebar } from '../src/core/rebar/column';
|
||||
import { COLUMN_REBAR_RANGES, columnSettingsIssues, DEFAULT_COLUMN_REBAR } from '../src/core/rebar/column-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(columnSettingsIssues(DEFAULT_COLUMN_REBAR)).toEqual([]);
|
||||
for (const [key, [lo, hi]] of Object.entries(COLUMN_REBAR_RANGES)) {
|
||||
const v = DEFAULT_COLUMN_REBAR[key as keyof typeof DEFAULT_COLUMN_REBAR];
|
||||
expect(v >= lo && v <= hi, key).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it('a value outside its range gives CL01 on that key; an odd n_div gives CL02', () => {
|
||||
expect(columnSettingsIssues({ ...DEFAULT_COLUMN_REBAR, c: 151 })).toEqual([expect.objectContaining({ code: 'CL01', key: 'c' })]);
|
||||
expect(columnSettingsIssues({ ...DEFAULT_COLUMN_REBAR, nDiv: 45 })).toEqual([expect.objectContaining({ code: 'CL02', key: 'nDiv' })]);
|
||||
});
|
||||
|
||||
it('P1 defaults: P1 원주 46등분, P3 간격 300 · 기본값 근거', () => {
|
||||
const rows = rebarSummary(buildPier(loadP1())).rows;
|
||||
const p1 = rows.find((r) => r.name === 'P1')!;
|
||||
expect([p1.spacing, p1.basis]).toEqual(['원주 46등분', 'default']);
|
||||
const p3 = rows.find((r) => r.name === 'P3')!;
|
||||
expect([p3.spacing, p3.actual, p3.basis]).toEqual(['300', '300', 'default']);
|
||||
});
|
||||
|
||||
it('changed inputs reach the table (간격·근거·비고) and the column input', () => {
|
||||
const m = buildPier({ ...loadP1(), columnRebar: { ctcP3: 320, nDiv: 40 } });
|
||||
expect(columnInputFor(m).ctcP3).toBe(320);
|
||||
expect(columnInputFor(m).nDiv).toBe(40);
|
||||
const rows = rebarSummary(m).rows;
|
||||
const p3 = rows.find((r) => r.name === 'P3')!;
|
||||
expect([p3.spacing, p3.basis]).toEqual(['320', 'input']);
|
||||
expect(p3.note).toContain('@320');
|
||||
const p1 = rows.find((r) => r.name === 'P1')!;
|
||||
expect([p1.spacing, p1.basis]).toEqual(['원주 40등분', 'input']);
|
||||
// mainP1 = n_div × (couplers + 1): 40 bars per level.
|
||||
const col = columnRebar(columnInputFor(m));
|
||||
expect(col.mainP1).toBe(40 * (col.couplerP1.length + 1));
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user