初始化提交
This commit is contained in:
commit
887c1f449e
963 files changed
+166869
No files matched your search
@@ -0,0 +1,77 @@
|
||||
"""事件存储测试:订阅推送、sequence 单调、run 隔离。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
import pytest
|
||||
|
||||
from app.modules.runtime.events import Event, InMemoryEventStore
|
||||
|
||||
|
||||
async def test_subscribe_receives_appended_event() -> None:
|
||||
store = InMemoryEventStore()
|
||||
queue = store.subscribe("run_1")
|
||||
await store.append(
|
||||
Event(type="tool.started", source="tool", run_id="run_1", payload={"tool": "calc"})
|
||||
)
|
||||
event = await asyncio.wait_for(queue.get(), timeout=1.0)
|
||||
assert event.type == "tool.started"
|
||||
assert event.run_id == "run_1"
|
||||
|
||||
|
||||
async def test_sequence_increments_per_run() -> None:
|
||||
store = InMemoryEventStore()
|
||||
first = await store.append(Event(type="tool.started", source="tool", run_id="r1"))
|
||||
second = await store.append(Event(type="tool.completed", source="tool", run_id="r1"))
|
||||
assert first.sequence == 1
|
||||
assert second.sequence == 2
|
||||
|
||||
|
||||
async def test_subscribe_isolated_by_run() -> None:
|
||||
store = InMemoryEventStore()
|
||||
queue_a = store.subscribe("run_a")
|
||||
await store.append(Event(type="x", source="tool", run_id="run_b"))
|
||||
with pytest.raises(asyncio.TimeoutError):
|
||||
await asyncio.wait_for(queue_a.get(), timeout=0.3)
|
||||
|
||||
|
||||
async def test_unsubscribe_stops_delivery() -> None:
|
||||
store = InMemoryEventStore()
|
||||
queue = store.subscribe("run_1")
|
||||
store.unsubscribe("run_1", queue)
|
||||
await store.append(Event(type="x", source="tool", run_id="run_1"))
|
||||
with pytest.raises(asyncio.TimeoutError):
|
||||
await asyncio.wait_for(queue.get(), timeout=0.3)
|
||||
|
||||
|
||||
async def test_subscribe_by_pattern_glob_match() -> None:
|
||||
"""subscribe_by_pattern('time.*') 仅收 type 匹配的事件,不收其它 type。"""
|
||||
store = InMemoryEventStore()
|
||||
queue = store.subscribe_by_pattern("time.*")
|
||||
await store.append(Event(type="time.reunion", source="time_sense"))
|
||||
await store.append(Event(type="run.started", source="run"))
|
||||
# time.reunion 命中,立即可取(append 内 put_nowait 同步执行)
|
||||
received = queue.get_nowait()
|
||||
assert received.type == "time.reunion"
|
||||
# run.started 不命中,队列应空
|
||||
assert queue.empty()
|
||||
|
||||
|
||||
async def test_unsubscribe_by_pattern_stops_delivery() -> None:
|
||||
"""unsubscribe_by_pattern 后不再收到事件。"""
|
||||
store = InMemoryEventStore()
|
||||
queue = store.subscribe_by_pattern("time.*")
|
||||
store.unsubscribe_by_pattern("time.*", queue)
|
||||
await store.append(Event(type="time.reunion", source="time_sense"))
|
||||
assert queue.empty()
|
||||
|
||||
|
||||
async def test_subscribe_by_pattern_wildcard_all() -> None:
|
||||
"""subscribe_by_pattern('*') 收所有 type(Dispatcher 用此订阅全量)。"""
|
||||
store = InMemoryEventStore()
|
||||
queue = store.subscribe_by_pattern("*")
|
||||
await store.append(Event(type="time.reunion", source="time_sense"))
|
||||
await store.append(Event(type="run.started", source="run"))
|
||||
assert queue.get_nowait().type == "time.reunion"
|
||||
assert queue.get_nowait().type == "run.started"
|
||||
@@ -0,0 +1,50 @@
|
||||
"""测试目标上下文注入。"""
|
||||
|
||||
from app.modules.runtime.goals import build_goals_context
|
||||
|
||||
|
||||
def test_build_goals_context_with_active_goals():
|
||||
"""生成了 Active Goals 系统提示片段。"""
|
||||
goals = [
|
||||
{
|
||||
"title": "学习 Python",
|
||||
"level": "long_term",
|
||||
"status": "active",
|
||||
"priority": 80,
|
||||
"progress": 0.5,
|
||||
},
|
||||
{
|
||||
"title": "完成项目文档",
|
||||
"level": "task",
|
||||
"status": "active",
|
||||
"priority": 60,
|
||||
"progress": 0.0,
|
||||
"parent_id": "goal_1",
|
||||
},
|
||||
]
|
||||
result = build_goals_context(goals)
|
||||
assert "学习 Python" in result
|
||||
assert "任务目标" in result or "task" in result or "长期目标" in result
|
||||
assert result.startswith("当前活跃目标:") or "当前" in result
|
||||
|
||||
|
||||
def test_build_goals_context_empty():
|
||||
assert build_goals_context([]) == ""
|
||||
|
||||
|
||||
def test_build_goals_context_sorts_by_priority():
|
||||
"""按优先级降序排列输出。"""
|
||||
goals = [
|
||||
{"title": "low", "level": "task", "status": "active", "priority": 10, "progress": 0.0},
|
||||
{
|
||||
"title": "high",
|
||||
"level": "long_term",
|
||||
"status": "active",
|
||||
"priority": 90,
|
||||
"progress": 0.5,
|
||||
},
|
||||
]
|
||||
result = build_goals_context(goals)
|
||||
high_idx = result.index("high")
|
||||
low_idx = result.index("low")
|
||||
assert high_idx < low_idx # high priority first
|
||||
Reference in new issue
Block a user