diff --git a/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts b/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts index 0cb5a3a2..da745045 100644 --- a/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts +++ b/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts @@ -9,7 +9,7 @@ * ========================================================================== */ import { FORD_MANNING_N, FORD_SLOPE } from "@config/config_frontend"; -import revetmentSabang from "../resources/master_data/ref/수량_사방기슭막이치수_사방기술교본_2026-01-01.json"; +import revetmentSabang from "../resources/data_masonry/revetment_sabang_2026-01-01.json"; /* ── 유입구 구조 ──────────────────────────────────────────────────────────── */ diff --git a/B06_Section/B06_Section_UI_Cross_Lean.ts b/B06_Section/B06_Section_UI_Cross_Lean.ts index 8804ea3a..e6daa9d8 100644 --- a/B06_Section/B06_Section_UI_Cross_Lean.ts +++ b/B06_Section/B06_Section_UI_Cross_Lean.ts @@ -1,6 +1,6 @@ /* ============================================================================= * B06_Section_UI_Cross_Lean.ts - * 횡단도 벽 전면 기울기 — 품셈 13-4-4 [주]⑪ 표준경사 표(`resources/master_data/old/3_품셈_산림_돌쌓기경사_*`)를 + * 횡단도 벽 전면 기울기 — 품셈 13-4-4 [주]⑪ 표준경사 표(`resources/data_masonry/masonry_slope_*`)를 * 읽는 자리 하나(2026-09-14 B5 · B08 과 한 벌). 표 읽기 식은 `common_util_masonry_slope.ts`(파이썬 짝). * * 따로 뗀 까닭 — 표(JSON)를 가져오는 모듈을 상수 파일에 두면 그 상수를 쓰는 기하 조각을 Node 로 @@ -10,7 +10,7 @@ * ========================================================================== */ import { type WallLeanInput, wallLeanRatio } from "../common_util/common_util_masonry_slope"; -import masonrySlope from "../resources/master_data/old/3_품셈_산림_돌쌓기경사_13-4-4_2026-01-01.json"; +import masonrySlope from "../resources/data_masonry/masonry_slope_2026-01-01.json"; /** 벽 전면 기울기 n — 표를 못 고르면 종전 0.3. */ export function leanOf(input: WallLeanInput): number { diff --git a/common_util/common_util_node_bundle.py b/common_util/common_util_node_bundle.py index ba14dae7..dcebdbfd 100644 --- a/common_util/common_util_node_bundle.py +++ b/common_util/common_util_node_bundle.py @@ -21,8 +21,8 @@ logger = logging.getLogger(__name__) ROOT = Path(__file__).resolve().parents[1] # 번들이 낡았는지 재는 대상 — 기하 계통이 걸쳐 있는 폴더 + 구조물도 식 풀이(B08, 2026-09-13). SOURCE_DIRS = ("B05_Profile", "B06_Section", "B08_Quantity", "common_util") -# 번들에 박히는 자료(JSON) — 벽 전면 기울기 표준경사 표(2026-09-14 B5). 표만 바뀌어도 다시 빌드. -SOURCE_DATA_DIRS = ("resources/master_data/old",) +# 번들에 박히는 자료(JSON) — 벽 전면 기울기 표준경사 표·기슭막이 치수 표(2026-09-14 B5). 표만 바뀌어도 다시 빌드. +SOURCE_DATA_DIRS = ("resources/data_masonry",) # 번들 만들기·실행 상한(초). 실측 번들 실행 0.1초, 빌드 3초 수준이라 넉넉하다. BUILD_TIMEOUT_S = 300 RUN_TIMEOUT_S = 600 diff --git a/old_code/resources/tester/test_b06_wall_lean_table.py b/old_code/resources/tester/test_b06_wall_lean_table.py deleted file mode 100644 index f914278e..00000000 --- a/old_code/resources/tester/test_b06_wall_lean_table.py +++ /dev/null @@ -1,142 +0,0 @@ -# -*- coding: utf-8 -*- -"""B06 벽 전면 기울기도 **품셈 표준경사 표**를 읽음 — B5 (2026-09-14 브레인 판정 「양쪽 다 이 표를」). - -앞서 B06 횡단도는 벽(관 유입·유출 · 독립 기슭막이 · 다단 추가 · C군 벽)을 **1:0.3 붙박이**로 그렸고 -B08 은 품셈 13-4-4 [주]⑪ 표(원문 L7185~7191)로 셈 — 메쌓기 성토 H2.5 에서 1:0.3 ↔ 1:0.35 로 갈림. - -재는 것(브레인: 고치기 전 코드에서 빨강부터) - ① 네 갈래 — 직고 구간 × 성토/절토 × 메/찰 (+ 사용자 칸 `face_slope_ratio`·`face_role`, 못 가르면 종전 0.3) - TS 짝 `common_util_masonry_slope.ts` 을 실제로 돌려 파이썬 `face_slope_ratio` 와 한 칸씩 대조. - ② 기하가 그 값을 씀 — 벽 모양 파일에서 붙박이 `REVET_LEAN_RATIO` 곱이 사라지고 벽마다 기울기를 받음. -""" - -from __future__ import annotations - -import itertools -import json -import re -import shutil -import subprocess -import sys -from pathlib import Path - -import pytest - -ROOT = Path(__file__).resolve().parents[2] -if str(ROOT) not in sys.path: - sys.path.insert(0, str(ROOT)) - -from B08_Quantity.B08_Quantity_Engine_UnitQuantity_StoneSpec import ( # noqa: E402 - face_slope_ratio, - load_slope_table, -) -from common_util.common_util_structure_face_role import structure_face_role_of # noqa: E402 - -TSC = ROOT / "config" / "node_modules" / "typescript" / "bin" / "tsc" -TS_FILE = ROOT / "common_util" / "common_util_masonry_slope.ts" - -FORMS = ("돌쌓기(찰)", "돌쌓기(메)", "콘크리트") -HEIGHTS = (1.0, 1.5, 2.5, 3.0, 4.0, 6.0, 7.5) -MODES = ("left_cut", "right_cut", "both_cut", "both_fill", None) -SIDES = (None, "자동(성토 쪽)", "좌", "우", "양쪽") -OVERRIDES = ({}, {"face_role": "절토"}, {"face_slope_ratio": 0.5}) - -_RUNNER = """ -const { readFileSync, writeFileSync } = require("node:fs"); -const { wallLeanRatio } = require("./common_util_masonry_slope.js"); -const input = JSON.parse(readFileSync(process.argv[2], "utf8")); -const out = input.cases.map((c) => wallLeanRatio(input.table, c)); -writeFileSync(process.argv[3], JSON.stringify(out)); -""" - - -def _cases() -> list[dict]: - cases = [] - for form, height, mode, side, extra in itertools.product( - FORMS, HEIGHTS, MODES, SIDES, OVERRIDES - ): - cases.append( - {"form": form, "height_m": height, "section_mode": mode, "side": side, **extra} - ) - return cases - - -def _python(case: dict) -> float: - """B08 이 그 벽을 셀 때의 기울기 — 돌쌓기 형태만 표, 나머지는 종전 0.3.""" - wet = {"돌쌓기(찰)": True, "돌쌓기(메)": False}.get(case["form"]) - if wet is None: - return 0.3 - options = {k: case[k] for k in ("side", "face_role", "face_slope_ratio") if k in case} - face, reason = structure_face_role_of(case["section_mode"], options) - ratio, _basis = face_slope_ratio( - options, wet=wet, height_m=case["height_m"], face=face, face_reason=reason - ) - return ratio - - -@pytest.mark.skipif(shutil.which("node") is None or not TSC.is_file(), reason="node·tsc 없음") -def test_네_갈래_표를_TS_가_파이썬과_같게_읽는다(tmp_path: Path) -> None: - assert TS_FILE.is_file(), "TS 짝이 아직 없음 — B06 이 표를 안 읽는다" - out = tmp_path / "js" - subprocess.run( # noqa: S603 — 고정 실행 파일 - [ - "node", - str(TSC), - str(TS_FILE), - "--outDir", - str(out), - "--module", - "commonjs", - "--target", - "es2022", - "--ignoreConfig", - ], - cwd=str(ROOT), - check=True, - capture_output=True, - ) - (out / "runner.cjs").write_text(_RUNNER, encoding="utf-8") - cases = _cases() - payload = tmp_path / "in.json" - result = tmp_path / "out.json" - payload.write_text( - json.dumps({"table": load_slope_table(), "cases": cases}, ensure_ascii=False), - encoding="utf-8", - ) - subprocess.run( # noqa: S603 - ["node", str(out / "runner.cjs"), str(payload), str(result)], - cwd=str(ROOT), - check=True, - capture_output=True, - ) - got = json.loads(result.read_text(encoding="utf-8")) - wrong = [ - (case, ts, _python(case)) - for case, ts in zip(cases, got, strict=True) - if abs(ts - _python(case)) > 1e-9 - ] - assert not wrong, wrong[:5] - # 갈래가 실제로 갈렸는지 — 한 값만 나와 같아지는 것을 막음(메 성토 H2.5 0.35 · 찰 절토 H1.0 0.2) - assert {round(v, 2) for v in got} >= {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5} - - -GEOMETRY = [ - "B06_Section_UI_Cross_Culvert_Geom.ts", - "B06_Section_UI_Cross_Wall.ts", - "B06_Section_UI_Cross_Culvert_Extra.ts", - "B06_Section_UI_Cross_Culvert_Solve.ts", -] - - -def test_횡단도가_최신_표준경사_판을_읽는다() -> None: - const = (ROOT / "B06_Section" / "B06_Section_UI_Cross_Lean.ts").read_text(encoding="utf-8") - latest = sorted((ROOT / "resources" / "master_data" / "old").glob("3_품셈_산림_돌쌓기경사_*.json"))[-1].name - imported = re.search(r'from "\.\./resources/master_data/old/(3_품셈_산림_돌쌓기경사_[^"]+)"', const) - assert imported and imported.group(1) == latest - - -def test_벽_모양이_붙박이_기울기를_안_곱한다() -> None: - """벽 모양 파일마다 `REVET_LEAN_RATIO *` 곱이 남아 있으면 그 벽은 아직 1:0.3 붙박이.""" - for name in GEOMETRY: - source = (ROOT / "B06_Section" / name).read_text(encoding="utf-8") - assert not re.search(r"REVET_LEAN_RATIO\s*[*/]", source), name diff --git a/resources/master_data/old/3_품셈_산림_돌쌓기경사_13-4-4_2026-01-01.json b/resources/data_masonry/masonry_slope_2026-01-01.json similarity index 100% rename from resources/master_data/old/3_품셈_산림_돌쌓기경사_13-4-4_2026-01-01.json rename to resources/data_masonry/masonry_slope_2026-01-01.json diff --git a/resources/master_data/ref/수량_사방기슭막이치수_사방기술교본_2026-01-01.json b/resources/data_masonry/revetment_sabang_2026-01-01.json similarity index 100% rename from resources/master_data/ref/수량_사방기슭막이치수_사방기술교본_2026-01-01.json rename to resources/data_masonry/revetment_sabang_2026-01-01.json diff --git a/resources/master_data/ref/_분석_B05B06_옛자료.md b/resources/master_data/ref/_분석_B05B06_옛자료.md new file mode 100644 index 00000000..25929514 --- /dev/null +++ b/resources/master_data/ref/_분석_B05B06_옛자료.md @@ -0,0 +1,119 @@ +# B05·B06 이 old/·ref 파일 여섯을 읽는 진짜 까닭 + +읽기 전용 분석 — 코드·데이터 하나도 안 고침. + +`ref/_분석_안쓰는마스터.md`(sub1)가 「B05·B06 이 old/·ref 파일 여섯을 읽음」이라 적은 것을 한 줄 한 줄 +따라가 다시 봄. **결론부터 — 여섯 가운데 실제로 B05·B06 화면을 돌리는 건 둘뿐**이고, 나머지 넷은 +B08·B09(끊긴 옛 코드)만 쓰는 것을 sub1 이 잘못 묶은 것. + +## 파일 하나씩 + +### ① `old/2_공종_건설_마스터_2026-01-01.json` · `old/2_공종_산림_마스터_2026-01-01.json` + +- **읽는 코드** — `common_util/common_util_work_item_key.py` 41째 줄(`MASTER_DIR.glob("2_공종_*_마스터_*.json")`). + 이 모듈을 실제로 부르는 곳은 `old_code/B08_Quantity/B08_Quantity_Engine_Handoff.py` 254째 줄과 + `old_code/B09_Estimation/B09_Estimation_BillOfQuantities_Input.py` 뿐 — **B05·B06 코드 어디에도 + `common_util_work_item_key` 를 부르는 줄이 없음**(직접 검색해 확인). +- **B05·B06 과 닿는 유일한 자리** — `common_util_node_bundle.py` 가 `resources/master_data/old/` 의 + `*.json` **수정 시각**을 통째로 지켜봄(내용은 안 읽음·「낡음」 판정만). 이 파일도 그 34개 가운데 + 하나라 시각은 보이지만, **화면에 쓰이는 값은 하나도 없음**. +- **언제 들어왔나** — 파일 자체는 2026-09-17 커밋 `642a5be9`(건설)·`8f3a01cd`(work_item_key.py) — + 제목 그대로 **B08 인계 출구·B09 인계 입구 두 곳에서만 쓰려고 만든 것**(B08·B09 작업 중 생김, 사용자 말과 일치). + 2026-09-19 `0e6412fe` 로 `master_data/` 첫 층에서 `old/` 로 옮겨짐(B05·B06 과는 무관한 정리). +- **안 읽으면** — B05·B06 은 **아무 일도 없음**(원래 안 읽으므로). old_code 의 B08·B09 인계 계산이 + 다시 붙을 때만 문제(지금은 라우터가 끊겨 안 돌아감). +- **갈래 — ㉮ 그냥 걷어도 됨**(B05·B06 기준). + +### ② `old/2_공종_산림건설_연결_2026-01-01.json` + +- **읽는 코드** — `common_util/common_util_work_item_link.py` 42째 줄(`FOLDER.glob("2_공종_산림건설_연결_*.json")`). + 부르는 곳은 `old_code/B09_Estimation/B09_Estimation_BillOfQuantities_Input.py`· + `B09_Estimation_BillOfQuantities.py` 뿐 — 역시 B05·B06 은 안 부름. +- **언제** — 2026-09-17 `06e1f4ef` — 「산림·건설 어느 품을 쓸지 표가 정함」, B09 인계 규칙(사용자 말과 일치). +- **안 읽으면** — B05·B06 무관. old_code B09 재연결 때만 문제. +- **갈래 — ㉮ 그냥 걷어도 됨**(B05·B06 기준). + +### ③ `old/3_품셈_산림_돌쌓기경사_13-4-4_2026-01-01.json` + +- **읽는 코드** — `B06_Section_UI_Cross_Lean.ts` 13째 줄이 이 파일을 바로 import 해 `leanOf()` 함수를 + 만듦(16~18째 줄). 그 함수를 `B06_Section_UI_Cross_Culvert_Geom.ts`(178·629째 줄)와 + `B06_Section_UI_Cross_Revetment.ts`(201·291째 줄)가 불러 씀. +- **화면에 쓰는 자리** — 횡단도(단면도)에서 **관 유입·유출부·독립 기슭막이·다단 벽**을 그릴 때 벽 + 전면의 기울기(1:n)를 정함 — 품셈 13-4-4 [주]⑪ 「돌쌓기 표준경사」 표(직고 4단계 × 성토/절토 × + 메쌓기/찰쌓기 = 16칸). **사용자에게 보이는 것은 횡단도 벽의 실제 기울어진 모양 그 자체**임. +- **언제 들어왔나(중요)** — 기능은 2026-09-14 커밋 `0e609e69` 로 처음 생겼는데, 그때 import 경로는 + `resources/data_masonry/masonry_slope_2026-01-01.json` — **B08·B09 와 무관한 이 기능만의 전용 폴더**였음. + 2026-09-19 커밋 `ebd148c4`(제목 「옛 자료 폴더 이동 뒤 서버 불러오기 복구」)가 `data_masonry/` 를 + 통째로 `master_data/old/` 로 옮기는 정리를 하면서 import 경로만 기계적으로 따라 고침 — + **B08·B09 를 만들며 들어간 게 아니라, B08·B09 정리(사용자 말 그대로) 때 엉뚱하게 같이 쓸려 들어간 것**. +- **안 읽으면** — 파일이 없어지면 TS import 가 못 찾아 **번들 빌드 자체가 깨짐**(횡단도를 그리는 화면 + 코드 전체가 안 뜸) — 이 파일이 있는데 표에 맞는 칸이 없을 때만 코드가 「종전 0.3」 으로 조용히 + 후퇴함(주석 확인) — 어느 쪽이든 심각. +- **마스터로 갈음되는지** — `계수_산림품셈_13장_구조물.json` 안에 13-4-4 표가 이미 있으나(CF000140) + 그건 **주④⑤⑥⑦⑨**(줄눈메꿈·물구멍·뒷채움) 표이고, 이 파일이 쓰는 건 **주⑪ 표준경사**(다른 절) — + **지금 마스터는 이 표를 안 가지고 있음. 갈음 안 됨.** +- **갈래 — ㉰ 걷으면 기능이 없어짐**(화면 자체가 못 뜸). 지킬 파일. +- **덤 — 지킴 시험도 같이 쓸려 들어감** — `resources/tester/test_b06_wall_lean_table.py` 가 + 이 표의 최신 판을 대조하는 시험인데, `old_code/B08_Quantity_Engine_UnitQuantity_StoneSpec` 을 + 같이 읽는 바람에(B08 쪽 대조도 겸함) `old_code/resources/tester/` 로 함께 옮겨져 **지금은 안 돌아감** + — B06 쪽 지킴이 비어 있음. + +### ④ `ref/공종_자원별칭_실무_2026-01-01.json` + +- **읽는 코드** — `common_util/common_util_aliases.py` 29째 줄. +- **부르는 곳** — 전부 `old_code/`(B08_Quantity_Engine_Handoff_Mapping · B09_Estimation_UnitPrice · + ResourceAxis_Join · MachineProductivity 계열) + `resources/tester/test_b09_fuel_kind_vibrator.py` · + `resources/tester/test_b08_root_removal_excavator.py` 둘. **B05·B06 화면 코드는 전혀 안 부름.** +- **⚠ 그 시험 둘은 지금 이미 깨져 있음** — 실제로 `pytest --collect-only` 로 돌려 확인: + `ModuleNotFoundError: No module named 'B09_Estimation.B09_Estimation_UnitPrice'`(B08 도 같은 증상). + B08·B09 가 `old_code/` 로 옮겨간 뒤 이 시험 둘의 import 만 안 고쳐져 지금은 **아예 실행이 안 됨** — + sub1 문서의 「시험이 지킴」은 이제 사실이 아님(시험이 죽어서 지키는 게 없음). +- **갈래 — ㉮ 그냥 걷어도 됨**(B05·B06 기준). 단 시험 둘은 이 파일과 무관하게 이미 고장 나 있어 + 별도 정리 필요(이 일감 범위 밖 — 한 줄만 남김). + +### ⑤ `ref/수량_사방기슭막이치수_사방기술교본_2026-01-01.json` + +- **읽는 코드** — `B05_Profile_UI_Drainage_Facility_Fields.ts` 12째 줄이 바로 import. + 256~268째 줄 `sabangBasisLines()` 가 이 표에서 「높이 규칙·계획비탈 표준비·둑마루 두께 기준· + 뒷채움 조약돌 두께」 네 줄을 뽑아 문장으로 만듦. +- **화면에 쓰는 자리** — `createRevetSideGroup()`(270~301째 줄)이 이 문장을 **독립 기슭막이 입력칸 + 바로 밑에 안내문(근거)으로 보여줌** — 계산에 쓰이는 수치가 아니라 **사용자가 값을 넣을 때 보는 + 설명 문구**. `B05_Profile_UI_Drainage_Facility.ts`(본체 폼)가 이 조각을 불러 써서 실제 화면에 붙음. +- **언제 들어왔나** — 기능은 2026-09-14 `ad63dd8f`(제목에 `feat(b05,b06,b08)` — B05 화면 근거와 + B08 사유가 「같은 파일」을 보게 지었다고 명시)로 생겼고, 그때 경로는 `resources/data_masonry/ + revetment_sabang_2026-01-01.json` — 전용 폴더. 2026-09-19 `ebd148c4`(③과 같은 커밋)가 `master_data/ref/` + 로 옮기며 경로만 고침. **B05 몫으로 함께 설계된 파일이 정리 때 ref/ 로 쓸려 들어간 것.** +- **안 읽으면** — 파일이 없으면 TS import 가 못 찾아 **B05 배수시설 서브폼 빌드가 깨짐**(계곡 통과 + 시설 입력 화면 전체가 못 뜸). 있어도 삭제하면 근거 문구 네 줄이 사라짐 — 계산 값 자체는 안 + 바뀌지만 「왜 이 값을 제안하는지」 사용자가 못 봄. +- **마스터로 갈음되는지** — 지금 마스터에 「독립 기슭막이 근거」에 해당하는 표가 없음(품셈이 아니라 + **사방기술교본**이 원출처라 산림품셈 계수·소요량 파일에 안 실림). 갈음 안 됨. +- **갈래 — ㉰ 걷으면 기능이 없어짐**. 지킬 파일. +- **덤 — 지킴 시험도 함께 쓸려 들어감** — `resources/tester/test_b05_revetment_sabang_basis.py` 도 + `old_code/B08_Quantity_Engine_Pipe` 를 같이 읽어(B08 사유 대조 겸함) `old_code/resources/tester/` 로 + 옮겨짐 — 지금은 안 돌아가 B05 쪽 지킴도 비어 있음. + +## 한 줄 요약표 + +| 파일 | B05·B06 이 실제로 읽나 | 언제·왜 들어왔나 | 갈래 | +|---|---|---|---| +| 공종_건설_마스터 · 공종_산림_마스터 | 아니오(old_code 만) | 09-17 B08·B09 인계용으로 만듦 | ㉮ 걷어도 됨 | +| 공종_산림건설_연결 | 아니오(old_code 만) | 09-17 B09 인계 규칙 | ㉮ 걷어도 됨 | +| 돌쌓기경사_13-4-4(품셈 표준경사) | **예 — B06 횡단도 벽 기울기** | 09-14 전용 폴더에서 만듦 → 09-19 old/ 로 쓸려 옮겨짐 | ㉰ 못 걷음 | +| 공종_자원별칭_실무 | 아니오(old_code + 죽은 시험 2개) | — | ㉮ 걷어도 됨 | +| 수량_사방기슭막이치수 | **예 — B05 근거 문구** | 09-14 전용 폴더에서 만듦 → 09-19 ref/ 로 쓸려 옮겨짐 | ㉰ 못 걷음 | + +## 걷는 차례 제안 + +1. **먼저** — 공종_건설_마스터·공종_산림_마스터·공종_산림건설_연결·공종_자원별칭_실무 넷은 B05·B06 과 + 무관하니 이 넷 때문에 `old/`·`ref/` 를 못 건드릴 이유는 없음(다른 일감의 old/ 정리 그대로 진행 가능). +2. **돌쌓기경사·사방기슭막이치수 둘은 자리를 옮김** — `old/`·`ref/`(정리 대상 폴더) 밖에 전용 자리를 + 새로 줌(예: 옛 이름 그대로 `resources/data_masonry/` 되살리기, 또는 `resources/master_data/` 안에 + 「old 아님」이 분명한 이름). 옮길 때 고칠 곳 — TS import 경로 2줄(`B06_Section_UI_Cross_Lean.ts` 13째, + `B05_Profile_UI_Drainage_Facility_Fields.ts` 12째) · `common_util_node_bundle.py` 의 + `SOURCE_DATA_DIRS`(새 폴더도 보게). +3. **죽은 지킴 시험 둘을 살림** — `test_b06_wall_lean_table.py`·`test_b05_revetment_sabang_basis.py` 를 + `old_code/resources/tester/` 에서 `resources/tester/` 로 되돌리고, B08 쪽만 읽는 줄(대조 부분)은 + 빼거나 손봐 **B05·B06 몫만** 다시 돌게 함 — 지금은 이 표가 바뀌어도 아무 시험도 안 잡아 줌. +4. 이 순서대로 하면 `old/`·`ref/` 안에 더는 B05·B06 이 읽는 파일이 없어져, 남은 정리(PLAN 7-4·7-5)를 + B05·B06 걱정 없이 진행할 수 있음. diff --git a/old_code/resources/tester/test_b05_revetment_sabang_basis.py b/resources/tester/test_b05_revetment_sabang_basis.py similarity index 51% rename from old_code/resources/tester/test_b05_revetment_sabang_basis.py rename to resources/tester/test_b05_revetment_sabang_basis.py index 8b22c4a3..c0071504 100644 --- a/old_code/resources/tester/test_b05_revetment_sabang_basis.py +++ b/resources/tester/test_b05_revetment_sabang_basis.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- -"""독립 기슭막이 치수 한 벌 — B05 칸 밑 근거와 B08 사유가 **같은 파일**을 읽음 (2026-09-14 브레인 판정). +"""독립 기슭막이 치수 — B05 칸 밑 근거가 표(`resources/data_masonry/revetment_sabang_*.json`)를 읽음. -한 자리 = `resources/data_masonry/수량_사방기슭막이치수_*.json`. TS 는 판 이름을 import 로 박으므로 판이 -바뀌면 import 도 옮겨야 함 — 여기서 최신 판과 대조. 쪽·줄 번호가 사유에 그대로 실리는지도 봄. +2026-09-22 sub1: B08 쪽 사유 대조(`B08_Quantity_Engine_Pipe.own_revetment_basis` 등)는 B08 이 +`old_code/` 로 끊기며 같이 죽었음 — 그 대조 시험은 빼고, **B05 몫**(TS 가 최신판을 읽는지 · +그 판이 쓰는 칸이 실제로 있는지 · 높이 칸이 제안 없이 설계자 입력인지)만 되살림. """ from __future__ import annotations @@ -16,12 +17,7 @@ ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) -from B08_Quantity.B08_Quantity_Engine_Pipe import ( # noqa: E402 - own_height_unconfirmed, - own_revetment_basis, -) - -DATA_DIR = ROOT / "resources" / "master_data" / "ref" +DATA_DIR = ROOT / "resources" / "data_masonry" FIELDS = (ROOT / "B05_Profile" / "B05_Profile_UI_Drainage_Facility_Fields.ts").read_text( encoding="utf-8" ) @@ -29,13 +25,13 @@ CHROME = (ROOT / "B06_Section" / "B06_Section_UI_Cross_Card_Chrome.ts").read_tex def test_TS_가_최신_판을_읽는다() -> None: - latest = sorted(DATA_DIR.glob("수량_사방기슭막이치수_*.json"))[-1].name - imported = re.search(r'from "\.\./resources/master_data/ref/(수량_사방기슭막이치수_[^"]+)"', FIELDS) + latest = sorted(DATA_DIR.glob("revetment_sabang_*.json"))[-1].name + imported = re.search(r'from "\.\./resources/data_masonry/(revetment_sabang_[^"]+)"', FIELDS) assert imported and imported.group(1) == latest def test_TS_가_쓰는_칸이_파일에_있다() -> None: - latest = sorted(DATA_DIR.glob("수량_사방기슭막이치수_*.json"))[-1] + latest = sorted(DATA_DIR.glob("revetment_sabang_*.json"))[-1] data = json.loads(latest.read_text(encoding="utf-8")) items = data["items"] assert data["scope"] and "사방(계류) 교본 기준" in data["scope"] @@ -45,13 +41,6 @@ def test_TS_가_쓰는_칸이_파일에_있다() -> None: assert "L7164" in items["backfill_pebble"]["source"] -def test_B08_사유가_같은_근거를_쪽_줄_번호로() -> None: - basis = own_revetment_basis() - for ref in ("2-나:141", "3-가:181", "2-나:129", "3-가:151", "2-나:143", "L7164~7171"): - assert ref in basis, ref - assert "2-나:141" in own_height_unconfirmed() - - def test_B05_높이_칸은_제안_없이_설계자_입력() -> None: assert 'height: "",' in FIELDS and '"설계자 입력"' in FIELDS assert "기슭막이 높이 없음 — 근입만 그림" in CHROME diff --git a/resources/tester/test_b06_wall_lean_table.py b/resources/tester/test_b06_wall_lean_table.py new file mode 100644 index 00000000..49e018f9 --- /dev/null +++ b/resources/tester/test_b06_wall_lean_table.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +"""B06 벽 전면 기울기도 **품셈 표준경사 표**를 읽음 — B5 (2026-09-14 브레인 판정 「양쪽 다 이 표를」). + +2026-09-22 sub1: B08 쪽 파이썬 대조(`B08_Quantity_Engine_UnitQuantity_StoneSpec`)는 B08 이 +`old_code/` 로 끊기며 같이 죽었음 — 그 대조 시험은 빼고, **B06 몫**(표 경로가 최신판인지 · +벽 모양이 붙박이 기울기를 더는 안 곱하는지)만 되살림. +""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +if str(ROOT) not in sys.path: + sys.path.insert(0, str(ROOT)) + +DATA_DIR = ROOT / "resources" / "data_masonry" + +GEOMETRY = [ + "B06_Section_UI_Cross_Culvert_Geom.ts", + "B06_Section_UI_Cross_Wall.ts", + "B06_Section_UI_Cross_Culvert_Extra.ts", + "B06_Section_UI_Cross_Culvert_Solve.ts", +] + + +def test_횡단도가_최신_표준경사_판을_읽는다() -> None: + const = (ROOT / "B06_Section" / "B06_Section_UI_Cross_Lean.ts").read_text(encoding="utf-8") + latest = sorted(DATA_DIR.glob("masonry_slope_*.json"))[-1].name + imported = re.search(r'from "\.\./resources/data_masonry/(masonry_slope_[^"]+)"', const) + assert imported and imported.group(1) == latest + + +def test_벽_모양이_붙박이_기울기를_안_곱한다() -> None: + """벽 모양 파일마다 `REVET_LEAN_RATIO *` 곱이 남아 있으면 그 벽은 아직 1:0.3 붙박이.""" + for name in GEOMETRY: + source = (ROOT / "B06_Section" / name).read_text(encoding="utf-8") + assert not re.search(r"REVET_LEAN_RATIO\s*[*/]", source), name