import pytest from cymsim.config import (Hit, MalletExciter, SimulationConfig, StickExciter, default_config) def test_yaml_round_trip(tmp_path): cfg = default_config("stick") cfg.hits.append(Hit(time=0.5, r=0.1, phi=1.0, velocity=3.0, exciter=MalletExciter(mass=0.2))) path = tmp_path / "c.yaml" cfg.to_yaml(path) back = SimulationConfig.from_yaml(path) assert back == cfg assert isinstance(back.hits[0].exciter, StickExciter) assert isinstance(back.hits[1].exciter, MalletExciter) assert back.imperfections.rim_warp_modes == (2, 3, 4, 5) def test_partial_dict_uses_defaults(): cfg = SimulationConfig.from_dict({"hits": [{"time": 0.1, "exciter": {"kind": "stick"}}], "numerics": {"duration": 0.5}}) assert cfg.hits[0].exciter == StickExciter() assert cfg.numerics.duration == 0.5 and cfg.material.E == 1.1e11 def test_errors(): with pytest.raises(ValueError): SimulationConfig.from_dict({"material": {"youngs": 1.0}}) with pytest.raises(ValueError): SimulationConfig.from_dict({"hits": [{"exciter": {"kind": "hammer"}}]}) cfg = default_config() cfg.hits[0].r = 0.23 with pytest.raises(ValueError): cfg.validate() cfg = default_config() cfg.hits = [] with pytest.raises(ValueError): cfg.validate() def test_examples_load(): import glob for path in glob.glob("examples/*.yaml"): SimulationConfig.from_yaml(path).validate()