Files
thechart/tests/test_theme_manager.py
William Valentin df9738ab17
Some checks failed
Build and Push Docker Image / build-and-push (push) Has been cancelled
feat: enhance menu theming with comprehensive documentation and testing support
2025-08-05 14:06:42 -07:00

127 lines
4.6 KiB
Python

"""
Tests for theme manager menu functionality.
"""
import os
import sys
import unittest
from unittest.mock import Mock, patch
import tkinter as tk
# Add src to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from theme_manager import ThemeManager
class TestThemeManagerMenu(unittest.TestCase):
"""Test cases for theme manager menu functionality."""
def setUp(self):
"""Set up test fixtures."""
self.root = tk.Tk()
self.root.withdraw() # Hide the window during testing
self.mock_logger = Mock()
self.theme_manager = ThemeManager(self.root, self.mock_logger)
def tearDown(self):
"""Clean up after tests."""
if self.root:
self.root.destroy()
def test_get_menu_colors(self):
"""Test that get_menu_colors returns valid color dictionary."""
colors = self.theme_manager.get_menu_colors()
# Check that all required keys are present
required_keys = ["bg", "fg", "active_bg", "active_fg", "disabled_fg"]
for key in required_keys:
self.assertIn(key, colors)
# Check that colors are valid hex strings or named colors
for key, color in colors.items():
self.assertIsInstance(color, str)
self.assertTrue(len(color) > 0)
def test_configure_menu(self):
"""Test that configure_menu applies theme to menu widget."""
menu = tk.Menu(self.root)
# Configure the menu
self.theme_manager.configure_menu(menu)
# Check that menu configuration was called
# Note: We can't directly test the visual appearance, but we can
# verify that no exceptions were raised
self.assertIsNotNone(menu)
def test_create_themed_menu(self):
"""Test that create_themed_menu creates and themes a menu."""
menu = self.theme_manager.create_themed_menu(self.root, tearoff=0)
# Check that a menu was created
self.assertIsInstance(menu, tk.Menu)
# Check that the menu has the tearoff option set
self.assertEqual(menu['tearoff'], 0)
def test_menu_colors_consistency(self):
"""Test that menu colors are consistent across theme changes."""
original_colors = self.theme_manager.get_menu_colors()
# Try to apply a different theme
available_themes = self.theme_manager.get_available_themes()
if len(available_themes) > 1:
# Apply a different theme
other_theme = available_themes[1] if available_themes[0] == self.theme_manager.current_theme else available_themes[0]
self.theme_manager.apply_theme(other_theme)
# Get new colors
new_colors = self.theme_manager.get_menu_colors()
# Colors should still have the same structure
self.assertEqual(set(original_colors.keys()), set(new_colors.keys()))
# Colors might be different (which is expected)
# Just ensure they're still valid
for color in new_colors.values():
self.assertIsInstance(color, str)
self.assertTrue(len(color) > 0)
@patch('tkinter.Menu')
def test_create_themed_menu_error_handling(self, mock_menu_class):
"""Test that create_themed_menu handles errors gracefully."""
# Make the Menu constructor raise an exception
mock_menu_class.side_effect = Exception("Test error")
# This should not raise an exception but return a fallback menu
menu = self.theme_manager.create_themed_menu(self.root)
# The method should still return something (fallback behavior)
self.assertIsNotNone(menu)
def test_menu_theme_integration(self):
"""Test complete menu theming workflow."""
# Create a menu structure similar to the main application
menubar = self.theme_manager.create_themed_menu(self.root)
file_menu = self.theme_manager.create_themed_menu(menubar, tearoff=0)
theme_menu = self.theme_manager.create_themed_menu(menubar, tearoff=0)
# Add some menu items
file_menu.add_command(label="Test Item 1")
file_menu.add_separator()
file_menu.add_command(label="Test Item 2")
# Add theme selection items
available_themes = self.theme_manager.get_available_themes()
for theme in available_themes:
theme_menu.add_radiobutton(label=theme.title())
# Verify structure was created successfully
self.assertIsInstance(menubar, tk.Menu)
self.assertIsInstance(file_menu, tk.Menu)
self.assertIsInstance(theme_menu, tk.Menu)
if __name__ == '__main__':
unittest.main()