`add_diameter_dim` / `add_radius_dim` measure to the point they are handed; `leader_length` is a text placement. The ezdxf backend passed `centre + (radius + leader)` as that point, so the leader became part of the measurement: a true 40 mm bore was dimensioned 60 at the default `leader_length=10`, and 108 at 34. Radius callouts were `leader_length` too large the same way. This is the worst class of defect for this project -- a wrong number, at default settings, on the one part of a drawing that exists to carry numbers -- and it shipped in v1.4.0 and earlier. The size now comes from `radius` and `location` only places the text. The live COM backend was never affected: ActiveX's AddDimDiametric takes the two chord points and the leader length as separate arguments. The two engines had been disagreeing by 2 x leader_length on the same call. Found while building the drawing for the new README, whose own bore callout was wrong. Two checks added to correctness_suite.py; both report fail -> pass against v1.4.0, not miss -> pass, which is what separates a repaired defect from new capability in that lane. A/B is now 21/26 -> 26/26, five fixed, zero regressed. README rewritten from scratch - Hero is a real ISO A3 sheet the server drew: m6 z24 involute spur gear, DIN 6885 keyed bore, section A-A, ISO 129 dimensions, ISO 286 H7 fit, ISO 7200 title block, 56 entities, drawing_critique clean. New scripts/render_readme_showcase.py rebuilds it, and the tool-call sequence that produces it is printed in the page. - Star history chart, badge row, capability matrix, five evidence lanes, and a "what this release is bad at" section carrying the 28% throughput regression. - Every image and repo link is now an absolute URL: README.md is the PyPI long description, where relative paths 404. Corrections this work forced, all measured - The df=0 example was wrong. FILLET is already in entity_fillet's own text; the commands that genuinely scored zero are WBLOCK, PEDIT, OVERKILL, LAYTRANS and MATCHPROP. - 40,305 tokens is the tools/list wire payload; ~25,143 is the part forwarded to the model. The old wording said "of schema", which is neither. - `--tokenizer anthropic` needs a package and credentials this repo does not lock, and refuses rather than falling back. Said so. - Discovery ranks over the 149-tool advertised catalog, not the 154 registered. - Five middlewares, not four; the fifth is what makes refusals machine-readable. - Five of the 27 capability keys are environment-dependent, so the matrix carries footnotes instead of bare ticks. - "Every coordinate is WCS" has one deliberate exception: TEXT rotation. - render_live_chart's axis still said "fixed 10-task matrix" while our bar came from v3's fifteen. Each bar now carries its own matrix. - .env.example said MAX_UNDO_STACK=50 (code: 5) and omitted four real variables, two of them the remote-HTTP controls. - server.json described an empty ALLOWED_PATHS as blocking access. It disables the allowlist. - server.py called the lean profile ~46 tools; it is 47. - backends/capability.py cited a test file that does not exist. 1249 passed, 1 xfailed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
"""Tests for dimension creation via ezdxf backend."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
pytestmark = pytest.mark.asyncio
|
|
|
|
|
|
async def test_dimension_linear(backend):
|
|
info = await backend.dimension_linear(0, 0, 100, 0, 50, 20, rotation=0)
|
|
assert info.handle
|
|
assert info.type == "DIMENSION"
|
|
|
|
|
|
async def test_dimension_aligned(backend):
|
|
info = await backend.dimension_aligned(0, 0, 100, 50, 50, 60)
|
|
assert info.handle
|
|
assert info.type == "DIMENSION"
|
|
|
|
|
|
async def test_dimension_angular(backend):
|
|
info = await backend.dimension_angular(0, 0, 100, 0, 0, 100, 50, 50)
|
|
assert info.handle
|
|
assert info.type == "DIMENSION"
|
|
|
|
|
|
async def test_dimension_radius(backend):
|
|
await backend.entity_create_circle(50, 50, 30)
|
|
info = await backend.dimension_radius(50, 50, 80, 50, leader_length=15)
|
|
assert info.handle
|
|
assert info.type == "DIMENSION"
|
|
|
|
|
|
async def test_dimension_diameter(backend):
|
|
info = await backend.dimension_diameter(20, 50, 80, 50, leader_length=10)
|
|
assert info.handle
|
|
assert info.type == "DIMENSION"
|
|
|
|
|
|
# ── the number on the dimension must be the number on the drawing ───────────
|
|
#
|
|
# `add_diameter_dim`/`add_radius_dim` take `mpoint` as a point ON the circle;
|
|
# `leader_length` is where the *text* sits. Passing `centre + (radius + leader)`
|
|
# as `mpoint` makes ezdxf measure to that point, so every diameter came out
|
|
# `2 x leader_length` too big and every radius `leader_length` too big -- at
|
|
# DEFAULT settings, silently, on a drawing whose whole purpose is the number.
|
|
# The live COM backend was never wrong here: AddDimDiametric takes the two
|
|
# chord points and the leader length as separate arguments.
|
|
|
|
|
|
async def test_a_diameter_dimension_measures_the_diameter(backend):
|
|
"""Two ends of a diameter of a true 40 mm circle."""
|
|
info = await backend.dimension_diameter(-20, 0, 20, 0)
|
|
|
|
dim = backend._doc.entitydb.get(info.handle)
|
|
assert dim.get_measurement() == pytest.approx(40.0)
|
|
|
|
|
|
async def test_the_leader_length_moves_the_text_not_the_measurement(backend):
|
|
"""The regression in one assertion: leader_length must not be measurable."""
|
|
near = await backend.dimension_diameter(-20, 0, 20, 0, leader_length=5.0)
|
|
far = await backend.dimension_diameter(-20, 0, 20, 0, leader_length=40.0)
|
|
|
|
measurements = [
|
|
backend._doc.entitydb.get(near.handle).get_measurement(),
|
|
backend._doc.entitydb.get(far.handle).get_measurement(),
|
|
]
|
|
assert measurements == pytest.approx([40.0, 40.0])
|
|
|
|
|
|
async def test_a_radius_dimension_measures_the_radius(backend):
|
|
info = await backend.dimension_radius(0, 0, 20, 0)
|
|
|
|
dim = backend._doc.entitydb.get(info.handle)
|
|
assert dim.get_measurement() == pytest.approx(20.0)
|
|
|
|
|
|
async def test_a_radius_measurement_ignores_the_leader_too(backend):
|
|
near = await backend.dimension_radius(0, 0, 20, 0, leader_length=5.0)
|
|
far = await backend.dimension_radius(0, 0, 20, 0, leader_length=40.0)
|
|
|
|
measurements = [
|
|
backend._doc.entitydb.get(near.handle).get_measurement(),
|
|
backend._doc.entitydb.get(far.handle).get_measurement(),
|
|
]
|
|
assert measurements == pytest.approx([20.0, 20.0])
|
|
|
|
|
|
async def test_an_off_axis_diameter_is_measured_from_its_own_chord(backend):
|
|
"""The two points are a diameter at any angle, not just horizontal."""
|
|
info = await backend.dimension_diameter(0, 0, 30, 40, leader_length=12.0)
|
|
|
|
dim = backend._doc.entitydb.get(info.handle)
|
|
assert dim.get_measurement() == pytest.approx(50.0)
|