Files
Pier_v1/tests/abut-rebar-block.test.ts
T
ypshimandClaude Haiku 5.5 a2d0d6057f feat(abut-rebar): 교대 받침블럭 배근 규칙 S1 · S2 (AD6)
- 받침마다 1개 블럭 (1200 × 1200, 높이 125 − 패드 50 = 콘크리트 75). 본수 · 다리 · 여유는 교각 규칙(barsAcross · barLength) 재사용, 깊이만 교대 H13으로 계산
- 묻힘 S2 675 · S1 688, 길이 2500, 블럭당 8본 (40 · 40). 블럭 방위각 회전
- 간섭 (Q-S4, 결정 2026-11-05): S1 다리가 W2 층을 지나면 RB-AK01 경고만
- 테스트: 교대 기획서 §10 값, 간섭 경고, 간격 수정, 회전

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-05 09:36:53 +09:00

53 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest';
import { abutBlockRebar, abutBarDepths } from '../src/core/abut/rebar/block';
// 교대 받침블럭 (교대 기획서 §10 · 받침블럭철근.md §6.6): 블럭 5개, 1200 × 1200, 높이 125 (패드 50 포함, 콘크리트 75).
const blocks = [1, 2, 3, 4, 5].map((no, i) => ({ no, s: 1 + i * 2, t: 0.2, rotDeg: 0, seatEl: 44.367, blockHeightMm: 125 }));
const bottom = 40.895;
const A1 = abutBlockRebar(blocks, bottom);
const bar = (r: typeof A1, m: 'S1' | 'S2') => r.bars.find((b) => b.mark === m)!;
describe('교대 받침블럭 배근 A1 (AD6, 교대 기획서 §10)', () => {
it('블럭 콘크리트 75 (블럭 125 − 패드 50), 깊이: S2 50 · S1 62.7 (H13 두 개)', () => {
expect(A1.concreteH).toBe(75);
expect(abutBarDepths(A1.settings)).toEqual({ S2: 50, S1: 50 + 6.35 + 6.35 });
});
it('본수: 블럭마다 8본 (7@125, 끝 162.5), 5개 → S1 40 · S2 40', () => {
expect(bar(A1, 'S1').count).toBe(40);
expect(bar(A1, 'S2').count).toBe(40);
expect(A1.paths.filter((p) => p.mark === 'S1' && p.block === 1).length).toBe(8);
// 블럭 1 (s = 1000 mm): S2 본은 블럭 모서리에서 162.5, 125 간격 → 첫 본 s = 1000 − 600 + 162.5 = 562.5.
const s2 = A1.paths.filter((p) => p.mark === 'S2' && p.block === 1).map((p) => p.pts[0][0]).sort((a, b) => a - b);
expect(s2[0]).toBeCloseTo(562.5, 6);
expect(s2[1] - s2[0]).toBeCloseTo(125, 6);
expect(s2.length).toBe(8);
});
it('길이 2500 (1100 직선 + 다리 700 × 2), 묻힘: S2 675 · S1 688', () => {
expect([bar(A1, 'S1').length, bar(A1, 'S2').length]).toEqual([2500, 2500]);
expect(Math.round(A1.embedment.S2)).toBe(675);
expect(Math.round(A1.embedment.S1)).toBe(688);
});
it('간섭 (Q-S4, 경고만): S1 다리가 W2 층을 지남 → RB-AK01 (W), 다른 오류 없음', () => {
const codes = A1.issues.map((i) => `${i.code}:${i.level}`);
expect(codes).toContain('RB-AK01:W');
expect(A1.issues.filter((i) => i.level === 'E')).toEqual([]);
});
it('간격 수정 → RB-AK03 "수정됨"', () => {
const r = abutBlockRebar(blocks, bottom, { spacingS1: 150 });
expect(r.issues.map((i) => i.code)).toContain('RB-AK03');
expect(bar(r, 'S1').modified).toBe(true);
expect(bar(r, 'S2').modified).toBe(false);
});
it('회전 (방위각): 블럭 축이 돌면 경로 점도 같이 돈다 (교대축 방향 길이 보존)', () => {
const r = abutBlockRebar([{ ...blocks[0], rotDeg: 30 }], bottom);
const p = r.paths.find((q) => q.mark === 'S1')!;
const len = Math.hypot(p.pts[2][0] - p.pts[1][0], p.pts[2][1] - p.pts[1][1]);
expect(len).toBeCloseTo(1100, 6);
});
});