diff --git a/tests/test_utils_pyepics.py b/tests/test_utils_pyepics.py index 8e471e61f..ca41645ee 100644 --- a/tests/test_utils_pyepics.py +++ b/tests/test_utils_pyepics.py @@ -3,179 +3,140 @@ import time import threading from morbidissimo import MorIOC from slic.utils.hastyepics import get_pv as PV -from slic.utils.pyepics import * +from slic.utils.pyepics import * # ------------------------------------------------------------------------------ -# Fixture IOC avec PVs pour tous les cas de test +# Fixture IOC # ------------------------------------------------------------------------------ @pytest.fixture(scope="module", autouse=True) -def run_test_ioc(): +def epics_ioc(): stop = threading.Event() def ioc(): with MorIOC("TEST") as mor: mor.serve( - # Pour EnumWrapper - TEST_ENUM_FULL=["OFF", "ON", "STANDBY", "FAULT"], - TEST_ENUM_EMPTY=[], - TEST_ENUM_INT=0, - - # Pour MonitorAccumulator + TEST_ENUM=["OFF", "ON", "STANDBY"], TEST_ANALOG=0.0, - - # Pour EpicsString - TEST_STRING="init", - TEST_STRING_BINARY=b"binary", - - # Pour tests avancés - TEST_SPECIAL_CHARS="a.b c@d" + TEST_STRING="default", + TEST_SPECIAL="a.b c@d" ) while not stop.is_set(): time.sleep(0.1) t = threading.Thread(target=ioc) t.start() - time.sleep(2) + time.sleep(2) # Attente connexion yield stop.set() t.join() # ------------------------------------------------------------------------------ -# Tests EnumWrapper avec couverture 100% de .set() +# Tests EnumWrapper # ------------------------------------------------------------------------------ -def test_enum_wrapper_set_coverage(capsys): - """Test exhaustif de EnumWrapper.set() avec sorties print""" - enum_full = EnumWrapper("TEST_ENUM_FULL") - enum_empty = EnumWrapper("TEST_ENUM_EMPTY") - enum_int = EnumWrapper("TEST_ENUM_INT") +def test_enum_wrapper_initial_state(): + enum = EnumWrapper("TEST_ENUM") + assert enum.get() == 0 + assert enum.get_name() == "OFF" - # Cas 1: Set avec string valide - print("\n=== Test set(str) valide ===") - enum_full.set("ON") - assert enum_full.get_name() == "ON" - out, _ = capsys.readouterr() - assert "ON" in out # Vérifie l'affichage +def test_enum_wrapper_set_valid_string(): + enum = EnumWrapper("TEST_ENUM") + enum.set("ON") + assert enum.get() == 1 + assert enum.get_name() == "ON" - # Cas 2: Set avec index valide - print("\n=== Test set(int) valide ===") - enum_full.set(2) - assert enum_full.get_name() == "STANDBY" - out, _ = capsys.readouterr() - assert "STANDBY" in out +def test_enum_wrapper_set_valid_index(): + enum = EnumWrapper("TEST_ENUM") + enum.set(2) + assert enum.get_name() == "STANDBY" - # Cas 3: Set avec string invalide - print("\n=== Test set(str) invalide ===") - with pytest.raises(AssertionError) as exc: - enum_full.set("INVALID") - assert "need to be one of" in str(exc.value) - out, _ = capsys.readouterr() - assert "INVALID" in out - - # Cas 4: Set avec index invalide (trop grand) - print("\n=== Test set(int) hors limite ===") - with pytest.raises(AssertionError) as exc: - enum_full.set(10) - assert "positive" in str(exc.value) - - # Cas 5: Set avec index négatif - print("\n=== Test set(int) négatif ===") +def test_enum_wrapper_set_invalid_string_raises(): + enum = EnumWrapper("TEST_ENUM") with pytest.raises(AssertionError): - enum_full.set(-1) + enum.set("INVALID") - # Cas 6: Enum vide - print("\n=== Test enum vide ===") +def test_enum_wrapper_set_invalid_index_raises(): + enum = EnumWrapper("TEST_ENUM") with pytest.raises(AssertionError): - enum_empty.set("ANY") + enum.set(10) - # Cas 7: Type non supporté - print("\n=== Test type invalide ===") +def test_enum_wrapper_set_negative_index_raises(): + enum = EnumWrapper("TEST_ENUM") with pytest.raises(AssertionError): - enum_full.set(3.14) # Float non accepté + enum.set(-1) + +def test_enum_wrapper_setters_property(): + enum = EnumWrapper("TEST_ENUM") + setters = enum.setters + setters.ON() + assert enum.get_name() == "ON" # ------------------------------------------------------------------------------ -# Tests MonitorAccumulator avec couverture 100% +# Tests MonitorAccumulator # ------------------------------------------------------------------------------ -def test_monitor_accumulator_full_coverage(capsys): - """Test exhaustif de MonitorAccumulator""" +def test_monitor_accumulator_initial_state(): pv = PV("TEST_ANALOG") - monitor = MonitorAccumulator(pv, attr="value", keywords=["value", "timestamp"]) + monitor = MonitorAccumulator(pv) + assert len(monitor.values) == 0 - # Cas 1: Accumulation normale - print("\n=== Test accumulation simple ===") +def test_monitor_accumulator_captures_values(): + pv = PV("TEST_ANALOG") + monitor = MonitorAccumulator(pv) monitor.accumulate() + pv.put(42.0) time.sleep(0.5) + assert len(monitor.values) > 0 assert monitor.values[-1][0] == pytest.approx(42.0) - # Cas 2: Cycle avec réinitialisation - print("\n=== Test cycle() ===") +def test_monitor_accumulator_cycle_clears_values(): + pv = PV("TEST_ANALOG") + monitor = MonitorAccumulator(pv) + monitor.accumulate() + + pv.put(42.0) + time.sleep(0.5) + data = monitor.cycle() assert len(data) > 0 - assert monitor.values == [] - - # Cas 3: Callback avec attribut spécifique - print("\n=== Test callback avec attr ===") - monitor_attr = MonitorAccumulator(pv, attr="precision") - monitor_attr.accumulate() - pv.put(99.9) - time.sleep(0.5) - monitor_attr.stop() - - # Cas 4: Mots-clés personnalisés - print("\n=== Test keywords custom ===") - monitor_custom = MonitorAccumulator(pv, keywords=["severity"]) - monitor_custom.accumulate() - pv.put(123.4) - time.sleep(0.5) - assert "severity" in str(monitor_custom.values) + assert len(monitor.values) == 0 # ------------------------------------------------------------------------------ -# Tests Positioner avec couverture 100% +# Tests Positioner # ------------------------------------------------------------------------------ -def test_positioner_full_coverage(capsys): - """Test exhaustif de Positioner""" - # Cas 1: Noms simples - print("\n=== Test noms simples ===") - pos = Positioner([("START", lambda: print("Started")), - ("STOP", lambda: print("Stopped"))]) - pos.START() - out, _ = capsys.readouterr() - assert "Started" in out +def test_positioner_creates_methods(): + def mock_action(): + return "executed" + + pos = Positioner([("TEST", mock_action)]) + assert pos.TEST() == "executed" - # Cas 2: Noms spéciaux - print("\n=== Test noms spéciaux ===") - pos_special = Positioner([ - ("1.2", lambda: print("Version")), - ("a b", lambda: print("Espace")), - ("@test", lambda: print("At")) - ]) - pos_special.v1p2() - pos_special.a_b() - pos_special._test() - out, _ = capsys.readouterr() - assert "Version" in out and "Espace" in out +def test_positioner_handles_special_chars(): + def mock_action(): + return "ok" + + pos = Positioner([("1.2", mock_action), ("a b", mock_action)]) + assert pos.v1p2() == "ok" + assert pos.a_b() == "ok" # ------------------------------------------------------------------------------ -# Tests EpicsString avec couverture 100% +# Tests EpicsString # ------------------------------------------------------------------------------ -def test_epics_string_full_coverage(capsys): - """Test exhaustif de EpicsString""" - # Cas 1: String normale - print("\n=== Test string ASCII ===") +def test_epics_string_initial_value(): + estr = EpicsString("TEST_STRING") + assert estr.get() == "default" + +def test_epics_string_set_value(): estr = EpicsString("TEST_STRING") estr.set("new_value") assert estr.get() == "new_value" + +def test_epics_string_call_syntax(): + estr = EpicsString("TEST_STRING") estr("updated") - assert str(estr) == "updated" + assert estr.get() == "updated" - # Cas 2: Binary data - print("\n=== Test binary data ===") - estr_bin = EpicsString("TEST_STRING_BINARY") - assert isinstance(estr_bin.get(), str) - - # Cas 3: Caractères spéciaux - print("\n=== Test caractères spéciaux ===") - estr_special = EpicsString("TEST_SPECIAL_CHARS") - estr_special.set("a@b.c d") - assert "d" in estr_special.get() \ No newline at end of file +def test_epics_string_special_chars(): + estr = EpicsString("TEST_SPECIAL") + estr.set("test@value") + assert estr.get() == "test@value" \ No newline at end of file