110 lines
2.9 KiB
Python
110 lines
2.9 KiB
Python
import weakref
|
|
import pytest
|
|
from slic.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__) |