- ruff profile in pyproject (E/W/F/I/B/RUF); clean src/ + tests/ - remove dead code: threaded_len/s/d/coat/first_rec_for_size, self.cat in gui - 59 public re-exports added to __all__ (sorted) - renamed l->ln (E741), zip(strict=True), split long lines, [*list, x] (RUF005) - CI: quality job (ruff), test runs tests/ -k 'not gen_all' w/ coverage - README rewritten (commands, API modules, tests/lint/coverage, CI) - docs/tasks.md: P4 recorded - 136 passed, 3 deselected (regen); ruff: all checks passed
40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
"""Tests for mass computation (STEP volume * density)."""
|
|
from __future__ import annotations
|
|
|
|
from fastengen.mass import _parse_density, mass_of
|
|
from fastengen.model import generate_bolt, generate_nut, generate_washer
|
|
from fastengen.standard import get_bolt, get_nut, get_washer
|
|
|
|
|
|
def test_density_defaults_to_steel():
|
|
assert _parse_density("Сталь") == 7.85
|
|
assert _parse_density("Сталь 8.8") == 7.85
|
|
assert _parse_density("Сталь 65Г") == 7.85
|
|
assert _parse_density("") == 7.85
|
|
|
|
|
|
def test_nut_mass_reasonable(tmp_path):
|
|
p = str(tmp_path / "nut_M12.step")
|
|
generate_nut(get_nut("M12"), p)
|
|
m = mass_of(p, "Сталь 8")
|
|
assert m is not None
|
|
# M12 hex nut (GOST 5915-70) ~ 20-25 g
|
|
assert 15.0 < m < 30.0, f"nut mass {m}g out of expected range"
|
|
|
|
|
|
def test_bolt_mass_reasonable(tmp_path):
|
|
p = str(tmp_path / "bolt_M12_60.step")
|
|
generate_bolt(get_bolt("M12", 60), p)
|
|
m = mass_of(p, "Сталь 8.8")
|
|
assert m is not None
|
|
# M12x60 bolt (GOST 7805-70) ~ 70-75 g
|
|
assert 55.0 < m < 95.0, f"bolt mass {m}g out of expected range"
|
|
|
|
|
|
def test_washer_mass_positive(tmp_path):
|
|
p = str(tmp_path / "washer_M12.step")
|
|
generate_washer(get_washer("M12"), p)
|
|
m = mass_of(p, "Сталь")
|
|
assert m is not None
|
|
assert m > 0.0
|