from datetime import UTC, datetime import pytest from pydantic import ValidationError from lmpm.domain.experiment import ExperimentRecord, ProcessingParams, QualityMetrics from lmpm.domain.material import MaterialProperty def material_property(): return MaterialProperty( material_id="acrylic-001", name="Clear Acrylic", category="polymer", reflectivity=0.08, absorptivity=0.92, melting_point_c=160.0, thermal_conductivity_w_m_k=0.19, density_g_cm3=1.18, roughness_um=1.2, ) def test_material_property_accepts_valid_values(): material = material_property() assert material.material_id == "acrylic-001" assert material.absorptivity == pytest.approx(0.92) @pytest.mark.parametrize( ("field", "value"), [("reflectivity", -0.1), ("absorptivity", 1.1), ("density_g_cm3", 0)], ) def test_material_property_rejects_out_of_range_values(field, value): data = material_property().model_dump() data[field] = value with pytest.raises(ValidationError): MaterialProperty.model_validate(data) def test_experiment_record_round_trips_nested_models(): experiment = ExperimentRecord( experiment_id=1, material_id="acrylic-001", params=ProcessingParams( power_percent=45, scan_speed_mm_s=80, pulse_frequency_hz=20, ), metrics=QualityMetrics(kerf_width_mm=0.18), recorded_at=datetime.now(UTC), ) dumped = experiment.model_dump() restored = ExperimentRecord.model_validate(dumped) assert restored == experiment