"""B07 횡단도 — B06 [상세] 글(`design.structure_note`)이 수량표 바로 위 여러 줄로 찍힘(150-3). 글 줄마다 Text(표 왼쪽 맞춤 · 표 윗변 아래로 줄 수만큼 내림) · 블록 높이도 같은 만큼 · 글 없으면 그대로. """ import pytest from B07_DesignDetail.B07_DesignDetail_Engine_Cad import FRAME_LAYER_ID, build_cross_drawing from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import section_block_size from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Table import ( cross_note_height, cross_note_lines, ) from B07_DesignDetail.B07_DesignDetail_Engine_Template import entities_bbox _SOURCE = { "chainage_m": 20.0, "samples": [ {"valid": True, "offset_m": float(x), "elevation_m": 100.0 + 0.3 * x} for x in range(-10, 11) ], } _TABLE = {"ground": 100.0, "planned": 99.5} def _draw(design: dict | None) -> dict: return build_cross_drawing(_SOURCE, "cross_00020m", None, design, _TABLE, "No.1") def _table(drawing: dict) -> dict: return next(e for e in drawing["entities"] if e["type"] == "Table") def _frame_height(drawing: dict) -> float: frame = [e for e in drawing["entities"] if e.get("layerId") == FRAME_LAYER_ID] _x0, y0, _x1, y1 = entities_bbox(frame) return y1 - y0 def test_글_줄_나눔() -> None: assert cross_note_lines(None) == [] assert cross_note_lines({"structure_note": " "}) == [] assert cross_note_lines({"structure_note": "\nL형 측구 \n\n집수정 보강\n"}) == [ "L형 측구", "", "집수정 보강", ] def test_글_없으면_그대로() -> None: plain = _draw(None) empty = _draw({"structure_note": ""}) assert _table(plain)["shapeData"] == _table(empty)["shapeData"] assert not [e for e in empty["entities"] if e["type"] == "Text"] def test_글_두_줄은_표_위_Text_둘_표는_내려감() -> None: plain = _draw(None) noted = _draw({"structure_note": "L형 측구\n집수정 보강"}) texts = [e for e in noted["entities"] if e["type"] == "Text"] assert [t["shapeData"]["label"] for t in texts] == ["L형 측구", "집수정 보강"] plain_top = _table(plain)["shapeData"]["origin"]["y"] noted_top = _table(noted)["shapeData"]["origin"]["y"] drop = cross_note_height(["a", "b"]) assert plain_top - noted_top == pytest.approx(drop) # 표 왼쪽 맞춤 · 위에서 아래로 · 모두 표 윗변과 옛 윗변 사이 left = _table(noted)["shapeData"]["origin"]["x"] for text in texts: base = text["shapeData"]["basePoint"] assert base["x"] == pytest.approx(left) assert text["shapeData"]["options"]["textAlign"] == "left" assert noted_top < base["y"] < plain_top assert texts[0]["shapeData"]["basePoint"]["y"] > texts[1]["shapeData"]["basePoint"]["y"] # 블록(테두리) 높이 = 글 높이만큼 커짐 · 블록 크기 계산도 같은 규칙 assert _frame_height(noted) - _frame_height(plain) == pytest.approx(drop) _w, plain_h = section_block_size(_SOURCE, None) _w, noted_h = section_block_size( _SOURCE, None, design={"structure_note": "L형 측구\n집수정 보강"} ) assert noted_h - plain_h == pytest.approx(drop) def test_빈_줄은_자리만() -> None: noted = _draw({"structure_note": "윗줄\n\n아랫줄"}) texts = [e for e in noted["entities"] if e["type"] == "Text"] assert [t["shapeData"]["label"] for t in texts] == ["윗줄", "아랫줄"] gap = texts[0]["shapeData"]["basePoint"]["y"] - texts[1]["shapeData"]["basePoint"]["y"] assert gap == pytest.approx(cross_note_height(["a", "b"]))