Files
Aislo/resources/tester/test_m02_drawing_sheets.py
T
eomsangdonandClaude Opus 5.5 5b9c804ff5 feat(M02): 구조물 도면 여러 장 저장 꼴 — 더한장 · 연결표 장 · 모든 장 표 맞춤 · 장 도번 도각(82-2)
- 더한장 = [{장id, 이름, 도면:{format, entities, layers}}] 뼈대 검사 · drawing_sheets
- 면적 [저장] 때 안 열린 장 표도 서버가 갱신
- /m02/structure-frame?number= 장 도번을 도각 {{도면번호}} 에
- StructureDoc 더한장 · 연결표 장 타입

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
2026-10-08 12:02:59 +09:00

161 lines
6.5 KiB
Python

"""M02 구조물 도면 여러 장(PLAN 82-2 · 82-3) — 저장 꼴 `더한장` · 뼈대 검사 · 모든 장 표 맞춤 ·
복사 · 스냅샷 · 개인 저장이 더한장을 같이 나름 · 장 도번 도각 `{{도면번호}}`.
시스템 층 = 견본 표(임시 폴더 · `test_m02_area_table.world`) · storage 는 임시.
"""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
import pytest
from M02_MasterTemplete import M02_Item_Personal as personal
from M02_MasterTemplete import M02_Item_Source as source
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete import M02_Template_Layers as layers
from M02_MasterTemplete.M02_MasterTemplete_Router_Drawing import structure_frame
from resources.tester.test_m02_area_table import world # noqa: F401 — 같은 견본 층
_ = world
def _table(link: str) -> dict[str, Any]:
return {
"type": "Table",
"shapeData": {
"origin": {"x": 0, "y": 0},
"columnWidths": [9, 9],
"rowHeights": [3, 3],
"cells": [[{"text": "낡음"}, {"text": "낡음"}], [None, {"text": "낡음"}]],
"style": {"fontSize": 2.5, "연결": link},
},
}
def _sheet(sheet_id: str, name: str, entities: list) -> dict[str, Any]:
return {
"장id": sheet_id,
"이름": name,
"도면": {"format": 6, "entities": entities, "layers": [{"id": "기본", "name": "기본"}]},
}
def _write_sheets(folder: Path) -> dict[str, Any]:
"""rv 도면 = 1장(T1 표) + 더한장 둘(s2 = T2 표 · s3 = 빈 장) · 연결표 줄에 `장`."""
with store.at(folder):
got = store.read("structure", "rv")
doc = got["문서"]
doc["도면"]["entities"] = [_table("T1")]
doc[layers.MORE_SHEETS] = [_sheet("s2", "단면", [_table("T2")]), _sheet("s3", "상세", [])]
doc["연결표"] = [
{"연결": "T1", "장": "", "시트": "s1", "범위": "A1:B2", "글자크기": 2.5, "값": {}},
{"연결": "T2", "장": "s2", "시트": "s1", "범위": "A1:B2", "글자크기": 2.5, "값": {}},
]
store.write("structure", "rv", got["판"], doc)
return store.read("structure", "rv")["문서"]
@pytest.mark.parametrize(
"more",
[
"장",
[{"이름": "가", "도면": {"entities": []}}],
[_sheet("s2", "가", []), _sheet("s2", "나", [])],
[{"장id": "s2", "이름": "가", "도면": {}}],
[{"장id": "s2", "도면": {"entities": []}}],
],
)
def test_더한장_모양이_틀리면_거절(more):
doc = {"도면": {"entities": []}, layers.MORE_SHEETS: more}
with pytest.raises(ValueError):
layers.check_skeleton("structure", doc)
def test_더한장_없거나_맞으면_통과_장_목록():
layers.check_skeleton("structure", {"도면": {"entities": []}}) # 옛 문서 그대로
doc = {"도면": {"entities": [1]}, layers.MORE_SHEETS: [_sheet("s2", "가", [2])]}
layers.check_skeleton("structure", doc)
assert layers.drawing_sheets(doc) == [("", doc["도면"]), ("s2", doc["더한장"][0]["도면"])]
assert layers.drawing_sheets({"도면": {"entities": []}, "더한장": ["틀림"]}) == [
("", {"entities": []})
]
def test_저장_다시_읽기_둘째_장_그대로(world): # noqa: F811
doc = _write_sheets(world["system"])
assert [s["장id"] for s in doc["더한장"]] == ["s2", "s3"]
assert doc["더한장"][0]["도면"]["entities"][0]["shapeData"]["style"]["연결"] == "T2"
with store.at(world["system"]), pytest.raises(store.StoreError):
got = store.read("structure", "rv")
store.write("structure", "rv", got["판"], {**got["문서"], "더한장": [{"장id": ""}]})
def test_면적_저장_뒤_안_열린_둘째_장_표도_갱신(world): # noqa: F811
system = world["system"]
_write_sheets(system)
with store.at(system):
got = store.read("area", "rv")
got["문서"]["시트"][0]["칸"]["B1"] = {"값": 10, "서식": 1}
store.write("area", "rv", got["판"], got["문서"])
doc = store.read("structure", "rv")["문서"]
first = doc["도면"]["entities"][0]["shapeData"]["cells"]
second = doc["더한장"][0]["도면"]["entities"][0]["shapeData"]["cells"]
assert first[0][1]["text"] == "10.00" and second[1][1]["text"] == "20.00"
assert [row["장"] for row in doc["연결표"]] == ["", "s2"] # 장 칸 그대로
assert doc["연결표"][1]["값"]["s1!B2"] == "20.00"
def test_다른_열로_복사_더한장_같이(world): # noqa: F811
_write_sheets(world["system"])
with store.at(world["system"]):
if not store._path("structure", "c1").is_file():
store.create_structure("c1")
store.copy_from("structure", "c1", "rv")
doc = store.read("structure", "c1")["문서"]
rv = store.read("structure", "rv")["문서"]
assert [s["장id"] for s in doc["더한장"]] == ["s2", "s3"]
assert doc["도번"] != rv["도번"] # 번호는 받는 열 그대로
def _rv_key(system: Path) -> str:
with store.at(system):
return next(r["키"] for r in store.read_combos()["줄"] if r.get("열") == "rv")
def test_스냅샷_원본이_더한장_같이_나름(world): # noqa: F811
_write_sheets(world["system"])
files = source.build_source({"layer": "system", "key": _rv_key(world["system"])})
assert len(files["도면.json"]["더한장"]) == 2
def test_개인에_저장_더한장_같이(world, tmp_path): # noqa: F811
_write_sheets(world["system"])
files = source.build_source({"layer": "system", "key": _rv_key(world["system"])})
copy = tmp_path / "copy"
copy.mkdir()
for name in ("집계.json", "도면.json"):
(copy / name).write_text(json.dumps(files[name], ensure_ascii=False), encoding="utf-8")
folder = layers.personal_dir(7, 99)
made = personal.create_item(folder, ["가"], "나", "m", copy=copy)
with store.at(folder):
doc = store.read("structure", made["열"])["문서"]
assert [s["이름"] for s in doc["더한장"]] == ["단면", "상세"]
def test_장_도번이_도각_도면번호에():
texts = [
(e.get("shapeData") or {}).get("label")
for e in structure_frame("SD-000010-2")["entities"]
if e.get("type") == "Text"
]
assert "SD-000010-2" in texts
blank = [
(e.get("shapeData") or {}).get("label")
for e in structure_frame()["entities"]
if e.get("type") == "Text"
]
assert "SD-000010-2" not in blank and not any("{{" in str(t) for t in blank)