Files
OpenClaw Coder 5ff5993d98
CI / quality (push) Canceled after 0s
CI / test (3.10) (push) Canceled after 0s
CI / test (3.11) (push) Canceled after 0s
CI / test (3.12) (push) Canceled after 0s
CI / build-check (push) Canceled after 0s
feat(P4): extend tests, coverage config, build license fix, tasks.md
- geometry: property guard hex nut across-flats (regression guard)
- gui tests: rewrite to ASCII + cover _type_name/_mass helper paths
- coverage: source=fastengen, omit gui.py (UI headless); total 87%
- build: license-files for setuptools, sdist+wheel OK
- tasks.md: P4 recorded
2026-11-11 17:12:54 +10:00

80 lines
2.7 KiB
Python

"""Tests for the tkinter GUI logic (window creation avoided: pure logic + helpers)."""
from __future__ import annotations
from fastengen.gui import MainWindow
def _fake_cat(records, models_dir):
"""Minimal catalog stub for GUI logic tests."""
class _Rec:
def __init__(self, r):
self.id = r["id"]
self.designation = r["designation"]
self.standard = r["standard"]
self.material = r["material"]
self.type = r["type"]
self.model_file = r.get("model_file", "bolt_M8_100.step")
self.attributes = r.get("attributes", {})
class _Cat:
def __init__(self, recs, md):
self._recs = [_Rec(r) for r in recs]
self.models_dir = md
self.catalog_path = ":memory:"
def all(self):
return list(self._recs)
def __len__(self):
return len(self._recs)
def __getitem__(self, rid):
for r in self._recs:
if r.id == rid:
return r
raise KeyError(rid)
def __contains__(self, rid):
return any(r.id == rid for r in self._recs)
return _Cat(records, models_dir)
def test_type_name_filter():
assert MainWindow._type_name("bolt", "all") is True
assert MainWindow._type_name("nut", "nut") is True
assert MainWindow._type_name("bolt", "bolt") is True
assert MainWindow._type_name("bolt_set", "bolt") is True
assert MainWindow._type_name("nut", "bolt") is False
assert MainWindow._type_name("self_tacker", "selftacker") is True
assert MainWindow._type_name("potay", "selftacker") is True
assert MainWindow._type_name("washer", "selftacker") is False
# screw / potay belong to selftacker filter
assert MainWindow._type_name("screw", "selftacker") is True
assert MainWindow._type_name("nut", "washer") is False
assert MainWindow._type_name("stud", "stud") is True
def _no_root_mass(r):
# _mass depends only on self.cat.models_dir; provide a stub carrying .cat
class _Stub:
cat = _fake_cat([], "out")
return MainWindow._mass(_Stub(), r)
def test_mass_helpers_paths():
# record without model_file -> mass_for_rec returns None -> em-dash
class _RecNoModel:
model_file = None
type = "bolt"
assert _no_root_mass(_RecNoModel()) == "\u2014"
# real model in out/ -> numeric string with per-piece mass (no crash)
real = _fake_cat([{"id": "bolt_M8_100", "designation": "Bolt M8",
"standard": "GOST 7805-70", "material": "Steel 8.8",
"type": "bolt", "attributes": {}}], "out")["bolt_M8_100"]
m = _no_root_mass(real)
assert isinstance(m, str)
assert m != "\u2014"
assert m.strip().replace(".", "").isdigit()