feat(styles): drawing_apply_standard — ISO or ANSI styles, units and layers in one idempotent call

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-21 22:49:12 +03:00
co-authored by Claude Opus 5
parent 021a4eb43d
commit a5d166f365
7 changed files with 269 additions and 10 deletions
+91 -1
View File
@@ -999,7 +999,9 @@ def com_backend(monkeypatch, tmp_path):
monkeypatch.setattr(_FakeStyle, "support_folder", support)
document = _FakeDocument()
app = types.SimpleNamespace(
Preferences=types.SimpleNamespace(Files=types.SimpleNamespace(SupportPath=str(support)))
Preferences=types.SimpleNamespace(Files=types.SimpleNamespace(SupportPath=str(support))),
GetVariable=document.GetVariable,
SetVariable=document.SetVariable,
)
monkeypatch.setattr(module, "_acad_doc", lambda: document)
monkeypatch.setattr(module, "_acad_app", lambda: app)
@@ -1626,3 +1628,91 @@ async def test_truetype_face_reads_family_and_subfamily(tmp_path):
assert _truetype_face(windows_arial) == ("Arial", False, False)
assert _com_font_path(str(regular)) == regular
assert _com_font_path(str(tmp_path / "missing.ttf")) is None
# ── drawing_apply_standard ──────────────────────────────────────────────────
async def test_apply_iso_then_dimension_linear_carries_iso25(backend):
from engineering.standards.apply import apply_standard
result = await apply_standard(backend, "iso")
assert result["standard"] == "iso"
assert result["dimstyle"] == {"name": "ISO-25", "created": True, "current": True}
assert result["textstyle"] == {"name": "ISOCP", "created": True, "current": True}
assert result["settings"]["changed"] == {"INSUNITS": [6, 4]}, "ezdxf.new() starts in metres"
assert result["layers"]["layer_set"] == "mech"
assert result["layers"]["layers"]["DIM"] in ("created", "exists")
dim = await backend.dimension_linear(0, 0, 33.333, 0, 16, -30)
assert _rendered(backend, dim.handle) == ("33,33", 2.5, [2.5])
assert backend._doc.header["$TEXTSTYLE"] == "ISOCP"
assert await backend.system_get_variable("LUNITS") == 2
assert await backend.system_get_variable("INSUNITS") == 4
async def test_apply_ansi_then_dimension_linear_carries_ansi(backend):
from engineering.standards.apply import apply_standard
result = await apply_standard(backend, "ANSI", layers=False)
assert result["dimstyle"]["name"] == "ANSI" and result["textstyle"]["name"] == "ROMANS"
assert result["layers"] is None
dim = await backend.dimension_linear(0, 0, 33.333, 0, 16, -30)
assert _rendered(backend, dim.handle) == ("33.33", 3.0, [3.0])
async def test_second_apply_is_idempotent_and_reports_nothing_created(backend):
from engineering.standards.apply import apply_standard
await apply_standard(backend, "iso")
again = await apply_standard(backend, "iso")
assert again["dimstyle"]["created"] is False and again["textstyle"]["created"] is False
assert again["settings"]["changed"] == {}
assert set(again["layers"]["layers"].values()) == {"exists"}
swapped = await apply_standard(backend, "ansi", layers=False)
assert swapped["dimstyle"]["created"] is True
assert (await backend.dimstyle_list())[0]["name"] == "ANSI"
back = await apply_standard(backend, "iso", layers=False, units=False)
assert back["dimstyle"]["created"] is False and back["settings"] == {
"changed": {},
"applied": False,
}
assert backend._doc.header["$DIMSTYLE"] == "ISO-25"
async def test_apply_refuses_an_unknown_standard_before_writing(backend):
from engineering.standards.apply import apply_standard
with pytest.raises(ValueError, match="standard"):
await apply_standard(backend, "din")
with pytest.raises(TypeError, match="layers"):
await apply_standard(backend, "iso", layers="yes")
assert [r["name"] for r in await backend.dimstyle_list()] == ["Standard"]
assert await backend.system_get_variable("INSUNITS") == 6
async def test_apply_standard_tool_is_registered_in_the_styles_group(backend):
import server
names = {t.name for t in await server._registered_tools() if getattr(t, "name", None)}
assert "drawing_apply_standard" in names
styles_group = set((await server._tool_groups())["styles"])
assert styles_group == STYLE_TOOLS | {"drawing_apply_standard"}, "SECTION 18 is exactly ten"
result = await server.drawing_apply_standard(standard="iso", layers=False, ctx=_Ctx(backend))
assert result["dimstyle"]["created"] is True
async def test_com_apply_standard_creates_both_styles_and_sets_units(com_backend):
from engineering.standards.apply import apply_standard
backend, document = com_backend
document.variables.update(
{"INSUNITS": 1, "LUNITS": 4, "AUNITS": 0, "LTSCALE": 1.0, "DIMSCALE": 1.0}
)
result = await apply_standard(backend, "iso", layers=False)
assert result["dimstyle"]["created"] is True and result["textstyle"]["created"] is True
assert result["settings"]["changed"] == {"INSUNITS": [1, 4], "LUNITS": [4, 2]}
names = [call[0] for call in document.calls]
assert names[0] == "TextStyles.Add" and "DimStyles.Add" in names
assert ("ActiveTextStyle", "ISOCP") in document.calls
assert document.ActiveDimStyle.Name == "ISO-25"
assert document.variables["DIMDSEP"] == "," and document.variables["INSUNITS"] == 4
+7 -5
View File
@@ -519,9 +519,11 @@ async def test_tool_group_sizes_are_unchanged():
tag is ranked first in `_GROUP_TAG_PRIORITY` so those tools file under
`pid` rather than under their secondary `query` / `create` tags. `styles`
appeared (0 -> 9) when track E's SECTION 18 opened with the dimension,
text and multileader style tools; the `style` tag sits ahead of `layer`
in `_GROUP_TAG_PRIORITY` so they never file under their secondary
`query` / `create` / `modify` tags. Every other number here has been
text and multileader style tools, then 9 -> 10 when
`drawing_apply_standard` (ISO or ANSI styles, units and layers in one
call) joined; the `style` tag sits ahead of `layer` and `drawing` in
`_GROUP_TAG_PRIORITY` so they never file under their secondary
`query` / `create` / `modify` / `drawing` tags. Every other number here has been
unchanged since the snapshot was taken.
"""
sizes = {label: len(names) for label, names in (await server._tool_groups()).items()}
@@ -541,11 +543,11 @@ async def test_tool_group_sizes_are_unchanged():
"pid": 9,
"premium": 12,
"solids": 5,
"styles": 9,
"styles": 10,
"system": 7,
"templates": 2,
"transactions": 3,
"validation": 1,
"view": 4,
}
assert sum(sizes.values()) == 175
assert sum(sizes.values()) == 176