DarkMode ist existent yeah
Dieser Commit ist enthalten in:
279
test_theme_system.py
Normale Datei
279
test_theme_system.py
Normale Datei
@ -0,0 +1,279 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Comprehensive test script for the theme system refactoring.
|
||||
Tests all components without requiring PyQt5.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
# Add project root to path
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
def test_theme_config():
|
||||
"""Test theme configuration module."""
|
||||
print("\n=== Testing Theme Configuration ===")
|
||||
try:
|
||||
from themes.theme_config import ThemeConfig
|
||||
|
||||
# Test light theme
|
||||
light = ThemeConfig.get_theme('light')
|
||||
print(f"✓ Light theme loaded: {len(light)} color definitions")
|
||||
|
||||
# Test dark theme
|
||||
dark = ThemeConfig.get_theme('dark')
|
||||
print(f"✓ Dark theme loaded: {len(dark)} color definitions")
|
||||
|
||||
# Check critical keys
|
||||
critical_keys = [
|
||||
'bg_primary', 'bg_secondary', 'bg_tertiary',
|
||||
'text_primary', 'text_secondary', 'text_tertiary',
|
||||
'accent', 'accent_hover', 'accent_pressed',
|
||||
'error', 'error_dark', 'success', 'warning',
|
||||
'border_default', 'border_subtle',
|
||||
'logo_path'
|
||||
]
|
||||
|
||||
for key in critical_keys:
|
||||
if key not in light:
|
||||
print(f"✗ Missing in light theme: {key}")
|
||||
return False
|
||||
if key not in dark:
|
||||
print(f"✗ Missing in dark theme: {key}")
|
||||
return False
|
||||
|
||||
print(f"✓ All {len(critical_keys)} critical keys present in both themes")
|
||||
|
||||
# Test sizes, fonts, etc
|
||||
sizes = ThemeConfig.FONT_SIZES
|
||||
fonts = ThemeConfig.FONTS
|
||||
weights = ThemeConfig.FONT_WEIGHTS
|
||||
spacing = ThemeConfig.SPACING
|
||||
radius = ThemeConfig.RADIUS
|
||||
|
||||
print(f"✓ Font sizes defined: {list(sizes.keys())}")
|
||||
print(f"✓ Font families defined: {list(fonts.keys())}")
|
||||
print(f"✓ Font weights defined: {list(weights.keys())}")
|
||||
print(f"✓ Spacing values defined: {list(spacing.keys())}")
|
||||
print(f"✓ Border radius defined: {list(radius.keys())}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Error testing theme config: {e}")
|
||||
return False
|
||||
|
||||
def test_qss_generator():
|
||||
"""Test QSS generation."""
|
||||
print("\n=== Testing QSS Generator ===")
|
||||
try:
|
||||
from themes.qss_generator import QSSGenerator
|
||||
|
||||
# Generate light theme QSS
|
||||
light_qss = QSSGenerator.generate('light')
|
||||
print(f"✓ Light theme QSS generated: {len(light_qss)} characters")
|
||||
|
||||
# Generate dark theme QSS
|
||||
dark_qss = QSSGenerator.generate('dark')
|
||||
print(f"✓ Dark theme QSS generated: {len(dark_qss)} characters")
|
||||
|
||||
# Check for key selectors
|
||||
key_selectors = [
|
||||
'QMainWindow', 'QPushButton', 'QLabel', 'QLineEdit',
|
||||
'QTextEdit', 'QScrollArea', 'QFrame', 'QWidget',
|
||||
'QMenuBar', 'QTabBar', 'QDialog'
|
||||
]
|
||||
|
||||
missing_light = []
|
||||
missing_dark = []
|
||||
|
||||
for selector in key_selectors:
|
||||
if selector not in light_qss:
|
||||
missing_light.append(selector)
|
||||
if selector not in dark_qss:
|
||||
missing_dark.append(selector)
|
||||
|
||||
if missing_light:
|
||||
print(f"✗ Missing selectors in light QSS: {missing_light}")
|
||||
if missing_dark:
|
||||
print(f"✗ Missing selectors in dark QSS: {missing_dark}")
|
||||
|
||||
if not missing_light and not missing_dark:
|
||||
print(f"✓ All {len(key_selectors)} key selectors present in both themes")
|
||||
|
||||
# Check for object name selectors (our custom ones)
|
||||
custom_selectors = [
|
||||
'#platform_button', '#filter_button', '#account_username',
|
||||
'#account_login_btn', '#account_export_btn', '#account_delete_btn',
|
||||
'#logo_button', '#dark_mode_toggle'
|
||||
]
|
||||
|
||||
found_custom = []
|
||||
for selector in custom_selectors:
|
||||
if selector in light_qss:
|
||||
found_custom.append(selector)
|
||||
|
||||
print(f"✓ Custom selectors found: {len(found_custom)}/{len(custom_selectors)}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Error testing QSS generator: {e}")
|
||||
return False
|
||||
|
||||
def test_file_structure():
|
||||
"""Test that all required files exist."""
|
||||
print("\n=== Testing File Structure ===")
|
||||
|
||||
required_files = [
|
||||
'themes/__init__.py',
|
||||
'themes/theme_config.py',
|
||||
'themes/qss_generator.py',
|
||||
'views/base/__init__.py',
|
||||
'views/base/theme_aware_widget.py',
|
||||
'views/widgets/dark_mode_toggle.py',
|
||||
'utils/theme_manager.py',
|
||||
'resources/icons/intelsight-logo.svg',
|
||||
'resources/icons/intelsight-dark.svg'
|
||||
]
|
||||
|
||||
missing = []
|
||||
for file in required_files:
|
||||
path = Path(file)
|
||||
if path.exists():
|
||||
print(f"✓ {file}")
|
||||
else:
|
||||
print(f"✗ Missing: {file}")
|
||||
missing.append(file)
|
||||
|
||||
if missing:
|
||||
print(f"\n✗ Missing {len(missing)} required files")
|
||||
return False
|
||||
else:
|
||||
print(f"\n✓ All {len(required_files)} required files present")
|
||||
return True
|
||||
|
||||
def test_no_hardcoded_colors():
|
||||
"""Check for hardcoded colors in view files."""
|
||||
print("\n=== Checking for Hardcoded Colors ===")
|
||||
|
||||
import re
|
||||
|
||||
# Pattern to match hex colors
|
||||
hex_pattern = re.compile(r'#[0-9A-Fa-f]{6}|#[0-9A-Fa-f]{3}')
|
||||
rgb_pattern = re.compile(r'rgb\s*\([^)]+\)|rgba\s*\([^)]+\)')
|
||||
|
||||
view_files = [
|
||||
'views/main_window.py',
|
||||
'views/platform_selector.py',
|
||||
'views/components/tab_navigation.py',
|
||||
'views/components/platform_grid_view.py',
|
||||
'views/components/accounts_overview_view.py',
|
||||
'views/widgets/platform_button.py',
|
||||
'views/widgets/account_card.py'
|
||||
]
|
||||
|
||||
files_with_colors = []
|
||||
|
||||
for file in view_files:
|
||||
if not Path(file).exists():
|
||||
continue
|
||||
|
||||
with open(file, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Skip import statements and comments
|
||||
lines = content.split('\n')
|
||||
for i, line in enumerate(lines):
|
||||
# Skip comments and imports
|
||||
if line.strip().startswith('#') or line.strip().startswith('from') or line.strip().startswith('import'):
|
||||
continue
|
||||
|
||||
# Check for hex colors
|
||||
if 'setStyleSheet' in line and (hex_pattern.search(line) or rgb_pattern.search(line)):
|
||||
files_with_colors.append((file, i+1, line.strip()))
|
||||
|
||||
if files_with_colors:
|
||||
print(f"✗ Found {len(files_with_colors)} lines with hardcoded colors:")
|
||||
for file, line_no, line in files_with_colors[:5]: # Show first 5
|
||||
print(f" {file}:{line_no}: {line[:60]}...")
|
||||
return False
|
||||
else:
|
||||
print(f"✓ No hardcoded colors found in {len(view_files)} view files")
|
||||
return True
|
||||
|
||||
def test_imports():
|
||||
"""Test that all imports work correctly."""
|
||||
print("\n=== Testing Imports ===")
|
||||
|
||||
test_imports = [
|
||||
('themes.theme_config', 'ThemeConfig'),
|
||||
('themes.qss_generator', 'QSSGenerator'),
|
||||
('views.base.theme_aware_widget', 'ThemeAwareWidget'),
|
||||
]
|
||||
|
||||
failed = []
|
||||
|
||||
for module_name, class_name in test_imports:
|
||||
try:
|
||||
module = __import__(module_name, fromlist=[class_name])
|
||||
if hasattr(module, class_name):
|
||||
print(f"✓ {module_name}.{class_name}")
|
||||
else:
|
||||
print(f"✗ {module_name} missing {class_name}")
|
||||
failed.append(f"{module_name}.{class_name}")
|
||||
except ImportError as e:
|
||||
# Check if it's just PyQt5 missing
|
||||
if 'PyQt5' in str(e):
|
||||
print(f"⚠ {module_name}.{class_name} (requires PyQt5)")
|
||||
else:
|
||||
print(f"✗ {module_name}.{class_name}: {e}")
|
||||
failed.append(f"{module_name}.{class_name}")
|
||||
|
||||
if failed:
|
||||
print(f"\n✗ {len(failed)} imports failed")
|
||||
return False
|
||||
else:
|
||||
print(f"\n✓ All critical imports successful (PyQt5-dependent modules skipped)")
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""Run all tests."""
|
||||
print("=" * 60)
|
||||
print("THEME SYSTEM COMPREHENSIVE TEST")
|
||||
print("=" * 60)
|
||||
|
||||
results = []
|
||||
|
||||
# Run tests
|
||||
results.append(("File Structure", test_file_structure()))
|
||||
results.append(("Theme Config", test_theme_config()))
|
||||
results.append(("QSS Generator", test_qss_generator()))
|
||||
results.append(("Imports", test_imports()))
|
||||
results.append(("No Hardcoded Colors", test_no_hardcoded_colors()))
|
||||
|
||||
# Summary
|
||||
print("\n" + "=" * 60)
|
||||
print("TEST SUMMARY")
|
||||
print("=" * 60)
|
||||
|
||||
passed = sum(1 for _, result in results if result)
|
||||
total = len(results)
|
||||
|
||||
for name, result in results:
|
||||
status = "✓ PASS" if result else "✗ FAIL"
|
||||
print(f"{status}: {name}")
|
||||
|
||||
print(f"\nTotal: {passed}/{total} tests passed")
|
||||
|
||||
if passed == total:
|
||||
print("\n✅ ALL TESTS PASSED! Theme system is properly configured.")
|
||||
else:
|
||||
print(f"\n⚠️ {total - passed} tests failed. Review the output above.")
|
||||
|
||||
return 0 if passed == total else 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren