Files
dify/api/tests/unit_tests/libs/test_attr_map.py
Harry 9d80770dfc feat(sandbox): enhance sandbox management and tool artifact handling
- Introduced SandboxManager.delete_storage method for improved storage management.
- Refactored skill loading and tool artifact handling in DifyCliInitializer and SandboxBashSession.
- Updated LLMNode to extract and compile tool artifacts, enhancing integration with skills.
- Improved attribute management in AttrMap for better error handling and retrieval methods.
2026-01-22 17:26:09 +08:00

249 lines
6.6 KiB
Python

import pytest
from libs.attr_map import AttrKey, AttrMap, AttrMapKeyError, AttrMapTypeError
class TestAttrKey:
def test_identity_based_equality(self):
key1 = AttrKey("session", str)
key2 = AttrKey("session", str)
assert key1 != key2
assert key1 == key1
def test_identity_based_hash(self):
key1 = AttrKey("session", str)
key2 = AttrKey("session", str)
assert hash(key1) != hash(key2)
assert hash(key1) == hash(key1)
def test_can_be_used_as_dict_key(self):
key1 = AttrKey("session", str)
key2 = AttrKey("session", str)
data: dict[AttrKey[str], str] = {}
data[key1] = "value1"
data[key2] = "value2"
assert data[key1] == "value1"
assert data[key2] == "value2"
assert len(data) == 2
def test_properties(self):
key = AttrKey("my_key", int)
assert key.name == "my_key"
assert key.type_ is int
def test_repr(self):
key = AttrKey("session", str)
assert repr(key) == "AttrKey('session', str)"
class TestAttrMap:
def test_set_and_get(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
attrs.set(key, "hello")
result = attrs.get(key)
assert result == "hello"
def test_get_raises_when_not_set(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
with pytest.raises(AttrMapKeyError) as exc_info:
attrs.get(key)
assert exc_info.value.key is key
def test_get_or_none_returns_none_for_missing(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
assert attrs.get_or_none(key) is None
def test_get_or_none_returns_value_when_set(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
attrs.set(key, "hello")
assert attrs.get_or_none(key) == "hello"
def test_get_or_default_returns_value_when_set(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
attrs.set(key, "hello")
result = attrs.get_or_default(key, "default")
assert result == "hello"
def test_get_or_default_returns_default_when_not_set(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
result = attrs.get_or_default(key, "default")
assert result == "default"
def test_has(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
assert not attrs.has(key)
attrs.set(key, "hello")
assert attrs.has(key)
def test_remove_existing(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
attrs.set(key, "hello")
result = attrs.remove(key)
assert result is True
assert not attrs.has(key)
def test_remove_non_existing(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
result = attrs.remove(key)
assert result is False
def test_set_if_absent_when_absent(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
result = attrs.set_if_absent(key, "first")
assert result == "first"
assert attrs.get(key) == "first"
def test_set_if_absent_when_present(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
attrs.set(key, "existing")
result = attrs.set_if_absent(key, "new")
assert result == "existing"
assert attrs.get(key) == "existing"
def test_clear(self):
key1: AttrKey[str] = AttrKey("key1", str)
key2: AttrKey[int] = AttrKey("key2", int)
attrs = AttrMap()
attrs.set(key1, "hello")
attrs.set(key2, 42)
attrs.clear()
assert len(attrs) == 0
assert not attrs.has(key1)
assert not attrs.has(key2)
def test_len(self):
key1: AttrKey[str] = AttrKey("key1", str)
key2: AttrKey[int] = AttrKey("key2", int)
attrs = AttrMap()
assert len(attrs) == 0
attrs.set(key1, "hello")
assert len(attrs) == 1
attrs.set(key2, 42)
assert len(attrs) == 2
def test_repr(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
attrs.set(key, "hello")
result = repr(attrs)
assert "AttrMap" in result
assert "session" in result
class TestAttrMapTypeValidation:
def test_set_with_wrong_type_raises(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
with pytest.raises(AttrMapTypeError) as exc_info:
attrs.set(key, 123) # type: ignore[arg-type]
assert exc_info.value.key is key
assert exc_info.value.expected_type is str
assert exc_info.value.actual_type is int
def test_set_with_validate_false_allows_wrong_type(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
attrs.set(key, 123, validate=False) # type: ignore[arg-type]
assert attrs.get(key) == 123
def test_set_if_absent_with_wrong_type_raises(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
with pytest.raises(AttrMapTypeError):
attrs.set_if_absent(key, 123) # type: ignore[arg-type]
def test_set_if_absent_with_validate_false_allows_wrong_type(self):
key: AttrKey[str] = AttrKey("session", str)
attrs = AttrMap()
attrs.set_if_absent(key, 123, validate=False) # type: ignore[arg-type]
assert attrs.get(key) == 123
def test_subclass_type_validation(self):
class Animal:
pass
class Dog(Animal):
pass
key: AttrKey[Animal] = AttrKey("animal", Animal)
attrs = AttrMap()
attrs.set(key, Dog())
assert isinstance(attrs.get(key), Dog)
class TestAttrMapIsolation:
def test_different_keys_with_same_name_are_isolated(self):
key_in_module_a: AttrKey[str] = AttrKey("config", str)
key_in_module_b: AttrKey[str] = AttrKey("config", str)
attrs = AttrMap()
attrs.set(key_in_module_a, "value_a")
attrs.set(key_in_module_b, "value_b")
assert attrs.get(key_in_module_a) == "value_a"
assert attrs.get(key_in_module_b) == "value_b"
def test_multiple_attr_maps_are_independent(self):
key: AttrKey[str] = AttrKey("session", str)
attrs1 = AttrMap()
attrs2 = AttrMap()
attrs1.set(key, "map1")
attrs2.set(key, "map2")
assert attrs1.get(key) == "map1"
assert attrs2.get(key) == "map2"