"""801-5 M01 로직 단위 글 = 건설품셈 원문 꼴(요구 663-2) 지킴 — 글만 바꿈 · 금액 그대로. ① 대응표 근거 — 규칙마다 근거 절 파일이 있고 그 안에 원문 글이 실제로 있음(+ 지금 글은 같은 꼴로 안 쓰임) ② 섞임 0 — M01 로직 입력 · 중간 · 결과단위가 원문 꼴로 다 바뀌어 있음(규칙이 더 바꿀 것 없음 · 두 번 돌려도 같음) ③ 금액 같음 — 변수 단위 글을 지워도 엔진 셈 · 끝수 지문이 같음(단위 글은 셈에 안 듦) ④ M02 사본 도구 — 같은 규칙으로 사본 줄 단위만 바뀌고 `판` 다시 셈 """ from __future__ import annotations import copy import importlib import re import pytest from M01_MasterData import M01_MasterData_Store as store ut = importlib.import_module("master_unit_text") mf = importlib.import_module("master_formula") build = importlib.import_module("build_단위표기_801_5") def _rows(): for data in store.loaded()[0].values(): if data.get("그룹") == "로직": yield from data["줄"] def test_대응표_근거_절에_원문_글이_있음(): assert len(ut.RULES) >= 7 for name, _, to, token, files in ut.RULES: assert files and to == token, name for rel in files: path = ut.EVIDENCE_ROOT / rel assert path.is_file(), (name, rel) assert token in path.read_text(encoding="utf-8"), (name, rel) def test_규칙_예(): got = { u: ut.canon(u) for u in ("㎥/시간", "㎡/시간", "㎢/시간", "원/시간", "초", "초/m", "mm", "TON/㎡") } assert got == { "㎥/시간": "㎥/hr", "㎡/시간": "㎡/hr", "㎢/시간": "㎢/시간", # 원문 9-5-4 가 쓰는 꼴 — 안 건드림 "원/시간": "원/시간", "초": "sec", "초/m": "sec/m", "mm": "㎜", "TON/㎡": "ton/㎡", } for u in got.values(): assert ut.canon(u) == u # 두 번 돌려도 같음 def test_섞임_0_원문_꼴로_다_바뀜(): left = [] for row in _rows(): units = [row.get("결과단위")] + [ s.get("단위") for k in ("입력", "중간") for s in row.get(k) or [] ] left += [(row["키"], u) for u in units if u and ut.canon(u) != u] assert not left, left[:5] def test_굴착기_Cm_sec_Q_hr(): row = store.loaded()[1].logic("GF000088") # 토사깍기(굴착기 0.7㎥) 시간당 작업량 assert {s["단위"] for s in row["중간"] if s["이름"] == "Cm"} == {"sec"} assert row["결과단위"] == "㎥/hr" _OLD = ( # 원문 꼴 → 옛 글(되돌려 본 꼴) — 두 꼴로 셈이 같음을 대조 (re.compile(r"(? str: for pat, old in _OLD: text = pat.sub(old, text) return text def test_금액_같음_옛_글로_되돌려도_셈_지문_같음(): files = store.loaded()[0] old = copy.deepcopy(files) for data in old.values(): if data.get("그룹") == "로직": for row in data["줄"]: for k in ("입력", "중간"): for s in row.get(k) or []: s["단위"] = _legacy(s.get("단위") or "") row["결과단위"] = _legacy(row.get("결과단위") or "") now, was = mf.Master(files), mf.Master(old) keys = [r["키"] for r in _rows()] hit = { r["키"] for r in _rows() if any( _legacy(s.get("단위") or "") != (s.get("단위") or "") for k in ("입력", "중간") for s in r.get(k) or [] ) } assert len(hit) >= 40 for key in sorted(hit) + keys[::25]: assert build.fingerprint(now, now.logic(key)) == build.fingerprint(was, was.logic(key)), key def test_M02_사본_도구(): cu = importlib.import_module("M02_MasterTemplete.M02_Copy_Units") old = { "로직": [ { "키": "GC000001", "결과단위": "㎥/시간", "입력": [{"이름": "a", "단위": "mm"}], "중간": [{"이름": "Cm", "단위": "초"}], } ], "판": "x", } new, done, _ = cu.fill(old, None) row = new["로직"][0] assert done == 3 and row["결과단위"] == "㎥/hr" and row["입력"][0]["단위"] == "㎜" assert row["중간"][0]["단위"] == "sec" and new["판"] != "x" assert cu.fill(new, None)[1] == 0 # 두 번째 = 바꿀 것 없음 if __name__ == "__main__": pytest.main([__file__, "-q"])