Files
Aislo/resources/tester/test_845_1_doc_units.py
T
eomsangdonandClaude Opus 5.5 54d49c1a82 feat(845-1): 수식 문서 변수 단위 채움 — 원본 · 식 셈 · 금액 줄 역산 규칙 한 벌(변환 끝 · 금액 무관)
- 새 규칙 `master_doc_unit.fill` — 변환(`master_doc_convert.convert`) 끝에서 부름 · 빌더 · 실행 중 변환(SK 사본) 한 벌 · 보이는 변수 `단위` 칸만(연결 안 단위 · 셈 안 건드림)
- 근거: 표 값칸 단위 · 「줄 따름」 류 = 고를 수 있는 행 단위 한 가지 · 기계 칸 = 기계 표 단위(천원 · 10^-7/시간 · ℓ/hr · ㎾h/hr · % · 인/일) · 노임 원/일 · 재료 · 유가 원/단위 · 부른 문서 결과단위 · 식 셈(천원 × 1000 · % ÷ 100 · 2 배 안 보정 계수) · 금액 줄 역산(줄 단위 = 단가 단위일 때 더하기로만 이은 변수)
- 저장본 다시 지음: 1,520 문서 중 1,486 문서의 변수 단위 칸만 바뀜(채움 7,816 · 자리표시 「구분 따름」 · 「수」 · 나열 고침 982 · 표기 25) · 금액 대조 기본 1,520 같음 · 옵션 표본 18,873 중 다름 3 = 채택 1 원 셋 그대로
- 짐작은 안 채움(목록 tmp/845_1 · 시간환산 1/8 · 측량 직종 칸 · 식 속 수 상수 등)
- 지킴 시험 test_845_1: 다시 채워도 바뀔 단위 0 · 자리표시 0 · 금액 줄 단위 = 단가 단위 · 사용자 그림 문서 · 단위 셈

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-15 22:32:39 +09:00

103 lines
3.9 KiB
Python
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.
"""845-1 수식 문서 변수 단위 채움 지킴 시험 (요구 880).
① 저장본 1,520 문서 — 채움 규칙(`master_doc_unit.fill`)을 다시 돌려도 바뀔 단위 0
(단위 있어야 할 줄에 빈 단위 0 · 남긴 짐작 빼고).
② 단위 칸에 자리표시 · 「수」 글이 남지 않음 — 행마다 다른 단위는 「줄 따름」 한 표기.
③ 단가 단위(원/X)를 가진 금액 줄은 줄 단위 X 와 맞음(노임 원/일 = 인 · 「D/M」 글 둘 뺌).
④ 사용자가 본 문서 — GC000088 Q_시공 ㎥ · GC000267 기계 칸(천원 · 10^-7/시간 · ℓ/hr · % · 인/일)
· C_손료 원/시간.
⑤ 단위 셈 — 천원 × 1000 · % ÷ 100 · 보정 계수(0.85) · 단위 품은 수(× 8)는 못 셈.
"""
import copy
import importlib
import json
from fractions import Fraction
from pathlib import Path
import pytest
from M01_MasterData import M01_MasterData_Store as m01 # scripts 길을 둠
mu = importlib.import_module("master_doc_unit")
md = importlib.import_module("master_doc")
FOLDER = Path(__file__).resolve().parents[1] / "master_data/수식문서"
@pytest.fixture(scope="module")
def saved():
return {
d["키"]: d
for f in sorted(FOLDER.glob("수식_*.json"))
for d in json.loads(f.read_text(encoding="utf-8"))["줄"]
}
@pytest.fixture(scope="module")
def whole():
return m01.loaded()[1]
def test_다시_채워도_바뀔_단위_없음(saved, whole):
assert len(saved) == 1520
left = {k: mu.fill(copy.deepcopy(d), whole) for k, d in saved.items()}
assert {k: v for k, v in left.items() if v} == {}
def test_자리표시_수_글_안_남음(saved):
bad = [
(k, v["열쇠"], v["단위"])
for k, d in saved.items()
for v in d["변수"]
if v.get("단위") in (*mu.ROW_UNIT, *mu.NOT_UNIT) and v["단위"] != mu.ROW
]
assert bad == []
def test_금액_줄_단위_단가와_맞음(saved):
miss = []
for k, d in saved.items():
units = mu.known(d)
for line in d["금액"]:
price = str(line.get("단가") or "").strip()
got = units.get(price) if md.good_id(price) else None
if line.get("단위") in ("식", "D/M") or got in (None, mu._TEXTV):
continue
if not mu.line_ok(line, units):
miss.append((k, line["이름"], line["단위"]))
assert miss == []
def _units(doc):
return {md.var_id(v): v.get("단위") for v in doc["변수"]}
def test_사용자_본_문서(saved):
assert _units(saved["GC000088"])["Q_시공"] == "㎥"
got = _units(saved["GC000267"])
assert got["P_기계"] == "천원"
assert got["k_기계상각비"] == got["k_기계관리비"] == "10^-7/시간"
assert got["P_기계주연료"] == "ℓ/hr" and got["r_기계잡재료"] == "%"
assert got["Q_기계조종원"] == "인/일" and got["w_기계운전사"] == "원/일"
assert got["C_손료"] == "원/시간" and got["r_가산"] == "%"
assert got["Q_시간환산"] == "" # 1/8 · 16/12 · 25/20 = 원본 칸 단위 빈칸 → 짐작(사용자 판단)
def test_단위_셈():
u = {
"Q": (Fraction(1), {"㎥": 1}),
"r": (Fraction(1, 100), {}),
"P": (Fraction(1000), {"원": 1}),
"k": (Fraction(1, 10**7), {"시간": -1}),
"C": (Fraction(1), {"대": 1}),
"S": mu._TEXTV,
}
assert mu.infer("Q × (1 - 만약(S == 'a', 0, r) ÷ 100)", u)[0] == "㎥"
assert mu.infer("Q × 만약(S == 'a', 0.85, 1)", u)[0] == "㎥"
assert mu.infer("P × 1000 × ((k + k) × (1 + r ÷ 100) + k) ÷ 10000000", u)[0] == "원/시간"
assert mu.infer("만약(S == 'a', 0, r)", u)[0] == "%"
assert mu.infer("C × 8 ÷ Q", u)[0] is None # 8 = 시간/일 — 지어내지 않음
assert mu.infer("3.33 × 1.07", u)[0] is None
assert mu.infer("만약(S == 'a', '가', '나')", u)[0] == "글"
assert mu.parse("1일 1대당") is None and mu.parse("%(주연료비의)") == (Fraction(1, 100), {})