"""338-1 순위 · 판정 · 조합 · 뒤 셈(`M02_Hopyo_Fit` · `_Verdict` · `_Combine`) — 같음 규칙 · 딱 맞음이 같음을 이김 · 맞음 · 다른 점 · 후보 · 철근 둘 · 고임돌 인력 10% · 맞춤셈 캐시 · 「셈 중」. 실물 = 북부청 임도 · 사방(읽기만) · 층 · 캐시 폴더는 임시.""" import queue import shutil import time import pytest from M02_MasterTemplete import M02_Hopyo_Fit as fit from M02_MasterTemplete import M02_Hopyo_Match as hm from M02_MasterTemplete import M02_Hopyo_Ours as ours from M02_MasterTemplete import M02_Hopyo_Store as hopyo_store from M02_MasterTemplete import M02_Hopyo_Verdict as verdict from resources.tester.helper_m02_hopyo_golden import line_of, read from resources.tester.test_m02_hopyo_excel import master_hash @pytest.fixture(scope="module") def got(): if not ours.ready(): ours.build() return hm.targets() def _block(lid: str, got: dict, **change) -> dict: block, line = line_of(lid) if change: line = {**line, "근거": {}} block = {**block, "출처": []} return verdict.block(block, line, got) def test_같음_규칙_이름_같음_1위_고정(got): r = _block("N014", got) assert r["B"] == "같음" and r["차례"][0] == "GC000214" and r["판정"]["상태"] == "맞음" def test_딱_맞음이_같음을_이김(got): r = _block("N001", got, 근거=None) # 인용 조항을 지우면 이름 같음 = 산림 GF000160 assert r["B"] == "같음" and hm.b_order(line_of("N001")[1], got)["상태"] == "후보" assert r["차례"][0] == "GC000211" and r["판정"]["상태"] == "맞음" def test_판정_셋(got): a = _block("N000", got) assert a["판정"]["상태"] == "맞음" and "소량감률 50" in a["판정"]["글"] assert a["후보"][0]["판정"] == "맞음" and a["후보"][0]["근거"]["까닭"].startswith("조항 같음") b = _block("N008", got) assert b["판정"]["상태"] == "다른 점" and b["차례"][0] == "GC000083" assert "특별인부 엑셀 0.3542 · 우리 0.3704" in b["판정"]["꼬리표"] c = _block("S084", got) assert c["판정"]["상태"] == "후보" and len(c["후보"]) == 5 def test_합판_맞음_못_가름_꼬리표(got): r = _block("N001", got) assert r["판정"]["상태"] == "맞음" assert any( t.endswith("못 가름") and {"측압", "폼타이규격"} <= set(t.split()) for t in r["판정"]["꼬리표"] ) def test_조합_철근_가공_조립(got): r = _block("N003", got) assert {c["로직"] for c in r["조합"] if c["체크"]} == {"GC000206", "GC000207"} def test_조합_고임돌_인력_몫_먼저(got): r = _block("N005", got) assert r["차례"][0] == "GF000211" labor = next(c for c in r["조합"] if c["로직"] == "GF000211") assert labor["몫"] == 0.1 and labor["체크"] assert all(not c["체크"] for c in r["조합"] if c["로직"] in ("GC000267", "GC000268")) def test_조합_근거_안_닿은_덧은_후보(got): r = _block("N009", got) # 구조물되메우기(인력100%) — 훈증더미 인력 제거(개)는 덧 아님 assert r["차례"][0] == "GF000113" and not r["조합"] assert any(c["로직"] == "GF000083" and c["글"].startswith("덧 후보") for c in r["후보"]) r = _block("N017", got) # 다웰바(EA) — PSC빔 쉬즈관(m) 덧 아님 assert r["차례"][0] == "GC000226" and not r["조합"] def test_숫자_없음_옛_HP(got): block, line = line_of("N000") r = verdict.block({**block, "글": []}, line, got) assert r["판정"]["상태"] == "후보" and r["판정"]["글"] == fit.NO_NUMBER assert r["차례"][0] == "GC000198" # 이름 · 근거 차례 그대로 @pytest.fixture def layer(tmp_path, monkeypatch, got): cache = tmp_path / "cache" cache.mkdir() shutil.copy(ours.path_of(), cache / ours.path_of().name) monkeypatch.setenv("AISLO_HOPYO_CACHE", str(cache)) book = read("북부청임도") small = {**book, "호표": book["호표"][:3]} brief = hopyo_store.save(tmp_path, "북부청.xls", small, {"id": "t"}) return tmp_path, brief["키"], cache def test_뒤_셈_캐시_셈_중(layer, monkeypatch): folder, key, cache = layer # 앞 시험들의 올리기가 쌓은 일감(북부청 통째)을 기다리지 않게 — 이 시험만의 일감 줄 · 일꾼 monkeypatch.setattr(fit, "_JOBS", queue.Queue()) monkeypatch.setattr(fit, "_PENDING", set()) monkeypatch.setattr(fit, "_WORKER", {"스레드": None}) before = master_hash() assert fit.result(folder, key) is None first = fit.ensure(folder, key) assert first["끝"] is False and first["한"] == 0 for _ in range(300): if fit.status(folder, key)["끝"]: break time.sleep(0.2) done = fit.status(folder, key) assert done["끝"] and done["한"] == done["모두"] > 0 got = fit.result(folder, key) assert got["판"] == ours.version() and len(got["블록"]) == done["모두"] assert fit.cache_path(folder, key).parent == cache assert fit.ensure(folder, key)["끝"] # 두 번째는 캐시만 봄 assert master_hash() == before def test_셈_단위_열쇠(got): book = read("북부청임도") units = fit.units({**book, "호표": book["호표"][:3]}) keys = [k for k, _, _ in units] assert len(keys) == len(set(keys)) and keys[0].startswith("단산:") assert all(k.startswith(("단산:", "줄:", "호표:")) for k in keys)