From 44ae1fb43dcc69efd690a4a0c40e8a4436538e24 Mon Sep 17 00:00:00 2001 From: tligui_y Date: Tue, 5 Aug 2025 20:48:34 +0200 Subject: [PATCH] Add tests/test_utils_registry.py --- tests/test_utils_registry.py | 126 +++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 tests/test_utils_registry.py diff --git a/tests/test_utils_registry.py b/tests/test_utils_registry.py new file mode 100644 index 000000000..e2e7b5d5b --- /dev/null +++ b/tests/test_utils_registry.py @@ -0,0 +1,126 @@ +import weakref +import pytest +from utils.registry import Registry, RegistryMeta, instances, _collect_instances + + +@pytest.fixture +def clean_registry(): + """Reset all registries before each test.""" + for cls in Registry.__subclasses__(): + cls.__instances__.clear() + +# RegistryMeta Tests + +def test_metaclass_creates_weakset(): + + # Test if RegistryMeta creates WeakSet on classes + class TestClass(metaclass=RegistryMeta): + pass + + assert hasattr(TestClass, '__instances__') + assert isinstance(TestClass.__instances__, weakref.WeakSet) + +def test_metaclass_tracks_instances(): + # Test instance tracking through metaclass + class TestClass(metaclass=RegistryMeta): + def __init__(self, x): + self.x = x + + instance = TestClass(42) + assert instance in TestClass.__instances__ + +# Registry Class Tests +def test_registry_inheritance(clean_registry): + # Test if a Registry subclass gets registry functionality + class TestClass(Registry): + pass + + assert isinstance(TestClass.__instances__, weakref.WeakSet) + +def test_instance_tracking(clean_registry): + # Test basic instance tracking + class Animal(Registry): + def __init__(self, name): + self.name = name + + cat = Animal("Misty") + dog = Animal("Rex") + + assert len(Animal.__instances__) == 2 + assert cat in Animal.__instances__ + assert dog in Animal.__instances__ + +# Utility function Tests +def test_collect_instances_recursive(clean_registry): + # Test recursive instance collection + class Animal(Registry): + pass + + class Dog(Animal): + pass + + a = Animal() + d = Dog() + + collected = _collect_instances(Animal, recursive=True) + assert len(collected) == 2 + assert a in collected + assert d in collected + +def test_instances_function(clean_registry): + # Test instances() function behavior + class Vehicle(Registry): + pass + + class Car(Vehicle): + pass + + v = Vehicle() + c = Car() + + # Non-recursive + assert len(instances(Vehicle, recursive=False)) == 1 + assert v in instances(Vehicle, recursive=False) + + # Recursive + assert len(instances(Vehicle, recursive=True)) == 2 + assert c in instances(Vehicle, recursive=True) + + # Weak vs strong references + assert isinstance(instances(Vehicle, weak=True), weakref.WeakSet) + assert isinstance(instances(Vehicle, weak=False), set) + +# Error Cases +def test_non_registry_class_error(): + + # Test error on non-registry classes + class RegularClass: + pass + + with pytest.raises(TypeError): + _collect_instances(RegularClass) + +def test_signature_preservation(): + # Test constructor signature preservation + class TestClass(Registry): + def __init__(self, x: int, y: str = "hello"): + pass + + assert "x: int" in str(TestClass.__signature__) + assert "y: str = 'hello'" in str(TestClass.__signature__) + +def test_weakset_vs_set_behavior(clean_registry): + # Test WeakSet vs set reference behavior + class Item(Registry): + pass + + item = Item() + reg_set = instances(Item, weak=False) + reg_weak = instances(Item, weak=True) + + assert len(reg_set) == 1 + assert len(reg_weak) == 1 + + del item + assert len(reg_weak) == 0 # WeakSet auto-clears + assert len(reg_set) == 1 # Regular set maintains reference \ No newline at end of file