Initial commit
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
"""M8 MCP 服务测试。
|
||||
|
||||
验证工具存在 + 格式化逻辑 + 降级行为,不依赖真实嵌入/检索。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from mcp_server.tools import (
|
||||
_fmt_results,
|
||||
mcp,
|
||||
search_company_news,
|
||||
search_news,
|
||||
search_sentiment_trend,
|
||||
search_stock_events,
|
||||
)
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 工具存在性
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def test_mcp_server_has_name() -> None:
|
||||
assert mcp.name == "A股DeepResearch"
|
||||
|
||||
|
||||
def test_all_five_tools_registered() -> None:
|
||||
tool_names = [getattr(t, "name", "") for t in mcp._tool_manager._tools.values()] # type: ignore[union-attr]
|
||||
expected = {
|
||||
"search_news", "search_company_news", "search_industry_news",
|
||||
"search_stock_events", "search_sentiment_trend",
|
||||
}
|
||||
assert set(tool_names) == expected
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# _fmt_results
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def _hit(title: str = "测试标题", source: str = "cls", score: float = 0.9,
|
||||
sentiment: str = "positive", stock_codes: list[str] | None = None,
|
||||
company_names: list[str] | None = None, summary: str = "摘要",
|
||||
publish_time: str = "2026-06-16T10:00:00",
|
||||
url: str = "https://example.com/1") -> dict:
|
||||
return {
|
||||
"title": title, "url": url, "source": source, "score": score,
|
||||
"publish_time": publish_time,
|
||||
"event": {
|
||||
"sentiment": sentiment, "importance": 4, "event_type": "重大合同",
|
||||
"stock_codes": stock_codes or [], "company_names": company_names or [],
|
||||
"industries": ["动力电池"], "summary": summary,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def test_fmt_results_contains_title_and_source() -> None:
|
||||
hits = [_hit("宁德时代签百亿合同", "cls")]
|
||||
out = _fmt_results(hits, "宁德时代")
|
||||
assert "百亿合同" in out
|
||||
assert "cls" in out
|
||||
assert "0.9" in out
|
||||
|
||||
|
||||
def test_fmt_results_includes_event_fields() -> None:
|
||||
hits = [_hit(
|
||||
company_names=["宁德时代"], stock_codes=["300750"],
|
||||
)]
|
||||
out = _fmt_results(hits, "查询")
|
||||
assert "300750" in out
|
||||
assert "宁德时代" in out
|
||||
assert "动力电池" in out
|
||||
assert "摘要" in out
|
||||
|
||||
|
||||
def test_fmt_results_empty_returns_hint() -> None:
|
||||
out = _fmt_results([], "无结果")
|
||||
assert "未找到" in out and "无结果" in out
|
||||
|
||||
|
||||
def test_fmt_results_multiple_hits() -> None:
|
||||
hits = [_hit(f"测试{i}") for i in range(3)]
|
||||
out = _fmt_results(hits, "查询")
|
||||
assert "共 3 条" in out
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 工具:降级行为(无精确命中时走纯语义)
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
@patch("mcp_server.tools._search")
|
||||
def test_search_company_news_falls_back_on_empty(mock_search) -> None:
|
||||
"""company 精确命中 0 条时,降级为无 filter 纯语义搜索。"""
|
||||
mock_search.side_effect = [
|
||||
[], # 第一次:精确匹配 0 条
|
||||
[_hit("fallback")], # 降级: 纯语义
|
||||
]
|
||||
out = search_company_news("查询", company="不存在的公司")
|
||||
assert "fallback" in out
|
||||
|
||||
|
||||
@patch("mcp_server.tools._search")
|
||||
def test_search_stock_events_normalizes_code(mock_search) -> None:
|
||||
"""stock_code 应去掉后缀,统一大写。"""
|
||||
mock_search.return_value = [_hit("结果")]
|
||||
out = search_stock_events("查询", stock_code="300750.SZ")
|
||||
mock_search.assert_called() # code 应为 '300750'
|
||||
assert "结果" in out
|
||||
|
||||
|
||||
@patch("mcp_server.tools._search")
|
||||
def test_search_sentiment_trend_includes_stats(mock_search) -> None:
|
||||
mock_search.return_value = [
|
||||
_hit("a", sentiment="positive"),
|
||||
_hit("b", sentiment="positive"),
|
||||
_hit("c", sentiment="negative"),
|
||||
_hit("d", sentiment="neutral"),
|
||||
]
|
||||
out = search_sentiment_trend("查询", sentiment="all", top_k=10)
|
||||
assert "利好 2" in out
|
||||
assert "利空 1" in out
|
||||
assert "中性 1" in out
|
||||
assert "共 4 条" in out
|
||||
|
||||
|
||||
@patch("mcp_server.tools._search")
|
||||
def test_search_news_passthrough(mock_search) -> None:
|
||||
mock_search.return_value = [_hit("结果")]
|
||||
out = search_news("查询")
|
||||
assert "结果" in out
|
||||
Reference in New Issue
Block a user