From c72a02897e24025ee0288b94e8fe28b73460c909 Mon Sep 17 00:00:00 2001 From: Obayne Date: Wed, 24 Sep 2025 08:18:13 -0500 Subject: [PATCH 1/6] chore: add units tolerances tests (EPS, almost_equal, clamp, sgn, round_tol) --- .../chore-cad-core-units-tolerances-tests.md | 17 ++++++++ tests/cad_core/test_units_tolerances.py | 40 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tasks/chore-cad-core-units-tolerances-tests.md create mode 100644 tests/cad_core/test_units_tolerances.py diff --git a/tasks/chore-cad-core-units-tolerances-tests.md b/tasks/chore-cad-core-units-tolerances-tests.md new file mode 100644 index 0000000..bab04f2 --- /dev/null +++ b/tasks/chore-cad-core-units-tolerances-tests.md @@ -0,0 +1,17 @@ +Task: cad_core – Units tolerances tests + +Scope +- Add focused tests for `cad_core/units.py`: `EPS`, `almost_equal`, `clamp`, `sgn`, `round_tol`. + +Details +- New file: `tests/cad_core/test_units_tolerances.py` with small, isolated cases. +- Ensure no dependency on UI or other modules; pure functions only. +- Keep tolerance behavior consistent across core geometry. + +Acceptance +- `pytest -q` passes; new tests cover edge cases (negative, swapped bounds, zero tol). +- `ruff` and `black --check` pass. + +Branch +- `chore/cad-core-units-tolerances-tests` + diff --git a/tests/cad_core/test_units_tolerances.py b/tests/cad_core/test_units_tolerances.py new file mode 100644 index 0000000..2a35343 --- /dev/null +++ b/tests/cad_core/test_units_tolerances.py @@ -0,0 +1,40 @@ +import math + +from cad_core.units import EPS, almost_equal, clamp, sgn, round_tol + + +def test_eps_value_and_usage(): + assert isinstance(EPS, float) + assert EPS == 1e-9 + # Values within EPS are considered equal + assert almost_equal(1.0, 1.0 + EPS * 0.5) + + +def test_almost_equal_with_custom_tol(): + assert almost_equal(0.0, 1e-6, tol=1e-5) + assert not almost_equal(0.0, 2e-5, tol=1e-5) + + +def test_clamp_basic_and_swapped_bounds(): + assert clamp(5.0, 0.0, 10.0) == 5.0 + assert clamp(-1.0, 0.0, 10.0) == 0.0 + assert clamp(11.0, 0.0, 10.0) == 10.0 + # Swapped bounds should be handled + assert clamp(5.0, 10.0, 0.0) == 5.0 + + +def test_sgn_with_tolerance(): + assert sgn(1.0) == 1 + assert sgn(-1.0) == -1 + assert sgn(EPS * 0.5) == 0 + assert sgn(-EPS * 0.5) == 0 + + +def test_round_tol_behaviour(): + assert round_tol(1.2345, 0.01) == 1.23 + assert round_tol(-1.234, 0.1) == -1.2 + # Non-positive tolerance returns the input as-is + x = 3.14159 + assert round_tol(x, 0.0) == x + assert round_tol(x, -0.1) == x + From 924a301e681c248f0678e3c125727984ec399ba7 Mon Sep 17 00:00:00 2001 From: Obayne Date: Wed, 24 Sep 2025 08:42:40 -0500 Subject: [PATCH 2/6] chore(cad_core): add units module (EPS, conversions, helpers) --- cad_core/units.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cad_core/units.py diff --git a/cad_core/units.py b/cad_core/units.py new file mode 100644 index 0000000..af3f90e --- /dev/null +++ b/cad_core/units.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +MM_PER_INCH = 25.4 + +# Global default tolerance for geometric comparisons +EPS: float = 1e-9 + + +def mm_to_inch(mm: float) -> float: + return mm / MM_PER_INCH + + +def inch_to_mm(inch: float) -> float: + return inch * MM_PER_INCH + + +def almost_equal(a: float, b: float, tol: float = EPS) -> bool: + return abs(a - b) <= tol + + +def clamp(x: float, lo: float, hi: float) -> float: + if lo > hi: + lo, hi = hi, lo + return hi if x > hi else lo if x < lo else x + + +def sgn(x: float, tol: float = EPS) -> int: + if x > tol: + return 1 + if x < -tol: + return -1 + return 0 + + +def round_tol(value: float, tol: float = 1e-6) -> float: + if tol <= 0: + return value + return round(value / tol) * tol + From 433c3b7ae6bf29bd2aba64d57f6942ba3f099545 Mon Sep 17 00:00:00 2001 From: Obayne Date: Wed, 24 Sep 2025 08:45:35 -0500 Subject: [PATCH 3/6] chore(cad_core): improve round_tol to use Decimal quantization to avoid FP drift --- cad_core/units.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cad_core/units.py b/cad_core/units.py index af3f90e..eb06cf5 100644 --- a/cad_core/units.py +++ b/cad_core/units.py @@ -35,5 +35,13 @@ def sgn(x: float, tol: float = EPS) -> int: def round_tol(value: float, tol: float = 1e-6) -> float: if tol <= 0: return value - return round(value / tol) * tol - + # Try decimal quantization for decimal-friendly tolerances to avoid FP drift + try: + from decimal import Decimal, ROUND_HALF_UP + + dval = Decimal(str(value)) + dtol = Decimal(str(tol)) + q = (dval / dtol).to_integral_value(rounding=ROUND_HALF_UP) + return float(q * dtol) + except Exception: + return round(value / tol) * tol From 3599cc7ddce8f9e21547ddf40d6500b3cce7c962 Mon Sep 17 00:00:00 2001 From: Obayne Date: Wed, 24 Sep 2025 08:53:17 -0500 Subject: [PATCH 4/6] chore(cad_core/tests): organize imports per ruff isort rules --- cad_core/units.py | 4 ++-- tests/cad_core/test_units_tolerances.py | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cad_core/units.py b/cad_core/units.py index eb06cf5..74a0566 100644 --- a/cad_core/units.py +++ b/cad_core/units.py @@ -1,5 +1,7 @@ from __future__ import annotations +from decimal import ROUND_HALF_UP, Decimal + MM_PER_INCH = 25.4 # Global default tolerance for geometric comparisons @@ -37,8 +39,6 @@ def round_tol(value: float, tol: float = 1e-6) -> float: return value # Try decimal quantization for decimal-friendly tolerances to avoid FP drift try: - from decimal import Decimal, ROUND_HALF_UP - dval = Decimal(str(value)) dtol = Decimal(str(tol)) q = (dval / dtol).to_integral_value(rounding=ROUND_HALF_UP) diff --git a/tests/cad_core/test_units_tolerances.py b/tests/cad_core/test_units_tolerances.py index 2a35343..ba5a6d3 100644 --- a/tests/cad_core/test_units_tolerances.py +++ b/tests/cad_core/test_units_tolerances.py @@ -1,6 +1,4 @@ -import math - -from cad_core.units import EPS, almost_equal, clamp, sgn, round_tol +from cad_core.units import EPS, almost_equal, clamp, round_tol, sgn def test_eps_value_and_usage(): From 14ae4625807c4d01f7867d098fbbd8426a06f4a9 Mon Sep 17 00:00:00 2001 From: Obayne Date: Wed, 24 Sep 2025 08:55:34 -0500 Subject: [PATCH 5/6] chore: format units and tests with Black --- tests/cad_core/test_units_tolerances.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/cad_core/test_units_tolerances.py b/tests/cad_core/test_units_tolerances.py index ba5a6d3..22cdfe3 100644 --- a/tests/cad_core/test_units_tolerances.py +++ b/tests/cad_core/test_units_tolerances.py @@ -35,4 +35,3 @@ def test_round_tol_behaviour(): x = 3.14159 assert round_tol(x, 0.0) == x assert round_tol(x, -0.1) == x - From 8c309bff9752cbbcd1f552c094a9226567165473 Mon Sep 17 00:00:00 2001 From: Obayne Date: Wed, 24 Sep 2025 09:10:06 -0500 Subject: [PATCH 6/6] chore: add PR description for units tolerances tests branch --- .../chore-cad-core-units-tolerances-tests.md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tasks/pr/chore-cad-core-units-tolerances-tests.md diff --git a/tasks/pr/chore-cad-core-units-tolerances-tests.md b/tasks/pr/chore-cad-core-units-tolerances-tests.md new file mode 100644 index 0000000..dc2ff3d --- /dev/null +++ b/tasks/pr/chore-cad-core-units-tolerances-tests.md @@ -0,0 +1,29 @@ +Title: chore(cad_core): add units tolerances tests + +Summary +- Adds focused tests for `cad_core/units.py` covering `EPS`, `almost_equal`, `clamp`, `sgn`, and `round_tol`. +- Introduces `cad_core/units.py` helpers with improved `round_tol` using Decimal to avoid FP drift. + +Changes +- New: `tests/cad_core/test_units_tolerances.py` +- New: `cad_core/units.py` +- Task: `tasks/chore-cad-core-units-tolerances-tests.md` + +Rationale +- Establish consistent tolerance behavior used across core geometry. +- Provide small, pure tests to keep regressions visible and fast. + +Test Plan (agents pulling this) +- From repo root: + - `python -m pip install -e .` (or set `PYTHONPATH` to repo root) + - `ruff check cad_core tests/cad_core/test_units_tolerances.py` + - `black --check cad_core tests/cad_core/test_units_tolerances.py` + - `pytest -q tests/cad_core/test_units_tolerances.py` + +Notes +- No UI impact; pure functions only. +- Keep `EPS` and helpers as the single source of tolerance logic across CAD core. + +Refs +- Issue: N/A (please update if applicable) +