mirror of
https://github.com/ZhuLinsen/daily_stock_analysis
synced 2026-09-20 10:53:33 +08:00
* fix: support KR stock autocomplete suggestions * fix(review-feedback-1723): 补充自动补全 JP/KR 建议渲染截图、前后对比或无法截图说明 * fix(review-feedback-1723): 补充 Web 自动补全 JP/KR 建议渲染的截图或无法截图说明 * fix(review-feedback-1723): docs/review-evidence-kr-autocomplete-ui.md 是针对本 PR * fix(review-feedback-1723): 修正 PR 描述与当前 head 的实际改动、验证范围不一致问题 * fix(review-feedback-1723): 修正 PR 描述与当前 diff 的实质性不一致,避免合入记录误导后续维护者 * fix(review-feedback-1723): 收敛 PR 描述与实际 diff 的契约不一致,避免用户误以为裸 005930 已会解析为 005930.KS * fix(review-feedback-1723): 把描述、验证证据和兼容性说明收敛到当前 6 个改动文件真实范围,或补齐描述中声称的后端/历史链路实现与测试 * fix(review-feedback-1723): 收敛 PR 描述与实际 diff,避免把未实现的 bare-code/历史展示能力作为本 PR 已交付内容合入 * fix(review-feedback-1723): 补上相应真实代码与测试后再审 * fix(review-feedback-1723): 补齐所声称的后端实现与测试后再评审 * fix(review-feedback-1723): PR description 与当前完整 diff 不一致:描述声称新增 bare JP/KR code * fix(review-feedback-1723): PR 描述与当前完整 diff 不一致 * fix(review-feedback-1723): 补充 Refs 1718,方便后续追踪 * fix(review-feedback-1723): 收敛描述与验证证据 * fix: resolve JP KR bare stock codes * fix: backfill JP KR daily analysis context * fix(review-feedback-1723): preserve persisted phase timing * fix: align JP KR history lookup keys * fix(review-feedback-1723): preserve raw code for snapshot lookups * fix(review-feedback-1723): 收敛
95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Regression tests for TaskService failure handling.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import unittest
|
|
import threading
|
|
from types import ModuleType, SimpleNamespace
|
|
from unittest.mock import patch
|
|
from unittest.mock import MagicMock
|
|
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
|
|
from tests.litellm_stub import ensure_litellm_stub
|
|
|
|
ensure_litellm_stub()
|
|
|
|
from src.analyzer import AnalysisResult
|
|
from src.services.task_service import TaskService
|
|
|
|
|
|
def _make_failed_result(code: str) -> AnalysisResult:
|
|
return AnalysisResult(
|
|
code=code,
|
|
name=f"股票{code}",
|
|
sentiment_score=80,
|
|
trend_prediction="看多",
|
|
operation_advice="持有",
|
|
analysis_summary="解析失败",
|
|
success=False,
|
|
error_message="JSON 解析失败",
|
|
)
|
|
|
|
|
|
class _FakePipeline:
|
|
def __init__(self, *args, **kwargs):
|
|
self.args = args
|
|
self.kwargs = kwargs
|
|
|
|
def process_single_stock(self, *args, **kwargs):
|
|
return _make_failed_result(kwargs["code"])
|
|
|
|
|
|
class TestTaskService(unittest.TestCase):
|
|
def test_run_analysis_marks_failed_for_unsuccessful_result(self):
|
|
service = TaskService()
|
|
service._tasks = {}
|
|
service._tasks_lock = threading.Lock()
|
|
|
|
fake_main = ModuleType("main")
|
|
fake_main.StockAnalysisPipeline = _FakePipeline
|
|
|
|
with patch.dict("sys.modules", {"main": fake_main}), patch(
|
|
"src.config.get_config", return_value=SimpleNamespace()
|
|
):
|
|
result = service._run_analysis(code="600519", task_id="task-1")
|
|
|
|
self.assertFalse(result["success"])
|
|
self.assertEqual(result["error"], "JSON 解析失败")
|
|
task = service.get_task_status("task-1")
|
|
self.assertIsNotNone(task)
|
|
self.assertEqual(task["status"], "failed")
|
|
self.assertEqual(task["error"], "JSON 解析失败")
|
|
self.assertIsNone(task["result"])
|
|
|
|
def test_submit_analysis_resolves_bare_jp_kr_code_before_submit(self):
|
|
service = TaskService()
|
|
service._tasks = {}
|
|
service._tasks_lock = threading.Lock()
|
|
captured = {}
|
|
|
|
executor = MagicMock()
|
|
|
|
def capture_submit(*args, **kwargs):
|
|
captured["args"] = args
|
|
return "future"
|
|
|
|
executor.submit.side_effect = capture_submit
|
|
service._executor = executor
|
|
|
|
with patch("src.services.task_service.resolve_index_stock_code_for_analysis", return_value="005930.KS"):
|
|
result = service.submit_analysis("005930", report_type="simple", query_source="cli")
|
|
|
|
self.assertEqual(result["code"], "005930.KS")
|
|
self.assertIn("args", captured)
|
|
self.assertEqual(captured["args"][1], "005930.KS")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import unittest
|
|
|
|
unittest.main()
|