Files
Aislo/resources/tester/test_ford_wall_vertical.mjs
T
eomsangdonandClaude Opus 5 0ef32b5279 chore(tester): 시험을 resources/tester/ 로 옮김 — 창끼리 건너가게
⚠ **뿌리** — `tmp/` 는 창 사이에 안 건너감(실측 확인: 상대 창이 놓은 `tmp/_sync_probe.txt`
가 시간을 두고 두 번 봐도 안 보임). 그래서 **정본(등록부 스키마)만 건너가고 그것을 읽는
시험은 안 건너가** 오늘 두 번, 같은 시험이 **연 창은 통과·받은 창은 실패**가 됐음.

- `tmp/tests/*` 를 `resources/tester/` 로 **복사**(127 파일). 내용은 **한 줄도 안 고침**
- `tmp/tests` 는 **남겨 둠** — 되돌릴 자리(사용자 지시)
- 실행: `./venv/Scripts/python.exe -m pytest resources/tester/ -q`
  옮기기 전과 **같은 수**: 617 통과 / 22 건너뜀 / 실패 0

⇒ 이제 시험·예외·까닭이 **정본과 함께** 움직임. 오늘 세운 「예외는 정본 스키마에」와 짝임.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 17:12:30 +09:00

96 lines
5.0 KiB
JavaScript

// 세월교 측벽 수직화(B06_Section_UI_Cross_Culvert_Basin `leanRatio`) 자체검증 — 로직 복제.
// 2026-08-30 사용자 확정: 세월교 측벽은 수직(교본 그림 3-18). 1:0.3 기움은 ㄴ형
// 집수정 부재를 재사용하며 딸려 온 값이라 세월교에서만 끈다(집수정은 그대로).
// 실행: node tmp/tests/test_ford_wall_vertical.mjs
import assert from "node:assert/strict";
const REVET_LEAN_RATIO = 0.3;
/* ── 복제: buildBasin의 벽·바닥판 좌표 산식 ─────────────────────────── */
function basinParts({ anchorOffset, anchorElevation, outward, wallHeight, memberT, floorT,
innerWidthM, leanRatio }) {
const lean = leanRatio ?? REVET_LEAN_RATIO;
const defaultBottom = anchorElevation - floorT;
const wallBase = anchorOffset + outward * (lean * wallHeight);
const wallOf = (baseOffset, dir, bottomElevation = defaultBottom) => {
const topShift = -dir * lean * wallHeight;
const spanZ = wallHeight + floorT;
const xAt = (elevation) => baseOffset + topShift * ((elevation - defaultBottom) / spanZ);
return [
{ offset: xAt(bottomElevation), elevation: bottomElevation },
{ offset: baseOffset + topShift, elevation: anchorElevation + wallHeight },
{ offset: baseOffset + topShift + dir * memberT, elevation: anchorElevation + wallHeight },
{ offset: xAt(bottomElevation) + dir * memberT, elevation: bottomElevation },
];
};
const wallOuterAt = (elevation) => {
const bottom = anchorElevation - floorT;
const t = (elevation - bottom) / (wallHeight + floorT);
return wallBase + outward * memberT - outward * lean * wallHeight * t;
};
const floorTopInner = wallOuterAt(anchorElevation);
const floorOuter = floorTopInner + outward * (innerWidthM + memberT);
const floorTaper = lean * floorT;
return {
wall: wallOf(wallBase, outward),
floor: [
{ offset: floorTopInner, elevation: anchorElevation },
{ offset: floorOuter, elevation: anchorElevation },
{ offset: floorOuter - outward * floorTaper, elevation: anchorElevation - floorT },
{ offset: wallOuterAt(anchorElevation - floorT), elevation: anchorElevation - floorT },
],
trimOffset: wallBase - outward * lean * wallHeight,
floorLengthM: Math.abs(floorOuter - floorTopInner),
};
}
const base = {
anchorOffset: 3.0, // 노견 끝
anchorElevation: 100.0, // 바닥판 상면
outward: 1, // 좌측
wallHeight: 1.5,
memberT: 0.3, // 벽 두께
floorT: 0.3, // 물받이 두께(교본 최소 0.3m)
innerWidthM: 1.2, // 날개벽 투영 연장
};
/* ── 세월교(leanRatio 0) — 벽이 수직이어야 한다 ─────────────────────── */
const ford = basinParts({ ...base, leanRatio: 0 });
const [b0, t0, t1, b1] = ford.wall;
assert.ok(Math.abs(t0.offset - b0.offset) < 1e-9, `벽 도로측 면이 안 섰다: ${t0.offset} vs ${b0.offset}`);
assert.ok(Math.abs(t1.offset - b1.offset) < 1e-9, `벽 계류측 면이 안 섰다: ${t1.offset} vs ${b1.offset}`);
// 벽은 노견 끝에서 그대로 내려간다 — 상단 자리(설계선 트림 경계)는 그대로.
assert.ok(Math.abs(t0.offset - base.anchorOffset) < 1e-9);
assert.ok(Math.abs(ford.trimOffset - base.anchorOffset) < 1e-9);
// 두께는 유지.
assert.ok(Math.abs(Math.abs(t1.offset - t0.offset) - base.memberT) < 1e-9);
// 바닥판 taper 0 = 직사각형(위·아래 바깥 모서리가 같은 offset).
assert.ok(Math.abs(ford.floor[1].offset - ford.floor[2].offset) < 1e-9, "바닥판 taper가 남았다");
assert.ok(Math.abs(ford.floor[0].offset - ford.floor[3].offset) < 1e-9, "바닥판 안쪽 변이 기울었다");
// 바닥 길이 = 날개벽 투영 연장 + 벽 두께(사용자 유지 지시).
assert.ok(
Math.abs(ford.floorLengthM - (base.innerWidthM + base.memberT)) < 1e-9,
`바닥 길이 어긋남: ${ford.floorLengthM}`,
);
/* ── 집수정(기본값) — 종전 1:0.3 기움 그대로여야 한다 ───────────────── */
const basin = basinParts(base);
const lean = REVET_LEAN_RATIO * base.wallHeight;
assert.ok(
Math.abs(basin.wall[1].offset - basin.wall[0].offset - -lean) < 1e-9,
"집수정 기움이 바뀌었다 — 집수정은 유지가 원칙",
);
assert.ok(
Math.abs(basin.floor[1].offset - basin.floor[2].offset) > 1e-9,
"집수정 바닥판 taper가 사라졌다",
);
// 집수정도 상단 도로측 꼭짓점은 노견 끝(트림 경계)에 있다 — 이 규칙은 공통.
assert.ok(Math.abs(basin.trimOffset - base.anchorOffset) < 1e-9);
/* ── 우측(outward -1)도 같은 규칙 ──────────────────────────────────── */
const right = basinParts({ ...base, outward: -1, leanRatio: 0 });
assert.ok(Math.abs(right.wall[1].offset - right.wall[0].offset) < 1e-9, "우측 벽이 안 섰다");
assert.ok(Math.abs(right.floorLengthM - (base.innerWidthM + base.memberT)) < 1e-9);
console.log("test_ford_wall_vertical.mjs OK");