""" Unit tests for the CallbackRegistry system. """ import unittest from unittest.mock import Mock from pyWebLayout.core.callback_registry import CallbackRegistry from pyWebLayout.concrete.functional import LinkText, ButtonText from pyWebLayout.abstract.functional import Link, Button, LinkType 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()