核心变更: - engine.py(1781行)拆分为8个独立模块: lifecycle/security/deps/ datastore/pl_injector/watcher/signature/manager - 新增plugin-bridge: 事件总线 + 服务注册 + RPC通信 - 新增i18n: 国际化/多语言翻译支持 - 新增plugin-storage: 插件键值/文件存储 - 新增ws-api: WebSocket实时通信(pub/sub + 自定义处理器) - nodejs-adapter统一为Plugin ABC模式 Bug修复: - 修复load_all()中store_dir未定义崩溃 - 修复DependencyResolver入度计算(拓扑排序) - 修复PermissionError隐藏内置异常 - 修复CORS中间件头部未附加到响应 - 修复IntegrityChecker跳过__pycache__目录 - 修复版本号不一致(v2.0.0→v1.2.0) - 修复测试文件的Logger导入/路径/私有方法调用 - 修复context.py缺少typing导入 - 修复config.py STORE_DIR默认路径(./mods→./store) 测试覆盖: 14→91个测试, 全部通过
89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
"""Tests for plugin-storage plugin"""
|
|
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
import json
|
|
import pytest
|
|
from pathlib import Path
|
|
|
|
PLUGIN_DIR = Path(__file__).parent.parent / "store" / "NebulaShell" / "plugin-storage"
|
|
sys.path.insert(0, str(PLUGIN_DIR))
|
|
|
|
import importlib.util
|
|
spec = importlib.util.spec_from_file_location("storage_main", str(PLUGIN_DIR / "main.py"))
|
|
main_module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(main_module)
|
|
PluginStorage = main_module.PluginStorage
|
|
|
|
|
|
class TestPluginStorage:
|
|
@pytest.fixture
|
|
def storage(self, tmp_path):
|
|
s = PluginStorage()
|
|
s._base_dir = tmp_path / "plugin-storage"
|
|
s._base_dir.mkdir(parents=True, exist_ok=True)
|
|
return s
|
|
|
|
def test_set_and_get(self, storage):
|
|
storage.set("test-plugin", "name", "hello")
|
|
assert storage.get("test-plugin", "name") == "hello"
|
|
|
|
def test_get_default(self, storage):
|
|
assert storage.get("test-plugin", "missing", "default") == "default"
|
|
|
|
def test_get_nonexistent(self, storage):
|
|
assert storage.get("test-plugin", "missing") is None
|
|
|
|
def test_delete(self, storage):
|
|
storage.set("test-plugin", "key", "val")
|
|
assert storage.get("test-plugin", "key") == "val"
|
|
storage.delete("test-plugin", "key")
|
|
assert storage.get("test-plugin", "key") is None
|
|
|
|
def test_list_keys(self, storage):
|
|
storage.set("test-plugin", "a", 1)
|
|
storage.set("test-plugin", "b", 2)
|
|
keys = storage.list_keys("test-plugin")
|
|
assert "a" in keys
|
|
assert "b" in keys
|
|
|
|
def test_clear(self, storage):
|
|
storage.set("test-plugin", "x", 1)
|
|
storage.clear("test-plugin")
|
|
assert storage.get("test-plugin", "x") is None
|
|
|
|
def test_raw_storage(self, storage):
|
|
storage.set_raw("test-plugin", "data.bin", b"hello world")
|
|
assert storage.get_raw("test-plugin", "data.bin") == b"hello world"
|
|
|
|
def test_delete_raw(self, storage):
|
|
storage.set_raw("test-plugin", "tmp.bin", b"123")
|
|
assert storage.get_raw("test-plugin", "tmp.bin") is not None
|
|
storage.delete_raw("test-plugin", "tmp.bin")
|
|
assert storage.get_raw("test-plugin", "tmp.bin") is None
|
|
|
|
def test_storage_size(self, storage):
|
|
storage.set("test-plugin", "a", "hello")
|
|
size = storage.get_storage_size("test-plugin")
|
|
assert size > 0
|
|
|
|
def test_get_info(self, storage):
|
|
info = storage.get_info()
|
|
assert "base_dir" in info
|
|
assert "plugins" in info
|
|
|
|
def test_lifecycle(self, storage):
|
|
storage.init()
|
|
storage.start()
|
|
storage.stop()
|
|
|
|
def test_json_types(self, storage):
|
|
data = {"nested": [1, 2, 3], "flag": True, "val": None}
|
|
storage.set("test-plugin", "complex", data)
|
|
assert storage.get("test-plugin", "complex") == data
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pytest.main([__file__, '-v'])
|