Merge remote-tracking branch 'origin/sub_laptop_2' into sub_laptop_4
This commit is contained in:
+1
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"format": 6,
|
||||
"source": "00_templete_A1.dxf (남의 프로젝트 자료 제거 · 플레이스홀더화)",
|
||||
"drawing_area": [42, 47, 812, 567],
|
||||
"entities": [
|
||||
{
|
||||
"id": "4afa84ae-9c15-50ec-8a76-db87d04d6311",
|
||||
@@ -12,7 +12,7 @@ import pytest
|
||||
from B07_DesignDetail.B07_DesignDetail_Engine_Cad import DRAWING_FORMAT, FRAME_LAYER_ID
|
||||
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Cover import build_cover_drawing
|
||||
|
||||
TEMPLATE = Path("resources/template_2dDrawing/00_template_cover.json")
|
||||
TEMPLATE = Path("resources/master_template/drawing/00_template_cover.json")
|
||||
|
||||
# A1 도각 템플릿과 같은 재단 표식 원점 — 두 도면이 같은 종이 좌표계를 써야 한다.
|
||||
PAPER = (-5.05, -5.04, 834.95, 588.96)
|
||||
@@ -62,9 +62,7 @@ def test_도면은_잠금_도각_레이어로_나온다():
|
||||
assert {e["layerId"] for e in drawing["entities"]} == {FRAME_LAYER_ID}
|
||||
layers = {layer["id"]: layer for layer in drawing["layers"]}
|
||||
assert layers[FRAME_LAYER_ID]["isLocked"] is True
|
||||
assert any(not layer["isLocked"] for layer in drawing["layers"]), (
|
||||
"덧그릴 비잠금 도면층이 없다"
|
||||
)
|
||||
assert any(not layer["isLocked"] for layer in drawing["layers"]), "덧그릴 비잠금 도면층이 없다"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
"""M02 도면 양식 — 작도 영역 칸 · B07 도각 층(프로젝트 작업본 → 시스템) (PLAN 10-3)."""
|
||||
|
||||
import json
|
||||
|
||||
from B07_DesignDetail import B07_DesignDetail_Engine_Template as engine
|
||||
from M02_MasterTemplete import M02_Template_Layers as layers
|
||||
|
||||
A1 = engine.A1_TEMPLATE
|
||||
|
||||
|
||||
def _project_template(project_root, document):
|
||||
path = engine.project_template_path(project_root)
|
||||
path.parent.mkdir(parents=True)
|
||||
path.write_text(json.dumps(document), encoding="utf-8")
|
||||
return path
|
||||
|
||||
|
||||
def _entities(project_root):
|
||||
engine.use_project_templates(project_root)
|
||||
try:
|
||||
return engine.template_entities()
|
||||
finally:
|
||||
engine.use_project_templates(None)
|
||||
|
||||
|
||||
def test_system_a1_reads_drawing_area():
|
||||
engine.use_project_templates(None)
|
||||
assert engine.drawing_area() == (42.0, 47.0, 812.0, 567.0)
|
||||
assert len(engine.template_entities()) == 51
|
||||
|
||||
|
||||
def test_missing_area_falls_back_to_a1(tmp_path):
|
||||
_project_template(tmp_path, {"format": 6, "entities": [], "layers": []})
|
||||
engine.use_project_templates(tmp_path)
|
||||
try:
|
||||
assert engine.drawing_area() == engine._A1_INNER
|
||||
finally:
|
||||
engine.use_project_templates(None)
|
||||
|
||||
|
||||
def test_template_area_moves_content(tmp_path):
|
||||
line = {
|
||||
"id": "a",
|
||||
"type": "Line",
|
||||
"shapeData": {"startPoint": {"x": 0, "y": 0}, "endPoint": {"x": 10, "y": 0}},
|
||||
}
|
||||
_project_template(
|
||||
tmp_path,
|
||||
{"format": 6, "drawing_area": [0, 0, 400, 200], "entities": [line], "layers": []},
|
||||
)
|
||||
engine.use_project_templates(tmp_path)
|
||||
try:
|
||||
assert engine.drawing_area() == (0.0, 0.0, 400.0, 200.0)
|
||||
assert engine.usable_area() == (400 * 0.96, 200 * 0.96)
|
||||
# 콘텐츠 중심(500, 500) 이 작도 영역 중심(200, 100) 에 온다 — 이동량 (300, 400).
|
||||
placed = engine.frame_entities("t", (490.0, 490.0, 510.0, 510.0), fit=False)
|
||||
assert placed[0]["shapeData"]["startPoint"] == {"x": 300.0, "y": 400.0}
|
||||
finally:
|
||||
engine.use_project_templates(None)
|
||||
|
||||
|
||||
def test_bad_area_falls_back(tmp_path):
|
||||
_project_template(tmp_path, {"drawing_area": [10, 10, 5, 5], "entities": []})
|
||||
engine.use_project_templates(tmp_path)
|
||||
try:
|
||||
assert engine.drawing_area() == engine._A1_INNER
|
||||
finally:
|
||||
engine.use_project_templates(None)
|
||||
|
||||
|
||||
def test_old_project_reads_system(tmp_path):
|
||||
# 작업본이 없는 옛 프로젝트 — 시스템 양식으로 떨어진다.
|
||||
assert len(_entities(tmp_path)) == 51
|
||||
assert engine.is_project_template_customized(tmp_path) is False
|
||||
|
||||
|
||||
def test_save_reset_on_seeded_project(tmp_path):
|
||||
layers.seed_project(tmp_path)
|
||||
assert engine.project_template_path(tmp_path).is_file()
|
||||
assert engine.is_project_template_customized(tmp_path) is False
|
||||
|
||||
# [완료] — 작업본에만 쓴다 · 작도 영역은 이어 받는다 · `_initial/` · 시스템은 그대로.
|
||||
path = engine.save_project_template(tmp_path, [])
|
||||
saved = json.loads(path.read_text(encoding="utf-8"))
|
||||
assert saved["drawing_area"] == [42, 47, 812, 567]
|
||||
assert _entities(tmp_path) == []
|
||||
assert engine.is_project_template_customized(tmp_path) is True
|
||||
initial = layers.template_path(layers.initial_dir(tmp_path), "drawing", A1)
|
||||
assert len(json.loads(initial.read_text(encoding="utf-8"))["entities"]) == 51
|
||||
assert (
|
||||
len(json.loads(engine.system_template_path().read_text(encoding="utf-8"))["entities"]) == 51
|
||||
)
|
||||
|
||||
# [기본 도각으로] — `_initial/` 을 작업본에 덮어쓴다.
|
||||
assert engine.reset_project_template(tmp_path) is True
|
||||
assert len(_entities(tmp_path)) == 51
|
||||
assert engine.is_project_template_customized(tmp_path) is False
|
||||
|
||||
|
||||
def test_reset_on_old_project_drops_to_system(tmp_path):
|
||||
engine.save_project_template(tmp_path, [])
|
||||
assert _entities(tmp_path) == []
|
||||
assert engine.reset_project_template(tmp_path) is True
|
||||
assert not engine.project_template_path(tmp_path).exists()
|
||||
assert len(_entities(tmp_path)) == 51
|
||||
assert engine.reset_project_template(tmp_path) is False
|
||||
@@ -0,0 +1,58 @@
|
||||
"""M02 도면 양식 서버 길 — 자리표 키 목록 · 도각 파일 불러오기 (PLAN 10-3)."""
|
||||
|
||||
import io
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from M02_MasterTemplete.M02_MasterTemplete_Router_Drawing import DRAWING_FIELDS, router
|
||||
|
||||
app = FastAPI()
|
||||
app.include_router(router)
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_fields_cover_system_placeholders():
|
||||
# 시스템 도면 양식에 박힌 자리표는 전부 키 목록에 있다 — 없으면 화면이 모르는 칸이 생긴다.
|
||||
keys = {key for key, _, _ in DRAWING_FIELDS}
|
||||
used = set()
|
||||
for path in Path("resources/master_template/drawing").glob("00_*.json"):
|
||||
text = json.dumps(json.loads(path.read_text(encoding="utf-8")), ensure_ascii=False)
|
||||
used |= {match.strip() for match in re.findall(r"\{\{\s*([^}]+?)\s*\}\}", text)}
|
||||
assert used and used <= keys, used - keys
|
||||
|
||||
|
||||
def test_fields_without_project():
|
||||
response = client.get("/api/m02/drawing-fields")
|
||||
assert response.status_code == 200
|
||||
body = response.json()
|
||||
assert [item["key"] for item in body["fields"]] == [key for key, _, _ in DRAWING_FIELDS]
|
||||
assert body["values"] == {}
|
||||
|
||||
|
||||
def test_import_rejects_other_files():
|
||||
response = client.post(
|
||||
"/api/m02/drawing-import", files={"file": ("a.txt", b"hello", "text/plain")}
|
||||
)
|
||||
assert response.status_code == 400
|
||||
assert "DXF" in response.json()["message"]
|
||||
|
||||
|
||||
def test_import_dxf():
|
||||
import ezdxf
|
||||
|
||||
document = ezdxf.new()
|
||||
document.modelspace().add_line((0, 0), (100, 50))
|
||||
stream = io.StringIO()
|
||||
document.write(stream)
|
||||
response = client.post(
|
||||
"/api/m02/drawing-import",
|
||||
files={"file": ("frame.dxf", stream.getvalue().encode("utf-8"), "application/dxf")},
|
||||
)
|
||||
assert response.status_code == 200, response.text
|
||||
body = response.json()
|
||||
assert body["entity_count"] == 1
|
||||
assert body["drawing"]["entities"][0]["type"] == "Line"
|
||||
Reference in New Issue
Block a user