EU-Utility/plugins/ui_test_suite/test_modules/widget_tests.py

531 lines
18 KiB
Python

"""
Widget System Tests
Tests for the widget registry and floating widgets including:
- Widget registration
- Widget creation
- Positioning and resizing
- Opacity control
- Widget lifecycle
"""
class WidgetSystemTests:
"""Test suite for widget system."""
name = "Widget System"
icon = "🎨"
description = "Tests widget creation, positioning, resizing, opacity, and lifecycle"
def __init__(self):
self.tests = {
'registry_initialization': self.test_registry_initialization,
'widget_registration': self.test_widget_registration,
'widget_creation': self.test_widget_creation,
'widget_lookup': self.test_widget_lookup,
'widget_by_plugin': self.test_widget_by_plugin,
'widget_unregister': self.test_widget_unregister,
'widget_clear': self.test_widget_clear,
'widget_info_structure': self.test_widget_info_structure,
'overlay_widget_creation': self.test_overlay_widget_creation,
'widget_positioning': self.test_widget_positioning,
}
def test_registry_initialization(self) -> dict:
"""Test widget registry initialization."""
try:
from core.widget_registry import WidgetRegistry, get_widget_registry
# Test singleton pattern
reg1 = get_widget_registry()
reg2 = get_widget_registry()
if reg1 is not reg2:
return {
'passed': False,
'message': "WidgetRegistry singleton not working correctly",
'severity': 'error'
}
# Test that registry has _widgets dict
if not hasattr(reg1, '_widgets'):
return {
'passed': False,
'message': "Registry missing _widgets dictionary",
'severity': 'error'
}
return {
'passed': True,
'message': "WidgetRegistry singleton working correctly",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error initializing registry: {e}",
'severity': 'error'
}
def test_widget_registration(self) -> dict:
"""Test widget registration."""
try:
from core.widget_registry import get_widget_registry
from PyQt6.QtWidgets import QLabel
registry = get_widget_registry()
# Test registration
test_widget_id = "_test_widget_123"
def create_test_widget():
return QLabel("Test")
registry.register_widget(
widget_id=test_widget_id,
name="Test Widget",
description="A test widget",
icon="🧪",
creator=create_test_widget,
plugin_id="test_plugin"
)
# Verify registration
if test_widget_id not in registry._widgets:
return {
'passed': False,
'message': "Widget not found after registration",
'severity': 'error'
}
# Cleanup
registry.unregister_widget(test_widget_id)
return {
'passed': True,
'message': "Widget registration working",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error registering widget: {e}",
'severity': 'error'
}
def test_widget_creation(self) -> dict:
"""Test widget creation via registry."""
try:
from core.widget_registry import get_widget_registry
from PyQt6.QtWidgets import QLabel, QWidget
registry = get_widget_registry()
test_widget_id = "_test_creation_123"
def create_widget():
return QLabel("Test Widget")
registry.register_widget(
widget_id=test_widget_id,
name="Creation Test",
description="Testing widget creation",
icon="🔨",
creator=create_widget,
plugin_id="test"
)
# Test creation
widget = registry.create_widget(test_widget_id)
if widget is None:
registry.unregister_widget(test_widget_id)
return {
'passed': False,
'message': "create_widget returned None",
'severity': 'error'
}
if not isinstance(widget, QWidget):
registry.unregister_widget(test_widget_id)
return {
'passed': False,
'message': "Created widget is not a QWidget",
'severity': 'error'
}
# Cleanup
registry.unregister_widget(test_widget_id)
return {
'passed': True,
'message': "Widget creation working correctly",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error creating widget: {e}",
'severity': 'error'
}
def test_widget_lookup(self) -> dict:
"""Test widget lookup by ID."""
try:
from core.widget_registry import get_widget_registry
from PyQt6.QtWidgets import QLabel
registry = get_widget_registry()
test_id = "_test_lookup_123"
registry.register_widget(
widget_id=test_id,
name="Lookup Test",
description="Testing lookup",
icon="🔍",
creator=lambda: QLabel("Test"),
plugin_id="test"
)
# Test get_widget
info = registry.get_widget(test_id)
if info is None:
registry.unregister_widget(test_id)
return {
'passed': False,
'message': "get_widget returned None for existing widget",
'severity': 'error'
}
if info.id != test_id:
registry.unregister_widget(test_id)
return {
'passed': False,
'message': f"Widget ID mismatch: expected {test_id}, got {info.id}",
'severity': 'error'
}
# Test non-existent widget
non_existent = registry.get_widget("_non_existent_widget_999")
if non_existent is not None:
registry.unregister_widget(test_id)
return {
'passed': False,
'message': "get_widget should return None for non-existent widgets",
'severity': 'warning'
}
registry.unregister_widget(test_id)
return {
'passed': True,
'message': "Widget lookup working correctly",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error looking up widget: {e}",
'severity': 'error'
}
def test_widget_by_plugin(self) -> dict:
"""Test getting widgets by plugin ID."""
try:
from core.widget_registry import get_widget_registry
from PyQt6.QtWidgets import QLabel
registry = get_widget_registry()
test_plugin_id = "_test_plugin_456"
# Register multiple widgets for same plugin
for i in range(3):
registry.register_widget(
widget_id=f"_test_wp_{i}",
name=f"Widget {i}",
description=f"Test widget {i}",
icon="📦",
creator=lambda: QLabel("Test"),
plugin_id=test_plugin_id
)
# Get widgets by plugin
widgets = registry.get_widgets_by_plugin(test_plugin_id)
if len(widgets) != 3:
# Cleanup
for i in range(3):
registry.unregister_widget(f"_test_wp_{i}")
return {
'passed': False,
'message': f"Expected 3 widgets, got {len(widgets)}",
'severity': 'error'
}
# Cleanup
for i in range(3):
registry.unregister_widget(f"_test_wp_{i}")
return {
'passed': True,
'message': f"get_widgets_by_plugin returned {len(widgets)} widgets",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error getting widgets by plugin: {e}",
'severity': 'error'
}
def test_widget_unregister(self) -> dict:
"""Test widget unregistration."""
try:
from core.widget_registry import get_widget_registry
from PyQt6.QtWidgets import QLabel
registry = get_widget_registry()
test_id = "_test_unregister_123"
registry.register_widget(
widget_id=test_id,
name="Unregister Test",
description="Testing unregistration",
icon="🗑️",
creator=lambda: QLabel("Test"),
plugin_id="test"
)
# Verify registration
if test_id not in registry._widgets:
return {
'passed': False,
'message': "Widget not registered",
'severity': 'error'
}
# Unregister
registry.unregister_widget(test_id)
# Verify unregistration
if test_id in registry._widgets:
return {
'passed': False,
'message': "Widget still in registry after unregister",
'severity': 'error'
}
# Verify get_widget returns None
info = registry.get_widget(test_id)
if info is not None:
return {
'passed': False,
'message': "get_widget returns widget after unregister",
'severity': 'error'
}
return {
'passed': True,
'message': "Widget unregistration working",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error unregistering widget: {e}",
'severity': 'error'
}
def test_widget_clear(self) -> dict:
"""Test clearing all widgets."""
try:
from core.widget_registry import get_widget_registry
from PyQt6.QtWidgets import QLabel
registry = get_widget_registry()
# Register some widgets
for i in range(5):
registry.register_widget(
widget_id=f"_test_clear_{i}",
name=f"Clear Test {i}",
description="Testing clear",
icon="🧹",
creator=lambda: QLabel("Test"),
plugin_id="test"
)
# Clear
registry.clear()
# Verify
if len(registry._widgets) != 0:
return {
'passed': False,
'message': f"Registry not empty after clear: {len(registry._widgets)} widgets",
'severity': 'error'
}
all_widgets = registry.get_all_widgets()
if len(all_widgets) != 0:
return {
'passed': False,
'message': f"get_all_widgets not empty after clear",
'severity': 'error'
}
return {
'passed': True,
'message': "Registry clear working",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error clearing widgets: {e}",
'severity': 'error'
}
def test_widget_info_structure(self) -> dict:
"""Test WidgetInfo dataclass structure."""
try:
from core.widget_registry import WidgetInfo
# Check required fields
required_fields = ['id', 'name', 'description', 'icon', 'creator', 'plugin_id']
# Create a test WidgetInfo
def dummy_creator():
return None
info = WidgetInfo(
id="test",
name="Test",
description="Test description",
icon="🧪",
creator=dummy_creator,
plugin_id="test_plugin"
)
missing = []
for field in required_fields:
if not hasattr(info, field):
missing.append(field)
if missing:
return {
'passed': False,
'message': f"WidgetInfo missing fields: {missing}",
'severity': 'error'
}
return {
'passed': True,
'message': f"WidgetInfo structure correct with {len(required_fields)} fields",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error checking WidgetInfo: {e}",
'severity': 'error'
}
def test_overlay_widget_creation(self) -> dict:
"""Test widget creation from overlay."""
try:
from core.overlay_window import OverlayWindow
issues = []
recommendations = []
# Check _add_registered_widget method
if not hasattr(OverlayWindow, '_add_registered_widget'):
issues.append("_add_registered_widget method missing")
# Check widget storage
if not hasattr(OverlayWindow, '_active_widgets'):
recommendations.append("Consider adding _active_widgets list to prevent GC")
# Check widgets tab
if not hasattr(OverlayWindow, '_create_widgets_tab'):
issues.append("_create_widgets_tab method missing")
if not hasattr(OverlayWindow, '_refresh_widgets_tab'):
issues.append("_refresh_widgets_tab method missing")
if issues:
return {
'passed': False,
'message': "; ".join(issues),
'severity': 'error',
'recommendation': recommendations[0] if recommendations else None
}
return {
'passed': True,
'message': "Overlay widget creation present",
'severity': 'info'
}
except Exception as e:
return {
'passed': False,
'message': f"Error checking overlay widget creation: {e}",
'severity': 'error'
}
def test_widget_positioning(self) -> dict:
"""Test widget positioning features."""
try:
from core.overlay_window import OverlayWindow
from core.widget_system import WidgetConfig
issues = []
recommendations = []
# Check widget config
if 'WidgetConfig' in dir():
config = WidgetConfig()
if not hasattr(config, 'x') or not hasattr(config, 'y'):
issues.append("WidgetConfig missing position fields")
else:
recommendations.append("Consider adding WidgetConfig for widget settings")
# Check if widgets can be positioned
# In _add_registered_widget, widgets are positioned at screen center
import inspect
if hasattr(OverlayWindow, '_add_registered_widget'):
source = inspect.getsource(OverlayWindow._add_registered_widget)
if 'move(' not in source:
recommendations.append("Consider allowing custom widget positions")
if issues:
return {
'passed': False,
'message': "; ".join(issues),
'severity': 'warning'
}
return {
'passed': True,
'message': "Widget positioning features present",
'severity': 'info',
'recommendation': recommendations[0] if recommendations else None
}
except Exception as e:
return {
'passed': False,
'message': f"Error checking widget positioning: {e}",
'severity': 'error'
}