from unittest.mock import MagicMock, patch from styles.simple import SimpleStyle def _make_style(): calls = [] return SimpleStyle(lambda on: calls.append(on)), calls def test_simple_ignores_unrelated_config(): # SimpleStyle must swallow style-specific kwargs it doesn't use (e.g. # music_file belongs to blink), so the runner can pass config uniformly. style, _ = _make_style() style = SimpleStyle(lambda on: None, music_file="ignored.mp3") with patch("styles.simple.pygame", MagicMock()): style.start() assert style.update(0.0, False) is True def test_simple_keeps_ringing_when_not_pressed(): style, _ = _make_style() with patch("styles.simple.pygame", MagicMock()): style.start() assert style.update(0.0, False) is True def test_simple_stops_on_first_press(): style, _ = _make_style() with patch("styles.simple.pygame", MagicMock()): style.start() assert style.update(0.0, True) is False # press -> stop def test_simple_led_solid_on(): style, calls = _make_style() with patch("styles.simple.pygame", MagicMock()): style.start() style.update(0.0, False) assert calls == [True, True] # start sets LED on; update keeps it on def test_simple_beeps_on_interval(): style, _ = _make_style() with patch("styles.simple.pygame", MagicMock()) as pg: style.start() style.update(100.0, False) # first tick -> beep assert pg.mixer.Sound.return_value.play.called pg.mixer.Sound.return_value.play.reset_mock() style.update(100.4, False) # before interval -> no beep assert not pg.mixer.Sound.return_value.play.called style.update(100.5, False) # at interval -> beep assert pg.mixer.Sound.return_value.play.called def test_simple_never_plays_music(): style, _ = _make_style() with patch("styles.simple.pygame", MagicMock()) as pg: style.start() style.update(0.0, False) style.update(0.0, True) # press -> stop assert not pg.mixer.music.play.called assert not pg.mixer.music.load.called