This commit is contained in:
@@ -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
|
||||||
Reference in New Issue
Block a user