Files
Pier_v1/tests/p1-regression.test.ts
ypshimandClaude Haiku 5.5 01d2bf4958 feat(parse): report per-sheet recognition and block error sheets
- parseWorkbook returns a report per sheet (table counts, issues, ok)
- sheets with E-level issues cannot be selected (spec section 2.3)
- pier input carries its source sheet name

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-21 17:43:36 +09:00

109 lines
4.3 KiB
TypeScript
Raw Permalink 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 { buildPier } from '../src/core/geometry';
import { loadP1 } from './helpers';
/**
* Regression against spec.md §12 (P1, 운곡교, T형, 말뚝기초).
* Coordinates and EL: ±1 mm (0.001 m). Angles: ±0.01°.
*/
const TOL = 0.001;
const model = buildPier(loadP1());
describe('P1 regression — spec.md §12', () => {
it('axis length and azimuth', () => {
expect(model.lengthIp).toBeCloseTo(12.166, 3);
expect(model.azimuthDeg).toBeCloseTo(350.37, 2);
});
it('BP1, BP2 coordinates (국토좌표 E, N)', () => {
expect(model.bp1.e).toBeCloseTo(259866.681, 2);
expect(model.bp1.n).toBeCloseTo(179132.173, 2);
expect(Math.abs(model.bp2.e - 259864.674)).toBeLessThan(TOL);
expect(Math.abs(model.bp2.n - 179144.004)).toBeLessThan(TOL);
});
it('IP2 reference recalculation and d_IP2', () => {
expect(Math.abs(model.dIp2 - 1.134)).toBeLessThan(TOL);
});
it('column centre coordinates', () => {
expect(Math.abs(model.pivot.e - 259865.677)).toBeLessThan(TOL);
expect(Math.abs(model.pivot.n - 179138.089)).toBeLessThan(TOL);
});
it('bearing positions: front row across-axis −0.698, back row +0.600; front s from 0.943 to 10.965', () => {
const front = model.bearings.filter((b) => b.row === '전열');
const back = model.bearings.filter((b) => b.row === '후열');
expect(front[0].n).toBeCloseTo(-0.698, 3);
expect(back[0].n).toBeCloseTo(0.6, 3);
expect(front[0].s).toBeCloseTo(0.943, 3);
expect(front[4].s).toBeCloseTo(10.965, 3);
expect(back[0].s).toBeCloseTo(1.029, 3);
expect(back[4].s).toBeCloseTo(11.05, 3);
});
it('step boundaries at the midpoints of front bearings: 2.196 / 4.701 / 7.207 / 9.712', () => {
const bounds = model.segments.slice(1).map((s) => s.s0);
[2.196, 4.701, 7.207, 9.712].forEach((b, i) => expect(Math.abs(bounds[i] - b)).toBeLessThan(TOL));
});
it('front segment tops: 43.411 / 43.483 / 43.555 / 43.626 / 43.698', () => {
const tops = model.segments.map((s) => s.top);
[43.411, 43.483, 43.555, 43.626, 43.698].forEach((t, i) => expect(Math.abs(tops[i] - t)).toBeLessThan(TOL));
});
it('bearing block heights: h1 = 150, h2 = 200 mm; concrete 100 / 150 mm', () => {
expect(model.h1).toBeCloseTo(0.15, 6);
expect(model.h2).toBeCloseTo(0.2, 6);
expect(model.derived.blockHeightFront).toBeCloseTo(0.1, 6);
expect(model.derived.blockHeightBack).toBeCloseTo(0.15, 6);
});
it('no lateral step (front and back tops agree)', () => {
expect(model.derived.frontBackDiffSpread).toBeLessThan(0.0051);
});
it('coping bottom: 42.411 at the ends, 40.911 at the Level zone', () => {
expect(Math.abs(model.endBottom - 42.411)).toBeLessThan(TOL);
expect(Math.abs(model.levelBottom - 40.911)).toBeLessThan(TOL);
});
it('column height 12.703 m and footing top 28.208 m, soil cover 0.723 m', () => {
expect(Math.abs(model.derived.columnHeight - 12.703)).toBeLessThan(TOL);
expect(Math.abs(model.footings[0].top - 28.208)).toBeLessThan(TOL);
expect(Math.abs(model.derived.soilCover - 0.723)).toBeLessThan(TOL);
});
it('piles: 4 rows × 5 = 20, spacing 2250 mm, tip at 2.208 m', () => {
expect(model.piles).toHaveLength(20);
expect(model.derived.pileCount).toBe(20);
expect(Math.abs((model.derived.pileTipEl ?? NaN) - 2.208)).toBeLessThan(TOL);
const sValues = [...new Set(model.piles.map((p) => p.s.toFixed(4)))];
const nValues = [...new Set(model.piles.map((p) => p.n.toFixed(4)))];
expect(sValues).toHaveLength(5);
expect(nValues).toHaveLength(4);
expect(Number(nValues[1]) - Number(nValues[0])).toBeCloseTo(2.25, 4);
expect(Number(sValues[1]) - Number(sValues[0])).toBeCloseTo(2.25, 4);
});
it('blinding concrete 10600 × 8350 × 100 under the footing', () => {
const b = model.blindings[0];
expect(b.length).toBeCloseTo(10.6, 4);
expect(b.width).toBeCloseTo(8.35, 4);
expect(b.thickness).toBeCloseTo(0.1, 4);
});
it('footing 10400 × 8150 × 2000 mm', () => {
const f = model.footings[0];
expect(f.length).toBeCloseTo(10.4, 4);
expect(f.width).toBeCloseTo(8.15, 4);
expect(f.top - f.bottom).toBeCloseTo(2.0, 4);
});
});
describe('pile layout text (spec §12, §6.8 display)', () => {
it('reads 4@2250 × 3@2250 = 20본', () => {
expect(model.derived.pileLayout).toBe('4@2250 × 3@2250 = 20본');
});
});