Files
thechart/tests/test_theme_manager.py

124 lines
4.5 KiB
Python

"""
Tests for theme manager menu functionality.
"""
import os
import sys
import unittest
from unittest.mock import Mock, patch
import tkinter as tk
from thechart.ui 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()