Files
Aislo/resources/tester/test_277_1_haul_steps.py
T
eomsangdonandClaude Opus 5.5 f43a36aa39 feat(b09): 운반 단가 창 오른쪽 계산 칸 나눔 · 운반거리 칸 자동계산 단추 (277-1~4)
- 오른쪽 글 상자 → 칸 차례(거리 · 사이클 8-2-8 · 단가산출) · 칸마다 제목 · 몸 · 바닥 결과
- 사이클 칸 = Cm · 사이클시간 · t2 받는 로직만 · 조합 = 담은 로직 줄마다 미리보기 · 하위 산근 이어 붙임
- logic-preview 응답에 blocks(머리 · 호표 줄 · 계 · 출처) 더함 · 셈 · lines 그대로
- 값 칸 숫자 칸 = ui-input--sm(고르기 칸과 같은 높이) · 「거리에서」 → 「자동계산」 단추

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Se7ytqbohmBQnfYpwYFnYf
2026-10-12 18:25:05 +09:00

80 lines
4.2 KiB
Python

"""277 「운반 단가」 창 오른쪽 계산 칸 — 미리보기 `blocks`(머리 · 호표 줄 · 계 · 출처 · 하위 산근) ·
옛 `lines` · 단가 그대로 · 칸 고르기(운반거리만 = 거리 칸만 · Cm 받음 = 사이클 칸까지) ·
운반거리 칸 높이(`ui-input--sm`) · 「자동계산」 단추."""
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
from B08_Quantity.B08_Quantity_Haul_Cycle import FILL # noqa: E402
from B09_Estimation.B09_Estimation_Router import PreviewBody, logic_preview # noqa: E402
from B09_Estimation.B09_Estimation_Sangeun import _input_names # noqa: E402
GIVEN = {"재료": "토사", "운반거리": 23.877, "지역": "전국평균", "보정작업": "해당 없음"}
CYCLE_ONLY = {"Cm", "사이클시간", "t2"}
def _src(name: str) -> str:
return (ROOT / name).read_text(encoding="utf-8")
def test_미리보기_칸_GF000284(tmp_path):
got = logic_preview(tmp_path, PreviewBody(code="GF000284", given=GIVEN))
(block,) = got["blocks"] # 하위 산근 없음
assert block["logic"] == "GF000284" and block["source"] == "산림품셈 10-12-1"
assert block["unit"] == got["unit"] == "㎥"
assert block["price"] == got["price"] and got["price"] > 0
assert block["parts"] == got["parts"]
assert block["head"][0].startswith(block["name"]) and block["foot"].startswith("계 :")
assert any(h.startswith("Cmt = ") for h in block["head"]) # 중간값
names = [ln["name"] for ln in block["lines"]]
assert names == ["굴착기(무한궤도) 0.7㎥(적재)", "덤프트럭 15ton(운반)"]
truck = block["lines"][1]
assert truck["qty"] == 1.25 and truck["unit"] == "시간" and len(truck["text"]) == 3
assert set(truck) == {"name", "spec", "qty", "unit", "kind", "labor", "material", "expense",
"why", "text"} # fmt: skip
# 옛 글 줄 그대로 = 머리 + 줄 글 + 계
texts = [t for ln in block["lines"] for t in ln["text"]]
assert got["lines"] == [*block["head"], *texts, block["foot"]]
def test_칸_고르기_규칙():
def boxes(code: str) -> tuple[bool, bool]:
names = _input_names(code)
return any(n in FILL for n in names), any(n in CYCLE_ONLY for n in names)
assert boxes("GF000284") == (True, False) # 운반거리만 = 거리 칸만
assert boxes("GF000134") == (True, True) # Cm = 사이클 칸까지
modal = _src("B09_Estimation/B09_Estimation_UI_Haul_Modal.ts")
assert 'CYCLE_ONLY = new Set(["Cm", "사이클시간", "t2"])' in modal
assert "want.some((n) => CYCLE_ONLY.has(n)) ? [cycleBox(input)]" in modal
assert 'el("pre"' not in modal and "cycleLines" not in modal
# 조합 = 담은 로직 줄마다 미리보기 · 최신 응답만 · 하위 산근 이어 붙임 · 셈 중 옛 칸 흐리게
for want in ("st.lines.map((l) => ({ code: l.로직, given: libFilled(l)", "my !== seq",
'"하위 산근"', 'classList.add("is-stale")',
"조합 단가 = [적용] · [저장] 뒤 서버 셈"): # fmt: skip
assert want in modal, want
def test_칸_그리기_테마():
steps = _src("B09_Estimation/B09_Estimation_UI_Haul_Steps.ts")
for want in ("export function distBox", "export function cycleBox", "export function logicBox",
"export function splitHead", 'toLocaleString("ko-KR"', '"입력값"', '"중간값"',
'"호표"', "빈칸 — "): # fmt: skip
assert want in steps, want
css = _src("B09_Estimation/B09_Estimation_UI_Haul_Steps.css")
assert "#" not in css.replace("/*", "").split("*/", 1)[1] # 색 = 테마 변수만
assert "var(--color-danger)" in css and "text-align: right" in css
def test_운반거리_칸_높이_자동계산_단추():
values = _src("M02_MasterTemplete/M02_Labor_Values.ts")
assert '"ui-input ui-input--sm m02-inputval__control"' in values
modal = _src("B09_Estimation/B09_Estimation_UI_Haul_Modal.ts")
assert '"거리에서"' not in modal and 'AUTO = "자동계산"' in modal
for want in ("unown && o.dist", 'variant: "pill"', '"aria-pressed"', '"is-active"',
"st.own.delete(name);", "st.libOwn.delete(id);"): # fmt: skip
assert want in modal, want