Files
Pier_v1/tests/parse.test.ts
T
ypshimandClaude Haiku 5.5 68e56d1037 feat(input): use RAG/운곡교P1입력.xlsx as the P1 input
- public/samples/운곡교P1입력.xlsx is a byte copy of RAG/운곡교P1입력.xlsx
- loadP1 and the sample loader read the three-sheet input
- spec workbook (intent.PR) stays for the single-sheet regression tests
- test: input file has sheets 교각 · IP · 받침 and parses to P1 with no issues

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

105 lines
4.3 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 * as XLSX from 'xlsx';
import { describe, expect, it } from 'vitest';
import { parseWorkbook } from '../src/core/parseWorkbook';
import { loadInputWorkbook, loadP1, loadWorkbook } from './helpers';
describe('parseWorkbook (P1 sheet intent.PR)', () => {
it('finds exactly one pier P1 with the input values of the sheet', () => {
const { piers, issues } = parseWorkbook(loadWorkbook());
expect(issues).toEqual([]);
expect(piers.map((p) => p.name)).toEqual(['P1']);
const p1 = loadP1();
expect(p1.type).toBe('T형');
expect(p1.foundationType).toBe('말뚝기초');
expect(p1.copingTopEl).toBeCloseTo(43.411, 6);
expect(p1.footingBottomEl).toBeCloseTo(26.208, 6);
expect(p1.groundEl).toBeCloseTo(28.931, 6);
expect(p1.pileLengthMm).toBe(24000);
expect(p1.copingWidthMm).toBe(3100);
expect(p1.copingLengthMm).toBe(12000);
expect(p1.columnCount).toBe(1);
});
it('reads 4 IP points and 10 bearings (5 front, 5 back)', () => {
const p1 = loadP1();
expect(p1.ips.map((p) => p.name)).toEqual(['IP1', 'IP2', 'IP3', 'IP4']);
expect(p1.bearings).toHaveLength(10);
expect(p1.bearings.filter((b) => b.row === '전열')).toHaveLength(5);
expect(p1.bearings.filter((b) => b.row === '후열')).toHaveLength(5);
});
it('converts the bearing azimuth strings to decimal degrees', () => {
const p1 = loadP1();
expect(p1.bearings[0].azimuthDeg).toBeCloseTo(75.9489, 4);
});
});
describe('sheet report (spec §2.3)', () => {
it('marks the P1 sheet as selectable and counts its tables', () => {
const { sheets } = parseWorkbook(loadWorkbook());
expect(sheets).toHaveLength(1);
expect(sheets[0]).toMatchObject({ name: 'intent.PR', ok: true, piers: 1, tables: { pier: 1, ip: 1, bearing: 1 } });
});
it('marks a sheet with a bad azimuth (E03) as not selectable and drops its pier', () => {
const wb = loadWorkbook();
wb.Sheets['intent.PR']['F32'].v = '75.9';
const { piers, sheets, issues } = parseWorkbook(wb);
expect(issues.map((i) => i.code)).toContain('E03');
expect(sheets[0].ok).toBe(false);
expect(piers).toHaveLength(0);
});
});
describe('tables split across sheets (spec §2.2: 시트 1장 = 교각 1기)', () => {
it('reports E05 and drops the pier when the IP table is not on the same sheet', () => {
const wb = loadWorkbook();
wb.Sheets['intent.PR']['B25'].v = '기타';
const { piers, sheets, issues } = parseWorkbook(wb);
expect(issues.map((i) => i.code)).toContain('E05');
expect(piers).toHaveLength(0);
expect(sheets[0].ok).toBe(false);
});
});
describe('three-sheet input (교각 · IP · 받침 on separate sheets, joined by 교각명)', () => {
/** Splits the P1 sheet into the three sheets the user prepares: rows 22–23, 25–29, 31–41 (1-based). */
function threeSheets(): XLSX.WorkBook {
const src = loadWorkbook();
const grid = XLSX.utils.sheet_to_json<(string | number | null)[]>(src.Sheets['intent.PR'], {
header: 1,
raw: true,
defval: null,
});
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(grid.slice(21, 23)), '교각');
XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(grid.slice(24, 29)), 'IP');
XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(grid.slice(30, 41)), '받침');
return wb;
}
it('joins the three sheets into one pier with 4 IP points and 10 bearings', () => {
const { piers, issues, sheets } = parseWorkbook(threeSheets());
expect(issues).toEqual([]);
expect(piers).toHaveLength(1);
expect(piers[0]).toMatchObject({ name: 'P1', sheet: '교각' });
expect(piers[0].ips).toHaveLength(4);
expect(piers[0].bearings).toHaveLength(10);
expect(sheets.map((s) => [s.name, s.ok, s.piers])).toEqual([
['교각', true, 1],
['IP', true, 0],
['받침', true, 0],
]);
});
});
describe('user input file (RAG/운곡교P1입력.xlsx)', () => {
it('has the three sheets 교각 · IP · 받침 and parses to one pier, P1, with no issues', () => {
const wb = loadInputWorkbook();
expect(wb.SheetNames).toEqual(['교각', 'IP', '받침']);
const { piers, issues } = parseWorkbook(wb);
expect(issues).toEqual([]);
expect(piers.map((p) => [p.name, p.sheet])).toEqual([['P1', '교각']]);
});
});