import unittest from unittest.mock import MagicMock, patch import math from src.theme_nerv_fx import CRTFilter, StatusFlicker, AlertPulsing class TestThemeNervFx(unittest.TestCase): @patch("src.theme_nerv_fx.imgui") def test_crt_filter_render(self, mock_imgui): # Setup mock_draw_list = MagicMock() mock_imgui.get_foreground_draw_list.return_value = mock_draw_list mock_imgui.get_color_u32.return_value = 0x12345678 overlay = CRTFilter() width, height = 800.0, 600.0 # Act overlay.render(width, height) # Assert mock_imgui.get_foreground_draw_list.assert_called_once() # height is 600, range(0, 600, 2) is 300 calls self.assertEqual(mock_draw_list.add_line.call_count, 300) # Vignette: v_steps = 15. height=600 is plenty for all insets. self.assertEqual(mock_draw_list.add_rect.call_count, 15) # Noise: 30 calls to add_rect_filled self.assertEqual(mock_draw_list.add_rect_filled.call_count, 30) # Verify some calls mock_draw_list.add_line.assert_any_call((0.0, 0.0), (800.0, 0.0), 0x12345678, 1.0) mock_draw_list.add_line.assert_any_call((0.0, 598.0), (800.0, 598.0), 0x12345678, 1.0) @patch("src.theme_nerv_fx.imgui") def test_crt_filter_disabled(self, mock_imgui): mock_draw_list = MagicMock() mock_imgui.get_foreground_draw_list.return_value = mock_draw_list overlay = CRTFilter() overlay.enabled = False overlay.render(800.0, 600.0) mock_imgui.get_foreground_draw_list.assert_not_called() @patch("src.theme_nerv_fx.time") def test_status_flicker_get_alpha(self, mock_time): flicker = StatusFlicker() # Test at multiple points in time to ensure range [0.7, 1.0] # sin(0) = 0 -> 0.85 mock_time.time.return_value = 0.0 self.assertAlmostEqual(flicker.get_alpha(), 0.85) # sin(pi/2) = 1 -> 1.0 mock_time.time.return_value = math.pi / 40.0 self.assertAlmostEqual(flicker.get_alpha(), 1.0) # sin(3pi/2) = -1 -> 0.7 mock_time.time.return_value = 3 * math.pi / 40.0 self.assertAlmostEqual(flicker.get_alpha(), 0.7) def test_alert_pulsing_update(self): pulse = AlertPulsing() self.assertFalse(pulse.active) pulse.update("error: something failed") self.assertTrue(pulse.active) pulse.update("Error: alert") self.assertTrue(pulse.active) pulse.update("idle") self.assertFalse(pulse.active) @patch("src.theme_nerv_fx.imgui") @patch("src.theme_nerv_fx.time") def test_alert_pulsing_render(self, mock_time, mock_imgui): mock_draw_list = MagicMock() mock_imgui.get_foreground_draw_list.return_value = mock_draw_list mock_imgui.get_color_u32.return_value = 0xFF0000FF pulse = AlertPulsing() pulse.active = True # sin(0) = 0 -> alpha = 0.05 + 0.15 * (0+1)/2 = 0.125 mock_time.time.return_value = 0.0 pulse.render(800.0, 600.0) mock_imgui.get_foreground_draw_list.assert_called() mock_draw_list.add_rect.assert_called_with((0.0, 0.0), (800.0, 600.0), 0xFF0000FF, 0.0, 0, 10.0) if __name__ == "__main__": unittest.main()