- 더한장 = [{장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
161 lines
6.5 KiB
Python
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)
|