Files
Pier_v1/tests/coping-geom.test.ts
T
ypshimandClaude Haiku 5.5 355bf4ea75 feat(rebar): C12 in the taper band (h2) and C13 in the end band (h1), from the coping geometry
The split between C12 and C13 follows the end underside, not a fixed level: C12 rows lie between the Level underside and
the end underside (taper height h2), C13 rows between the end underside and the top (end height h1). The break is the end
underside + 127 mm, the taper line's start at the end face. P1 is unchanged (C12 41.288–42.288, C13 42.538–42.788). Tests
check the band rule for h1 and h2 changes.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-23 12:03:24 +09:00

88 lines
4.1 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { buildPier } from '../src/core/geometry';
import { P1_COPING_GEOM, SIDE_COVER_M, sideRowLevels } from '../src/core/coping-geom';
import { sideRows } from '../src/core/rebar/coping';
import { shearUHeight, shearULength } from '../src/core/rebar/coping';
import { rebarSummary } from '../src/core/rebar/summary';
import { buildRebar3D } from '../src/view/rebar3d';
import { loadP1 } from './helpers';
const L = 12000;
describe('① 코핑 끝단 높이 h1 · 테이퍼 높이 h2 · Level 폭 (1단계, 승인 2026-10-23)', () => {
it('the P1 geometry reproduces the document U heights (890.9, 2178.8, Level 2300)', () => {
expect(shearUHeight(300, L)).toBeCloseTo(890.9, 1);
expect(shearUHeight(4550, L)).toBeCloseTo(2178.8, 1);
expect(shearUHeight(6000, L)).toBeCloseTo(2300, 6);
});
it('the model defaults to the P1 coping geometry and the P1 shear lengths', () => {
const model = buildPier(loadP1());
expect(model.copingGeom).toEqual(P1_COPING_GEOM);
expect(model.endBottom).toBeCloseTo(43.411 - 1.0, 6);
expect(model.levelBottom).toBeCloseTo(43.411 - 1.0 - 1.5, 6);
});
it('a higher end height h1 lowers the coping ends and adds the same height to every U', () => {
const base = buildPier(loadP1());
const high = buildPier({ ...loadP1(), copingH1Mm: 1200 });
expect(high.endBottom).toBeCloseTo(base.endBottom - 0.2, 6);
expect(high.levelBottom).toBeCloseTo(base.levelBottom - 0.2, 6);
const geomH1 = { ...P1_COPING_GEOM, h1: 1200 };
expect(shearUHeight(300, L, geomH1)).toBeCloseTo(shearUHeight(300, L) + 200, 6);
expect(shearULength(300, L, geomH1)).toBeCloseTo(shearULength(300, L) + 400, 6);
});
it('a taper h2 changes the Level underside and the height at the Level', () => {
const high = buildPier({ ...loadP1(), copingH2Mm: 1800 });
expect(high.levelBottom).toBeCloseTo(43.411 - 1.0 - 1.8, 6);
expect(shearUHeight(6000, L, { ...P1_COPING_GEOM, h2: 1800 })).toBeCloseTo(2600, 6);
});
it('a wider Level changes the Level zone in the model and the shear-bar Level half-width', () => {
const wide = buildPier({ ...loadP1(), levelWidthMm: 2500 });
expect(wide.copingGeom.levelWidth).toBe(2500);
expect(wide.levelBottom).toBeCloseTo(buildPier(loadP1()).levelBottom, 6);
});
it('side-row levels keep their P1 values from the Level underside (assumption, 명세 확인 필요)', () => {
const levels = sideRowLevels(40.911, 42.411);
expect(levels.zBottom).toBeCloseTo(41.288, 6);
expect(levels.zBreak).toBeCloseTo(42.538, 6);
});
it('the coping rebar follows a changed geometry: the rows and the 3D build without error, the positions are unchanged', () => {
const base = rebarSummary(buildPier(loadP1())).rows;
const changed = buildPier({ ...loadP1(), copingH1Mm: 1200, copingH2Mm: 1600, levelWidthMm: 2300 });
const rows = rebarSummary(changed).rows;
expect(rows.find((r) => r.name === 'C10')!.count).toBe(base.find((r) => r.name === 'C10')!.count);
expect(rows.find((r) => r.name === 'C9')!.count).toBe(base.find((r) => r.name === 'C9')!.count);
expect(buildRebar3D(changed).byName.get('C10')!.length).toBeGreaterThan(0);
});
});
describe('C12 in the taper band (h2), C13 in the end band (h1)', () => {
const bands = (input: Parameters<typeof buildPier>[0]) => {
const m = buildPier(input);
const lv = sideRowLevels(m.levelBottom, m.endBottom);
const rows = sideRows(lv.zBottom, lv.zBreak);
return { m, rows };
};
it.each([
['P1', {}],
['h1 800', { copingH1Mm: 800 }],
['h1 1200', { copingH1Mm: 1200 }],
['h2 1800', { copingH2Mm: 1800 }],
])('%s: every C12 row is in the taper band and every C13 row in the end band', (_name, change) => {
const { m, rows } = bands({ ...loadP1(), ...change });
for (const z of rows.c12) {
expect(z).toBeGreaterThanOrEqual(m.levelBottom - 1e-9);
expect(z).toBeLessThan(m.endBottom + SIDE_COVER_M);
}
for (const z of rows.c13) {
expect(z).toBeGreaterThanOrEqual(m.endBottom + SIDE_COVER_M - 1e-9);
expect(z).toBeLessThanOrEqual(m.copingRefTop);
}
});
});