브레인 일감(막힌 자리). 코덱스가 md 에 줄을 보태자 원천 벌의 옛 줄 번호가 밀려 산림 밑수가 238 → 105 로
떨어졌고, 머리글로 다시 맞추니 12장 같은 머리글 이웃 표를 집어 직접공사비가 움직였음. 추출기가 저장소에 없었음.
- `resources/data_cost_input_value/_build_pum.py` — md `|` 표를 칸 글자 그대로(2단 머리 안 펼침)
· 표 번호·절은 옛 벌에서 이어받음 — ① 글자 같은 표를 차례 지키며 맞댐(이웃으로 못 건너뜀)
② 맞은 표 사이 수가 같으면 같은 차례끼리(글자만 고쳐진 표) ③ 다르면 그 안 머리 같은 표끼리
· 새 표는 가장 큰 번호 다음 · 사라진 표는 번호 버리고 알림 · 줄 번호·sha256 은 새 md 에서
· 옛 md(177d8844)에 돌리면 산림 476 · 건설 2192 표가 원천 벌과 글자까지 같음(표 번호·절·줄·칸)
- 다시 뽑음 — 산림: 줄만 밀린 351 · 글자 바뀐 표 0 / 건설: 줄만 밀린 199 · 새 표 10(C2193~C2202 ·
코덱스가 뭉친 글을 표로 되살린 제8장 손료표 · 뒤 번호 안 밀림)
- ⭐ 금액 불변 — 다시 뽑고 공종 마스터를 다시 지어 원가계산서를 잼: 직접공사비 5,983,724 → 5,983,724 ·
총원가 9,203,637 · 합계 10,124,000 그대로(원가계산서 열세 칸 전부 같음 · `test_work_item_key_gate`) · 열쇠 새 발급 0
· 이 커밋만으로는 원문 맞대기 둘이 빨강(마스터 줄 번호가 옛 md 기준 — 받기 전부터 빨강) · 마스터 다시 지으면 초록
· ⚠ 마스터 다시 짓기는 데스크탑 서브 몫이라 커밋에 안 넣음 — 지으면 밑수 238 → 242 · 미확보 92 → 88
(코덱스가 되살린 밑수 줄: 5-19-1 ㎡ · 5-27 10㎡ · 5-28-1 100㎡ · 9-21 100㎡) · 지문 시험은 그때 갱신
- `test_build_pum.py` — 원천 벌이 md 와 같음 · 줄 37 보태도 번호·절 그대로 · 표가 끼어도 뒤 번호 안 밀림 ·
12-17-1 같은 머리글 표 가운데를 고쳐도 제 번호 · 빠진 표는 알림 · 2단 머리 안 펼침
- 원문 맞대기 알려진 목록을 마스터 다시 지은 뒤 모습에 맞춤 —
⚠ 5-26-1·2·3 코덱스 복원 「(인/992㎡당)」 ↔ 마스터 사람 판정 100㎡ 어긋남(사람 판단 필요) ·
5-28-2 「(일 당)」 은 작업조 표라 마스터가 일부러 비움
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
110 lines
5.6 KiB
Python
110 lines
5.6 KiB
Python
"""원천 벌 뽑기(`_build_pum.py`) 시험 — 2026-09-18 브레인 일감(랩탑 메인).
|
|
|
|
못박는 것
|
|
- 원천 벌이 **지금 md 와 같음** — md 가 고쳐졌는데 안 뽑았으면 빨강(뽑기를 돌리라는 뜻).
|
|
- ⚠ **줄이 밀려도 표 번호·절이 그대로** — 이번 막힘(밑수 238 → 105)의 원인 자리.
|
|
- 표가 끼어들어도 **뒤 번호가 안 밀림** · 글자만 고쳐진 표는 **제 번호** · 사라진 표는 **알림**.
|
|
- ⚠ 머리글이 같은 이웃 표(12-17-1 펌프카 타설 일곱 표)로 **건너뛰지 않음** — 서브가 겪은 사고.
|
|
금액 불변 — 뽑은 뒤 공종 마스터를 다시 짓고 `test_work_item_key_gate.py` 원가계산서 시험
|
|
(직접공사비 5,983,724)이 잼. 이 파일은 그 앞 단계(원천 벌 표 번호·절·칸 글자)가 안 흔들림을 잼.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import copy
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT / "resources" / "data_cost_input_value"))
|
|
|
|
import _build_pum as build # noqa: E402
|
|
|
|
FOREST = build.CATALOGS["pum_forest"]
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def forest() -> dict:
|
|
"""지금 md 에서 뽑은 산림 벌 — 아래 시험은 이것에 줄을 보태고·표를 끼우고·고치고·뺌."""
|
|
committed = json.loads(FOREST.read_text(encoding="utf-8"))
|
|
return build.extract(committed, build._read, "pum_forest")[0]
|
|
|
|
|
|
def _lines_of(doc: dict) -> list[str]:
|
|
return (ROOT / doc["sources"][0]["path"]).read_text(encoding="utf-8").splitlines()
|
|
|
|
|
|
def _reader(lines: list[str]):
|
|
return lambda path: "\n".join(lines).encode("utf-8")
|
|
|
|
|
|
def _tables(doc: dict) -> list[dict]:
|
|
return doc["variables"]["pum"]["tables"]
|
|
|
|
|
|
@pytest.mark.parametrize("dataset", list(build.CATALOGS))
|
|
def test_원천_벌이_지금_md_와_같음(dataset: str) -> None:
|
|
"""md 가 고쳐졌으면 `_build_pum.py` 를 돌릴 것. sha 는 줄끝(CRLF) 따라 PC 마다 갈려 안 봄."""
|
|
old = json.loads(build.CATALOGS[dataset].read_text(encoding="utf-8"))
|
|
doc, report = build.extract(old, build._read, dataset)
|
|
stale = {k: v for k, v in report.items() if k != "same" and v}
|
|
assert _tables(doc) == _tables(old), (
|
|
f"{dataset} 원천 벌이 md 와 다름 — _build_pum.py 돌릴 것: {stale}"
|
|
)
|
|
|
|
|
|
def test_줄이_밀려도_표_번호와_절이_그대로(forest: dict) -> None:
|
|
lines = _lines_of(forest)
|
|
at = next(i for i, x in enumerate(lines) if x.startswith("### 5-1."))
|
|
shifted = lines[:at] + ["보탠 줄"] * 37 + lines[at:]
|
|
doc, report = build.extract(forest, _reader(shifted), "pum_forest")
|
|
before, after = _tables(forest), _tables(doc)
|
|
assert [(t["table_id"], t["section"]) for t in after] == [(t["table_id"], t["section"]) for t in before] # fmt: skip
|
|
assert [t["line"] - b["line"] for t, b in zip(after, before)] == [37 if b["line"] > at else 0 for b in before] # fmt: skip
|
|
assert report["changed"] == report["new"] == report["removed"] == []
|
|
|
|
|
|
def test_표가_끼어들어도_뒤_번호가_안_밀리고_새_번호를_받음(forest: dict) -> None:
|
|
lines = _lines_of(forest)
|
|
at = next(i for i, x in enumerate(lines) if x.startswith("### 9-2."))
|
|
inserted = lines[: at + 1] + ["", "| 새 | 표 |", "|---|---|", "| 1 | 2 |", ""] + lines[at + 1 :]
|
|
doc, report = build.extract(forest, _reader(inserted), "pum_forest")
|
|
ids = [t["table_id"] for t in _tables(doc)]
|
|
assert [t["table_id"] for t in _tables(forest)] == [i for i in ids if i != "F0477"]
|
|
assert [(n["table_id"], n["section"]) for n in report["new"]] == [("F0477", "9-2. 노선 굴진 보조원")] # fmt: skip
|
|
assert report["removed"] == [] and report["changed"] == []
|
|
|
|
|
|
def test_글자만_고쳐진_표는_제_번호_머리글_같은_이웃으로_안_건너뜀(forest: dict) -> None:
|
|
"""12-17-1 펌프카 타설 — 같은 머리글 표가 줄지어 있음. 가운데 표 한 칸을 고쳐도 번호가 제자리."""
|
|
lines = _lines_of(forest)
|
|
target = next(t for t in _tables(forest) if t["table_id"] == "F0359")
|
|
row = target["line"] + 1 # 첫 몸 줄(0부터 셈: 머리 line-1 · 구분줄 line · 몸 line+1)
|
|
edited = copy.copy(lines)
|
|
edited[row] = edited[row].replace("|", "| 고침", 1) # 첫 칸 글자만 바꿈
|
|
doc, report = build.extract(forest, _reader(edited), "pum_forest")
|
|
assert [t["table_id"] for t in _tables(doc)] == [t["table_id"] for t in _tables(forest)]
|
|
assert report["changed"] == [{"table_id": "F0359", "line": target["line"]}]
|
|
|
|
|
|
def test_표가_빠지면_번호를_버리고_알림(forest: dict) -> None:
|
|
lines = _lines_of(forest)
|
|
target = next(t for t in _tables(forest) if t["table_id"] == "F0358")
|
|
end = target["line"] + 1 + len(target["rows"]) # 머리·구분줄·몸
|
|
removed = lines[: target["line"] - 1] + lines[end:]
|
|
doc, report = build.extract(forest, _reader(removed), "pum_forest")
|
|
ids = [t["table_id"] for t in _tables(doc)]
|
|
assert "F0358" not in ids and ids == [t["table_id"] for t in _tables(forest) if t["table_id"] != "F0358"] # fmt: skip
|
|
assert [r["table_id"] for r in report["removed"]] == ["F0358"] and report["new"] == []
|
|
|
|
|
|
def test_2단_머리를_펼치지_않음() -> None:
|
|
"""윗머리 줄은 표 머리(`headers`)로, 아랫머리는 첫 몸 줄로 **글자 그대로** 남음."""
|
|
lines = ["### 8-3-1 손료", "", "| 분류 번호 | 시 간 당(10-7) | |", "|---|---|---|", "| | 상각비 계수 | 계 |", "| 0101-0007 | 1,811 | 2,000 |"] # fmt: skip
|
|
(table,) = build.md_tables(lines)
|
|
assert table["headers"] == ["분류 번호", "시 간 당(10-7)", ""]
|
|
assert table["rows"][0] == ["", "상각비 계수", "계"]
|