| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- """
- Tests for the Theme Manager UI component (Story 7.11).
- """
- import pytest
- from pathlib import Path
- import tempfile
- from PyQt6.QtWidgets import QApplication
- from src.ui.theme_manager import (
- ThemeMode,
- ThemeColors,
- ThemeManager,
- LIGHT_COLORS,
- DARK_COLORS,
- get_theme_manager,
- )
- @pytest.fixture
- def app(qtbot):
- """Create QApplication for tests."""
- return QApplication.instance() or QApplication([])
- @pytest.fixture
- def clean_manager():
- """Create a fresh ThemeManager for testing."""
- # Reset singleton
- import src.ui.theme_manager as tm
- tm._theme_manager_instance = None
- manager = ThemeManager()
- return manager
- class TestThemeMode:
- """Tests for ThemeMode enum."""
- def test_theme_mode_values(self):
- """Test ThemeMode enum values."""
- assert ThemeMode.LIGHT.value == "light"
- assert ThemeMode.DARK.value == "dark"
- assert ThemeMode.AUTO.value == "auto"
- class TestThemeColors:
- """Tests for ThemeColors dataclass."""
- def test_light_colors_structure(self):
- """Test light colors have all required fields."""
- assert hasattr(LIGHT_COLORS, "window_bg")
- assert hasattr(LIGHT_COLORS, "window_text")
- assert hasattr(LIGHT_COLORS, "highlight")
- assert hasattr(LIGHT_COLORS, "success")
- assert hasattr(LIGHT_COLORS, "warning")
- assert hasattr(LIGHT_COLORS, "error")
- def test_dark_colors_structure(self):
- """Test dark colors have all required fields."""
- assert hasattr(DARK_COLORS, "window_bg")
- assert hasattr(DARK_COLORS, "window_text")
- assert hasattr(DARK_COLORS, "highlight")
- assert hasattr(DARK_COLORS, "success")
- assert hasattr(DARK_COLORS, "warning")
- assert hasattr(DARK_COLORS, "error")
- def test_light_and_dark_differ(self):
- """Test that light and dark themes are different."""
- assert LIGHT_COLORS.window_bg != DARK_COLORS.window_bg
- assert LIGHT_COLORS.window_text != DARK_COLORS.window_text
- class TestThemeManager:
- """Tests for ThemeManager."""
- def test_initialization(self, clean_manager):
- """Test manager initialization."""
- assert clean_manager.current_mode == ThemeMode.LIGHT
- def test_set_theme_light(self, clean_manager):
- """Test setting light theme."""
- clean_manager.set_theme(ThemeMode.LIGHT)
- assert clean_manager.current_mode == ThemeMode.LIGHT
- assert clean_manager.colors == LIGHT_COLORS
- def test_set_theme_dark(self, clean_manager):
- """Test setting dark theme."""
- clean_manager.set_theme(ThemeMode.DARK)
- assert clean_manager.current_mode == ThemeMode.DARK
- assert clean_manager.colors == DARK_COLORS
- def test_toggle_theme(self, clean_manager):
- """Test toggling between themes."""
- clean_manager.set_theme(ThemeMode.LIGHT)
- clean_manager.toggle_theme()
- assert clean_manager.current_mode == ThemeMode.DARK
- clean_manager.toggle_theme()
- assert clean_manager.current_mode == ThemeMode.LIGHT
- def test_generate_stylesheet(self, clean_manager):
- """Test stylesheet generation."""
- stylesheet = clean_manager.generate_stylesheet()
- assert isinstance(stylesheet, str)
- assert len(stylesheet) > 0
- assert "QWidget" in stylesheet
- assert "QPushButton" in stylesheet
- assert "QLineEdit" in stylesheet
- def test_stylesheet_contains_colors(self, clean_manager):
- """Test that stylesheet contains current theme colors."""
- clean_manager.set_theme(ThemeMode.DARK)
- stylesheet = clean_manager.generate_stylesheet()
- assert DARK_COLORS.window_bg in stylesheet
- assert DARK_COLORS.highlight in stylesheet
- def test_apply_to_application(self, app, clean_manager):
- """Test applying theme to application."""
- clean_manager.set_theme(ThemeMode.DARK)
- clean_manager.apply_to_application(app)
- # Stylesheet should be set
- assert app.styleSheet() != ""
- def test_get_color(self, clean_manager):
- """Test getting individual colors."""
- clean_manager.set_theme(ThemeMode.LIGHT)
- highlight = clean_manager.get_color("highlight")
- assert highlight == LIGHT_COLORS.highlight
- window_bg = clean_manager.get_color("window_bg")
- assert window_bg == LIGHT_COLORS.window_bg
- def test_adjust_color(self, clean_manager):
- """Test color adjustment."""
- # Lighten a color
- result = clean_manager._adjust_color("#3498db", 20)
- assert result.startswith("#")
- assert len(result) == 7
- # Darken a color
- result = clean_manager._adjust_color("#3498db", -20)
- assert result.startswith("#")
- assert len(result) == 7
- def test_custom_stylesheet(self, clean_manager, tmp_path):
- """Test loading custom stylesheet."""
- css_file = tmp_path / "custom.css"
- css_file.write_text("QPushButton { background-color: red; }")
- result = clean_manager.load_stylesheet_from_file(css_file)
- assert result is True
- assert "red" in clean_manager._custom_stylesheet
- def test_load_nonexistent_stylesheet(self, clean_manager):
- """Test loading non-existent stylesheet file."""
- result = clean_manager.load_stylesheet_from_file(Path("/nonexistent/file.css"))
- assert result is False
- def test_theme_changed_signal(self, app, clean_manager, qtbot):
- """Test that theme_changed signal is emitted."""
- signals = []
- def on_theme_changed(mode):
- signals.append(mode)
- clean_manager.theme_changed.connect(on_theme_changed)
- clean_manager.set_theme(ThemeMode.DARK)
- assert len(signals) == 1
- assert signals[0] == ThemeMode.DARK
- def test_set_custom_stylesheet(self, clean_manager):
- """Test setting custom stylesheet."""
- custom_css = "QPushButton { background: red; }"
- clean_manager.set_custom_stylesheet(custom_css)
- assert clean_manager._custom_stylesheet == custom_css
- class TestThemeManagerSingleton:
- """Tests for the singleton pattern."""
- def test_get_singleton(self):
- """Test getting singleton instance."""
- manager = get_theme_manager()
- assert manager is not None
- assert isinstance(manager, ThemeManager)
- def test_singleton_persistence(self):
- """Test that singleton returns same instance."""
- manager1 = get_theme_manager()
- manager2 = get_theme_manager()
- assert manager1 is manager2
|