109 lines
3.3 KiB
Python
109 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from src.cad.parametric_parts import (
|
|
PART_CAPABILITIES,
|
|
export_parametric_part,
|
|
get_parametric_part_capability,
|
|
list_parametric_part_capability_manifests,
|
|
make_parametric_part,
|
|
validate_part_parameters,
|
|
)
|
|
|
|
|
|
EXPECTED_SIMPLECADAPI_PARTS = {
|
|
"spur_gear",
|
|
"straight_bevel_gear",
|
|
"helical_gear",
|
|
"herringbone_gear",
|
|
"spur_ring_gear",
|
|
"helical_ring_gear",
|
|
"herringbone_ring_gear",
|
|
"cycloidal_disc",
|
|
"spur_rack",
|
|
"helical_rack",
|
|
"herringbone_rack",
|
|
"ball_bearing",
|
|
"roller_chain_sprocket",
|
|
"bolt",
|
|
"nut",
|
|
"n_hole_flange",
|
|
"naca_propeller_blade",
|
|
"threaded_rod",
|
|
}
|
|
|
|
|
|
def test_catalog_covers_all_simplecadapi_formula_factories() -> None:
|
|
assert EXPECTED_SIMPLECADAPI_PARTS <= set(PART_CAPABILITIES)
|
|
manifests = list_parametric_part_capability_manifests()
|
|
assert len(manifests) >= len(EXPECTED_SIMPLECADAPI_PARTS)
|
|
by_id = {item["part_id"]: item for item in manifests}
|
|
assert by_id["spur_gear"]["api_path"] == "simplecadapi.std.gear.make_spur_gear_rsolid"
|
|
assert by_id["ball_bearing"]["result_kind"] == "assembly"
|
|
assert by_id["roller_chain_sprocket"]["available"] is True
|
|
|
|
|
|
def test_simplecadapi_is_vendored_under_project_src() -> None:
|
|
import simplecadapi
|
|
|
|
assert "/src/simplecadapi/" in str(Path(simplecadapi.__file__).as_posix()) + "/"
|
|
assert hasattr(simplecadapi.std.fastener, "make_bolt_rsolid")
|
|
assert hasattr(simplecadapi.std.bearing, "make_ball_bearing_rassembly")
|
|
assert hasattr(simplecadapi.std.chain, "make_roller_chain_sprocket_rsolid")
|
|
|
|
|
|
def test_validate_part_parameters_uses_underlying_signature() -> None:
|
|
params = validate_part_parameters(
|
|
"roller_chain_sprocket",
|
|
{
|
|
"n_teeth": 12,
|
|
"chain_pitch": 6.35,
|
|
"roller_diameter": 3.3,
|
|
"sprocket_thickness": 3.0,
|
|
},
|
|
)
|
|
assert params["bore_radius"] == 0.0
|
|
assert params["roller_clearance"] == 0.15
|
|
with pytest.raises(Exception, match="invalid_parametric_part_parameters"):
|
|
validate_part_parameters("roller_chain_sprocket", {"n_teeth": 12})
|
|
|
|
|
|
def test_dependency_report_marks_sketch_solver_backed_gears() -> None:
|
|
capability = get_parametric_part_capability("spur_gear")
|
|
assert "py_slvs" in capability.required_packages
|
|
if importlib.util.find_spec("py_slvs") is None:
|
|
assert capability.missing_packages() == ("py_slvs",)
|
|
|
|
|
|
def test_make_and_export_available_parametric_sprocket(tmp_path: Path) -> None:
|
|
shape = make_parametric_part(
|
|
"roller_chain_sprocket",
|
|
{
|
|
"n_teeth": 12,
|
|
"chain_pitch": 6.35,
|
|
"roller_diameter": 3.3,
|
|
"sprocket_thickness": 3.0,
|
|
"bore_radius": 1.2,
|
|
},
|
|
)
|
|
assert shape.get_volume() > 0
|
|
|
|
manifest = export_parametric_part(
|
|
"roller_chain_sprocket",
|
|
{
|
|
"n_teeth": 12,
|
|
"chain_pitch": 6.35,
|
|
"roller_diameter": 3.3,
|
|
"sprocket_thickness": 3.0,
|
|
"bore_radius": 1.2,
|
|
},
|
|
tmp_path,
|
|
)
|
|
assert Path(manifest["exported_files"]["step"]).exists()
|
|
assert Path(manifest["exported_files"]["model"]).exists()
|
|
assert manifest["geometry_summary"]["volume_mm3"] > 0
|