213 lines
7.7 KiB
Python
213 lines
7.7 KiB
Python
"""
|
|
Unit tests for the CallbackRegistry system.
|
|
"""
|
|
|
|
import unittest
|
|
from unittest.mock import Mock
|
|
|
|
from pyWebLayout.core.callback_registry import CallbackRegistry
|
|
from pyWebLayout.core.base import Interactable
|
|
from pyWebLayout.concrete.functional import LinkText, ButtonText, FormFieldText
|
|
from pyWebLayout.abstract.functional import Link, Button, FormField, LinkType, FormFieldType
|
|
from pyWebLayout.style import Font
|
|
|
|
|
|
class TestCallbackRegistry(unittest.TestCase):
|
|
"""Test cases for CallbackRegistry class."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.registry = CallbackRegistry()
|
|
self.font = Font(font_size=12, colour=(0, 0, 0))
|
|
self.mock_draw = Mock()
|
|
|
|
def test_registry_initialization(self):
|
|
"""Test that registry initializes empty."""
|
|
self.assertEqual(self.registry.count(), 0)
|
|
self.assertEqual(len(self.registry.get_all_ids()), 0)
|
|
self.assertEqual(len(self.registry.get_all_types()), 0)
|
|
|
|
def test_register_with_html_id(self):
|
|
"""Test registering an interactable with HTML id."""
|
|
link = Link("https://example.com", LinkType.EXTERNAL, html_id="my-link")
|
|
link_text = LinkText(link, "Example", self.font, self.mock_draw)
|
|
|
|
registered_id = self.registry.register(link_text, html_id="my-link")
|
|
|
|
self.assertEqual(registered_id, "my-link")
|
|
self.assertEqual(self.registry.count(), 1)
|
|
self.assertIn("my-link", self.registry)
|
|
|
|
def test_register_without_html_id(self):
|
|
"""Test registering an interactable without HTML id (auto-generated)."""
|
|
button = Button("Click Me", callback=None)
|
|
button_text = ButtonText(button, self.font, self.mock_draw)
|
|
|
|
registered_id = self.registry.register(button_text)
|
|
|
|
# Should generate auto id like "auto_button_0"
|
|
self.assertTrue(registered_id.startswith("auto_button_"))
|
|
self.assertEqual(self.registry.count(), 1)
|
|
|
|
def test_get_by_id(self):
|
|
"""Test retrieving an interactable by id."""
|
|
link = Link("test", html_id="test-link")
|
|
link_text = LinkText(link, "Test", self.font, self.mock_draw)
|
|
self.registry.register(link_text, html_id="test-link")
|
|
|
|
retrieved = self.registry.get_by_id("test-link")
|
|
|
|
self.assertEqual(retrieved, link_text)
|
|
|
|
def test_get_by_id_not_found(self):
|
|
"""Test retrieving non-existent id returns None."""
|
|
result = self.registry.get_by_id("nonexistent")
|
|
self.assertIsNone(result)
|
|
|
|
def test_get_by_type(self):
|
|
"""Test retrieving all interactables of a type."""
|
|
# Register multiple buttons
|
|
button1 = Button("Button 1", callback=None)
|
|
button2 = Button("Button 2", callback=None)
|
|
button_text1 = ButtonText(button1, self.font, self.mock_draw)
|
|
button_text2 = ButtonText(button2, self.font, self.mock_draw)
|
|
|
|
self.registry.register(button_text1, html_id="btn1")
|
|
self.registry.register(button_text2, html_id="btn2")
|
|
|
|
# Also register a link
|
|
link = Link("test")
|
|
link_text = LinkText(link, "Test", self.font, self.mock_draw)
|
|
self.registry.register(link_text, html_id="link1")
|
|
|
|
buttons = self.registry.get_by_type("button")
|
|
links = self.registry.get_by_type("link")
|
|
|
|
self.assertEqual(len(buttons), 2)
|
|
self.assertIn(button_text1, buttons)
|
|
self.assertIn(button_text2, buttons)
|
|
|
|
self.assertEqual(len(links), 1)
|
|
self.assertIn(link_text, links)
|
|
|
|
def test_set_callback(self):
|
|
"""Test setting a callback by id."""
|
|
button = Button("Test", callback=None)
|
|
button_text = ButtonText(button, self.font, self.mock_draw)
|
|
self.registry.register(button_text, html_id="test-btn")
|
|
|
|
def my_callback(point):
|
|
return "clicked"
|
|
|
|
success = self.registry.set_callback("test-btn", my_callback)
|
|
|
|
self.assertTrue(success)
|
|
self.assertEqual(button_text._callback, my_callback)
|
|
|
|
def test_set_callback_not_found(self):
|
|
"""Test setting callback for non-existent id returns False."""
|
|
result = self.registry.set_callback("nonexistent", lambda: None)
|
|
self.assertFalse(result)
|
|
|
|
def test_set_callbacks_by_type(self):
|
|
"""Test setting callbacks for all objects of a type."""
|
|
# Register multiple buttons
|
|
button1 = Button("Button 1", callback=None)
|
|
button2 = Button("Button 2", callback=None)
|
|
button_text1 = ButtonText(button1, self.font, self.mock_draw)
|
|
button_text2 = ButtonText(button2, self.font, self.mock_draw)
|
|
|
|
self.registry.register(button_text1)
|
|
self.registry.register(button_text2)
|
|
|
|
def click_handler(point):
|
|
return "clicked"
|
|
|
|
count = self.registry.set_callbacks_by_type("button", click_handler)
|
|
|
|
self.assertEqual(count, 2)
|
|
self.assertEqual(button_text1._callback, click_handler)
|
|
self.assertEqual(button_text2._callback, click_handler)
|
|
|
|
def test_unregister(self):
|
|
"""Test unregistering an interactable."""
|
|
button = Button("Test", callback=None)
|
|
button_text = ButtonText(button, self.font, self.mock_draw)
|
|
self.registry.register(button_text, html_id="test-btn")
|
|
|
|
self.assertEqual(self.registry.count(), 1)
|
|
|
|
success = self.registry.unregister("test-btn")
|
|
|
|
self.assertTrue(success)
|
|
self.assertEqual(self.registry.count(), 0)
|
|
self.assertNotIn("test-btn", self.registry)
|
|
|
|
def test_clear(self):
|
|
"""Test clearing all registrations."""
|
|
button = Button("Test", callback=None)
|
|
button_text = ButtonText(button, self.font, self.mock_draw)
|
|
link = Link("test")
|
|
link_text = LinkText(link, "Test", self.font, self.mock_draw)
|
|
|
|
self.registry.register(button_text)
|
|
self.registry.register(link_text)
|
|
|
|
self.assertEqual(self.registry.count(), 2)
|
|
|
|
self.registry.clear()
|
|
|
|
self.assertEqual(self.registry.count(), 0)
|
|
self.assertEqual(len(self.registry.get_all_types()), 0)
|
|
|
|
def test_count_by_type(self):
|
|
"""Test counting objects by type."""
|
|
# Register 2 buttons and 1 link
|
|
for i in range(2):
|
|
button = Button(f"Button {i}", callback=None)
|
|
button_text = ButtonText(button, self.font, self.mock_draw)
|
|
self.registry.register(button_text)
|
|
|
|
link = Link("test")
|
|
link_text = LinkText(link, "Test", self.font, self.mock_draw)
|
|
self.registry.register(link_text)
|
|
|
|
self.assertEqual(self.registry.count_by_type("button"), 2)
|
|
self.assertEqual(self.registry.count_by_type("link"), 1)
|
|
self.assertEqual(self.registry.count_by_type("form_field"), 0)
|
|
|
|
def test_contains_operator(self):
|
|
"""Test 'in' operator for checking if id exists."""
|
|
button = Button("Test", callback=None)
|
|
button_text = ButtonText(button, self.font, self.mock_draw)
|
|
self.registry.register(button_text, html_id="test-btn")
|
|
|
|
self.assertIn("test-btn", self.registry)
|
|
self.assertNotIn("nonexistent", self.registry)
|
|
|
|
def test_len_operator(self):
|
|
"""Test len() operator."""
|
|
self.assertEqual(len(self.registry), 0)
|
|
|
|
button = Button("Test", callback=None)
|
|
button_text = ButtonText(button, self.font, self.mock_draw)
|
|
self.registry.register(button_text)
|
|
|
|
self.assertEqual(len(self.registry), 1)
|
|
|
|
def test_repr(self):
|
|
"""Test string representation."""
|
|
button = Button("Test", callback=None)
|
|
button_text = ButtonText(button, self.font, self.mock_draw)
|
|
self.registry.register(button_text)
|
|
|
|
repr_str = repr(self.registry)
|
|
|
|
self.assertIn("CallbackRegistry", repr_str)
|
|
self.assertIn("total=1", repr_str)
|
|
self.assertIn("button", repr_str)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|