This commit is contained in:
@@ -1,104 +1,90 @@
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import patch, MagicMock
|
||||
from slic.utils.snapshot import snapshot
|
||||
from slic.core.adjustable import Adjustable
|
||||
|
||||
class FakeAdjustable:
|
||||
"""Mock adjustable with isolated registry"""
|
||||
_registry = []
|
||||
|
||||
class FakeAdjustable(Adjustable):
|
||||
"""Test double that doesn't register in real registry"""
|
||||
def __init__(self, ID, name=None, internal=False):
|
||||
self.ID = ID
|
||||
self.name = name or ID
|
||||
self.internal = internal
|
||||
self.__class__._registry.append(self)
|
||||
|
||||
super().__init__(ID=ID, name=name or ID, internal=internal)
|
||||
self._value = 0
|
||||
|
||||
def get_current_value(self):
|
||||
return self._value
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Adjustable {self.name}>"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@classmethod
|
||||
def clear(cls):
|
||||
cls._registry = []
|
||||
|
||||
@pytest.fixture
|
||||
def clean_slate():
|
||||
"""Complete test isolation"""
|
||||
FakeAdjustable.clear()
|
||||
yield
|
||||
FakeAdjustable.clear()
|
||||
|
||||
# All test cases with proper isolation
|
||||
@pytest.mark.parametrize("case", [
|
||||
@pytest.mark.parametrize("test_input,expected,kwargs", [
|
||||
# Basic functionality
|
||||
{
|
||||
"id": "exclude_internal",
|
||||
"input": [("v1", "Visible", False), ("h1", "Hidden", True)],
|
||||
"expected": ["Visible"],
|
||||
"kwargs": {}
|
||||
},
|
||||
{
|
||||
"id": "include_internal",
|
||||
"input": [("v1", "Visible", False), ("h1", "Hidden", True)],
|
||||
"expected": ["Visible", "Hidden"],
|
||||
"kwargs": {"include_internal": True}
|
||||
},
|
||||
{
|
||||
"id": "empty_case",
|
||||
"input": [],
|
||||
"expected": [],
|
||||
"kwargs": {}
|
||||
},
|
||||
(
|
||||
[("v1", "Visible", False), ("h1", "Hidden", True)],
|
||||
["Visible"],
|
||||
{}
|
||||
),
|
||||
(
|
||||
[("v1", "Visible", False), ("h1", "Hidden", True)],
|
||||
["Visible", "Hidden"],
|
||||
{"include_internal": True}
|
||||
),
|
||||
(
|
||||
[],
|
||||
[],
|
||||
{}
|
||||
),
|
||||
|
||||
# All sorting variants
|
||||
{
|
||||
"id": "sort_repr",
|
||||
"input": [("3", "C"), ("1", "A"), ("2", "B")],
|
||||
"expected": ["A", "B", "C"],
|
||||
"kwargs": {"sort_key": repr}
|
||||
},
|
||||
{
|
||||
"id": "sort_str",
|
||||
"input": [("3", "C"), ("1", "A"), ("2", "B")],
|
||||
"expected": ["A", "B", "C"],
|
||||
"kwargs": {"sort_key": str}
|
||||
},
|
||||
{
|
||||
"id": "sort_id",
|
||||
"input": [("3", "C"), ("1", "A"), ("2", "B")],
|
||||
"expected": ["A", "B", "C"], # Sorted by ID
|
||||
"kwargs": {"sort_key": lambda a: a.ID}
|
||||
},
|
||||
{
|
||||
"id": "sort_lower",
|
||||
"input": [("3", "Charlie"), ("1", "alpha"), ("2", "Beta")],
|
||||
"expected": ["alpha", "Beta", "Charlie"],
|
||||
"kwargs": {"sort_key": lambda a: a.name.lower()}
|
||||
},
|
||||
{
|
||||
"id": "sort_length",
|
||||
"input": [("1", "A"), ("2", "BB"), ("3", "CCC")],
|
||||
"expected": ["A", "BB", "CCC"],
|
||||
"kwargs": {"sort_key": lambda a: len(a.name)}
|
||||
}
|
||||
], ids=lambda case: case["id"])
|
||||
def test_snapshot(case, clean_slate):
|
||||
"""Parametrized test covering all cases with proper isolation"""
|
||||
# Setup
|
||||
for args in case["input"]:
|
||||
FakeAdjustable(*args)
|
||||
(
|
||||
[("3", "C"), ("1", "A"), ("2", "B")],
|
||||
["A", "B", "C"],
|
||||
{"sort_key": repr}
|
||||
),
|
||||
(
|
||||
[("3", "C"), ("1", "A"), ("2", "B")],
|
||||
["A", "B", "C"],
|
||||
{"sort_key": str}
|
||||
),
|
||||
(
|
||||
[("3", "C"), ("1", "A"), ("2", "B")],
|
||||
["A", "B", "C"],
|
||||
{"sort_key": lambda a: a.ID}
|
||||
),
|
||||
(
|
||||
[("3", "Charlie"), ("1", "alpha"), ("2", "Beta")],
|
||||
["alpha", "Beta", "Charlie"],
|
||||
{"sort_key": lambda a: a.name.lower()}
|
||||
),
|
||||
(
|
||||
[("1", "A"), ("2", "BB"), ("3", "CCC")],
|
||||
["A", "BB", "CCC"],
|
||||
{"sort_key": lambda a: len(a.name)}
|
||||
)
|
||||
], ids=lambda x: x[1][0] if x[1] else "empty")
|
||||
def test_snapshot(test_input, expected, kwargs):
|
||||
"""Complete test with proper instance mocking"""
|
||||
# Create test objects
|
||||
test_objects = [FakeAdjustable(*args) for args in test_input]
|
||||
|
||||
# Mock the real registry to use our test doubles
|
||||
with patch('slic.utils.registry.instances',
|
||||
return_value=list(FakeAdjustable._registry)):
|
||||
# Mock the registry system at two levels:
|
||||
# 1. The instances() function
|
||||
# 2. The Adjustable._instances class attribute
|
||||
with patch('slic.utils.registry.instances') as mock_instances, \
|
||||
patch('slic.core.adjustable.Adjustable._instances', new_callable=MagicMock) as mock_adj:
|
||||
|
||||
# Configure mocks
|
||||
mock_instances.return_value = test_objects
|
||||
mock_adj.return_value = test_objects
|
||||
|
||||
# Execute
|
||||
result = snapshot(**case["kwargs"])
|
||||
result = snapshot(**kwargs)
|
||||
|
||||
# Verify
|
||||
if case["id"].startswith("sort_"):
|
||||
# For sorting tests, verify the order
|
||||
assert [x.name for x in result] == case["expected"]
|
||||
if "sort_key" in kwargs:
|
||||
# For sorting tests
|
||||
assert [x.name for x in result] == expected
|
||||
else:
|
||||
# For other tests, verify content
|
||||
assert set(x.name for x in result) == set(case["expected"])
|
||||
# For filtering tests
|
||||
assert {x.name for x in result} == set(expected)
|
||||
Reference in New Issue
Block a user