Files
Aislo/resources/tester/test_b05_not_in_table_marks.py
T
eomsangdonandClaude Opus 5 0d4f46ecbe feat(b05·b08): 비탈면 녹화 ㎡ 넷(새심기·평떼·줄떼·비탈덮기) — 구간 사면 면적 × 대상 면 칸 · 떼 11매/3.33매(품셈 5-22-1·5-23-1) · 초류종자 살포는 공법에서 빼고 칸 밑 까닭 · 단 직고·선떼 급수 칸 기본값 없음(12장 D 녹화 · 브레인 ⓐ~ⓓ)
- 겹친 사면(초류종자살포·면고르기)은 자동으로 안 빼고 맨 앞 사유 · 평떼 떼꽂이 5-22-3 [주] 읽기 사유
- 혼합석 사유 정정: 토사 = B06 측점 토사 토글(구성비는 암 몫만) · 사전터파기 「산림품셈에 노면 사전 터파기 공종 없음 — 9-3-2 토사깍기(기계)로 이음」
- UnitQuantity 700줄 — 늦은 import 를 한 벌(_lazy)로

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
2026-09-15 05:30:32 +09:00

116 lines
4.5 KiB
Python

# -*- coding: utf-8 -*-
"""「칸은 있는데 표가 안 읽음」 — 등록부 칸 옆에 「아직 표에 안 쓰임」 (2026-09-14 브레인 차례 ①).
사용자가 값을 넣어도 수량·금액이 아무것도 안 바뀌는 칸. 사유를 표에만 두지 말고 칸 옆에도 보임
(브레인 판정 ③ 「B」). 표시가 참말인지 **값을 바꿔 돌려 보고** 지킴 — 표가 그 칸을 읽기 시작하면
여기서 깨지고, 그때 표시를 걷음(표시가 거짓말로 남지 않게).
"""
from __future__ import annotations
import json
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 B05_Profile.B05_Profile_Structures_Schema import structure_type_map # noqa: E402
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table # noqa: E402
#: 종류 → (표가 서는 기준 제원, 안 읽는 칸). 2026-09-14 값을 바꿔 전수 대조한 결과.
#: ⚠ 기초(foundation)·높이는 인계 구조물터파기 심도 구간이 읽어 뺌 · 단 수·올림·이동은 횡단도 칸이라 뺌.
MARKED: dict[str, tuple[dict, list[str]]] = {
"erosion_check": (
{"height_m": 2.0, "top_length_m": 6.0, "bottom_length_m": 4.0, "form": "돌"},
["thickness_top_m", "thickness_bottom_m", "stone_supply", "stone_coeff_basis"],
),
"bed_sill": (
{"area_m2": 10.0, "form": "돌붙임(찰)"},
["stone_supply", "stone_coeff_basis", "fill_concrete_mpa", "face_slope_ratio"],
),
"boulder_masonry": (
{"height_m": 2.5, "length_m": 10.0, "stone_cm": "60~80", "bond": "찰쌓기"},
[
"stone_supply",
"stone_coeff_basis",
"fill_concrete_mpa",
"weep_hole_diameter_mm",
"weep_hole_area_m2",
],
),
# 2026-09-15 녹화 ㎡ 넷 — 단 직고·선떼 급수는 길이형(선떼·조공) 산출식이 설 때 읽힘.
"revegetation": (
{"method": "평떼", "face": "양쪽", "b06_cut_area_m2": 40.0, "b06_fill_area_m2": 60.0},
["step_height_m", "sod_grade"],
),
"soil_guard": (
{"height_m": 1.0, "length_m": 10.0, "form": "떼"},
[
"thickness_top_m",
"thickness_bottom_m",
"back_len_cm",
"stone_kind",
"stone_supply",
"stone_coeff_basis",
"fill_concrete_mpa",
"face_slope_ratio",
"weep_hole_diameter_mm",
"weep_hole_area_m2",
],
),
}
FIELDS = (ROOT / "B05_Profile" / "B05_Profile_UI_Structures_Fields.ts").read_text(encoding="utf-8")
PANEL = (ROOT / "B05_Profile" / "B05_Profile_UI_Structures_Panel.ts").read_text(encoding="utf-8")
def _snapshot(type_id: str, options: dict) -> str:
structure = {
"structure_id": "p",
"type_id": type_id,
"start_m": 0.0,
"end_m": 10.0,
"chainage_m": 5.0,
"options": options,
}
table = build_table([structure], {}, {5.0: "both_fill"}, None, 0.2)
# 저장 제원을 그대로 되돌려 싣는 칸(`options`)은 뺌 — 값이 **표에 닿았는지**만 봄.
for row in table["structures"]:
row.pop("options", None)
return json.dumps(table, ensure_ascii=False, sort_keys=True, default=str)
def _probe_values(option) -> list:
if option.choices:
return list(option.choices)
return [0.73, 1.37] if option.input == "number" else ["x"]
@pytest.mark.parametrize("type_id", sorted(MARKED))
def test_등록부에_표시가_있다(type_id: str) -> None:
options = {option.key: option for option in structure_type_map()[type_id].options}
for key in MARKED[type_id][1]:
note = options[key].not_in_table
assert note and "아직 표에 안 쓰임" in note, f"{type_id}.{key}"
@pytest.mark.parametrize("type_id", sorted(MARKED))
def test_표시한_칸은_정말_안_읽힌다(type_id: str) -> None:
base, keys = MARKED[type_id]
options = {option.key: option for option in structure_type_map()[type_id].options}
reference = _snapshot(type_id, dict(base))
assert '"components": []' not in reference, "기준 제원으로 표가 안 섬 — 시험이 무의미"
for key in keys:
for value in _probe_values(options[key]):
assert _snapshot(type_id, {**base, key: value}) == reference, (
f"{type_id}.{key}={value!r} 로 표가 바뀜 — 이제 읽힘, 표시를 걷을 것"
)
def test_폼_칸_이름에_붙는다() -> None:
assert "not_in_table" in FIELDS and "not_in_table" in PANEL