mirror of
https://github.com/langgenius/dify.git
synced 2026-02-11 19:00:44 -05:00
- 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.
249 lines
6.6 KiB
Python
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"
|