Files
Pier_v1/tests/rebar-pieces.test.ts
ypshimandClaude Haiku 5.5 2e0bfb6fc8 feat(rebar): 현장타설 말뚝 · 다주형 코핑 형상과 철근 계산
- 현장타설 기둥·말뚝 형상(cast-in-place-shape)과 주철근·횡철근·커플러 계산(rebar/cast-in-place, cast-layout)
- 다주형 코핑 철근(multicol-coping), 기둥 높이 · 양단부 연장
- 철근표 요약 · 재료 수량 · 3D 뷰 연결과 삽도(cast-rebar-svg)
- 검사 기준 갱신과 회귀 테스트, 검증 스크립트 보관

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-06 13:15:01 +09:00

50 lines
2.3 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { buildPier } from '../src/core/geometry';
import { DEFAULT_MATERIAL } from '../src/core/rebar/common';
import { buildQuantity } from '../src/core/rebar/quantity';
import { rebarSummary, type RebarRow } from '../src/core/rebar/summary';
import { loadP1 } from './helpers';
const rows = rebarSummary(buildPier(loadP1())).rows;
const row = (name: string): RebarRow => rows.find((r) => r.name === name)!;
const total = (r: RebarRow) => r.pieces!.reduce((s, p) => s + p.count * p.length, 0);
const bars = (r: RebarRow) => r.pieces!.reduce((s, p) => s + p.count, 0);
const hasLength = (r: RebarRow, mm: number, tol = 3) => r.pieces!.some((p) => Math.abs(p.length - mm) < tol);
describe('조각 길이 (승인 2026-10-23): 여러 길이를 가진 행', () => {
it('C9 and C11 pieces: U (3522 first, 6098 last) and 삿갓, 3 loops each; 108 bars per row', () => {
for (const name of ['C9', 'C11']) {
expect(row(name).pieces, name).toBeDefined();
expect(bars(row(name)), name).toBe(108);
expect(hasLength(row(name), 3522), name).toBe(true);
expect(hasLength(row(name), 6098), name).toBe(true);
}
});
it('C10 pieces: outer U 6249 and Level U 6340; 54 bars', () => {
expect(bars(row('C10'))).toBe(54);
expect(hasLength(row('C10'), 6249)).toBe(true);
expect(hasLength(row('C10'), 6340)).toBe(true);
});
it('C12 and C13 pieces: the bars per row equal the row count (4 per position)', () => {
expect(bars(row('C12'))).toBe(row('C12').count);
expect(bars(row('C13'))).toBe(row('C13').count);
expect(total(row('C12'))).toBeGreaterThan(0);
});
it('P1 and P2 pieces: each level has 46 bars, giving 230 physical pieces in all', () => {
expect(row('P1').pieces!.every((p) => p.count === 46)).toBe(true);
expect(row('P2').pieces!.every((p) => p.count === 46)).toBe(true);
expect(bars(row('P1'))).toBe(row('P1').count);
expect(bars(row('P2'))).toBe(row('P2').count);
expect(row('P1').pieces!.length).toBeGreaterThan(1);
});
it('the 재료표 no longer leaves out any P1 bar: no missing bars', () => {
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)))).toEqual(expect.arrayContaining(['C9', 'C10', 'C11', 'C12', 'P1', 'P2']));
});
});