Files
Aislo/resources/tester/test_pum_md_tool.py
T
eomsangdonandClaude Opus 5 b8d76feccd knowledge(품셈md): 산림 빈 파일 196 — 장머리 13 · 절 183 (plan)
- 제4장 일곱(다른 창 시범분)은 건너뜀 → 산림 전체 장머리 14 · 절 189
- 절 이름·표지는 본문 머리 글자 그대로(번호 뒤 마침표) · 띄어쓰기는 쪽 그림의 글자 틈으로 되살림
- 도구: 장마다 0-00_장머리.md · 이미 있는 자리는 번호로 봐서 건너뜀(이 폴더·다른 창 브랜치)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
2026-09-19 01:23:13 +09:00

81 lines
3.3 KiB
Python

"""품셈 PDF → 절별 md 도구(`_pipeline/pum_md_tool.py`) — 순수 함수 · 산림 차례 개수.
규칙: `resources/knowledge/original/원가계산/_품셈md_작성규칙.md`.
"""
import sys
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT / "resources/knowledge/original/_pipeline"))
import pum_md_tool as tool # noqa: E402
def test_parse_toc_strips_leaders_and_reads_appendix():
lines = ["제1장", "적용기준 ·········", "1", "1-1", "일반사항 ·····", "1", "부록 ······", "204"]
got = tool.parse_toc(lines)
assert [(e.ident, e.name, e.page) for e in got] == [
("제1장", "적용기준", 1),
("1-1", "일반사항", 1),
("부록", "", 204),
]
with pytest.raises(ValueError):
tool.parse_toc(["엉뚱한 줄", "1"])
def test_key_ignores_spaces_dot_after_number_and_middle_dots():
assert tool.key("9-5. 발파암") == tool.key("9-5 발파암")
assert tool.key("[부록1]할인") == tool.key("부록1 할인")
assert tool.key("보수·복구") == tool.key("보수․복구")
def test_heading_pattern_by_number_only():
sec = tool.heading_pattern("7-1")
assert sec.match("7-1. 벌도")
assert not sec.match("7-11. 동력상하차기") # 번호가 앞머리만 같음
assert not sec.match("7-1-1. 항")
assert tool.heading_pattern("제1장").match("제1장적용기준")
assert not tool.heading_pattern("제1장").match("제10장자재")
assert tool.heading_pattern("부록1").match("[부록1]할인")
assert not tool.heading_pattern("부록1").match("[부록10]x")
def test_name_of_and_safe():
assert tool.name_of("9-5", "9-5. 발파암") == "발파암"
assert tool.name_of("제2장", "제2장 소요재료 및 기계손료") == "소요재료 및 기계손료"
assert tool.safe("목재 운반/적재") == "목재_운반적재"
def test_head_round_trip(tmp_path):
path = tmp_path / "a.md"
path.write_text(
tool.head_text({"절": "9-5. 발파암", "상태": "대기"}) + "\n본문\n", encoding="utf-8"
)
head = tool.read_head(path)
assert list(head) == list(tool.HEAD_KEYS)
assert head["절"] == "9-5. 발파암" and head["상태"] == "대기" and head["작성"] == ""
def test_forest_toc_counts():
"""산림 차례 — 14장 · 189절(PDF 3~12쪽)."""
pymupdf = pytest.importorskip("pymupdf")
book = tool.BOOKS["산림"]
with pymupdf.open(book["pdf"]) as doc:
entries = tool.toc_entries(doc, *book["toc"])
assert sum(e.ident.startswith("제") for e in entries) == 14
assert sum(e.ident.count("-") == 1 for e in entries) == 189
def test_forest_headings_follow_page_spacing():
"""머리 글자 — 글자층은 빈칸을 잃음(「설계및수량」) · 쪽 그림대로 되살림 · 차례 오타(조림)는 안 따름."""
pymupdf = pytest.importorskip("pymupdf")
with pymupdf.open(tool.BOOKS["산림"]["pdf"]) as doc:
assert tool.find_heading(doc, "1-2", 14)[2] == "1-2. 설계 및 수량"
assert tool.find_heading(doc, "12-3", 172)[2] == "12-3. 철근 현장가공 및 조립"
assert tool.find_heading(doc, "제1장", 13)[2] == "제1장 적용기준"
page, row, _ = tool.find_heading(doc, "9-6", 136)
assert (page, row) == (136, 0) # 쪽 맨 위 — 앞 절은 135 쪽에서 끝남