feat: 完成 issue #75 [Ti-1] 交接班摘要生成功能
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""交接班摘要生成器测试(issue #75)。
|
||||
|
||||
覆盖:
|
||||
1. 配置资产加载(章节/异常处置要求/默认班次);
|
||||
2. 事件归类(production/equipment/alarm/safety/todo + 未知 → 待办);
|
||||
3. 异常处置校验:缺失处置 → needs_followup + followup_items;
|
||||
4. 无异常事件 → 「本班无异常事项」占位;
|
||||
5. to_text Markdown 输出(标题/章节/待跟进标注)。
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import _bootstrap # noqa: F401
|
||||
|
||||
from ti_scenarios.handover import ( # noqa: E402
|
||||
DEFAULT_SECTIONS,
|
||||
HandoverGenerator,
|
||||
)
|
||||
|
||||
CONFIG = os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||
"config", "handover.template.yaml",
|
||||
)
|
||||
|
||||
|
||||
class TestConfigLoad(unittest.TestCase):
|
||||
"""配置资产加载。"""
|
||||
|
||||
def setUp(self):
|
||||
self.g = HandoverGenerator.from_template_config(CONFIG)
|
||||
|
||||
def test_sections_and_defaults(self):
|
||||
self.assertEqual([s["key"] for s in self.g.sections],
|
||||
[s["key"] for s in DEFAULT_SECTIONS])
|
||||
self.assertTrue(self.g.alarm_requires_disposal)
|
||||
self.assertEqual(self.g.default_shift, "甲班")
|
||||
|
||||
|
||||
class TestGenerate(unittest.TestCase):
|
||||
"""事件归类与摘要生成。"""
|
||||
|
||||
def setUp(self):
|
||||
self.g = HandoverGenerator.from_template_config(CONFIG)
|
||||
|
||||
def test_event_classification(self):
|
||||
events = [
|
||||
{"type": "production", "text": "生产平稳,产出 12 批", "time": "08:00"},
|
||||
{"type": "equipment", "text": "洗涤泵 A 运行正常"},
|
||||
{"type": "safety", "text": "巡检未发现隐患"},
|
||||
{"type": "todo", "text": "明日更换滤芯"},
|
||||
{"type": "未知类型", "text": "临时事项"},
|
||||
]
|
||||
report = self.g.generate(events, shift="甲班", date="2026-09-01")
|
||||
self.assertEqual(len(report.sections["production"]), 1)
|
||||
self.assertEqual(len(report.sections["equipment"]), 1)
|
||||
self.assertEqual(len(report.sections["safety"]), 1)
|
||||
self.assertEqual(len(report.sections["todo"]), 2) # 已知 + 未知类型
|
||||
self.assertFalse(report.needs_followup)
|
||||
|
||||
def test_alarm_with_disposal_ok(self):
|
||||
events = [{"type": "alarm", "text": "炉温超上限",
|
||||
"time": "09:12", "operator": "李工",
|
||||
"disposal": "已降低氯气流量,10 分钟内回落"}]
|
||||
report = self.g.generate(events, shift="乙班")
|
||||
self.assertEqual(len(report.sections["alarm"]), 1)
|
||||
self.assertFalse(report.needs_followup)
|
||||
|
||||
def test_alarm_missing_disposal_marks_followup(self):
|
||||
events = [{"type": "alarm", "text": "炉温超上限", "time": "09:12"}]
|
||||
report = self.g.generate(events)
|
||||
self.assertTrue(report.needs_followup)
|
||||
self.assertTrue(any("炉温超上限" in it for it in report.followup_items))
|
||||
|
||||
def test_no_alarm_placeholder(self):
|
||||
report = self.g.generate([{"type": "production", "text": "正常"}])
|
||||
self.assertEqual(report.sections["alarm"], ["本班无异常事项"])
|
||||
self.assertFalse(report.needs_followup)
|
||||
|
||||
def test_default_shift(self):
|
||||
report = self.g.generate([])
|
||||
self.assertEqual(report.shift, "甲班")
|
||||
|
||||
|
||||
class TestOutput(unittest.TestCase):
|
||||
"""Markdown 输出。"""
|
||||
|
||||
def test_to_text_sections(self):
|
||||
g = HandoverGenerator.from_template_config(CONFIG)
|
||||
report = g.generate([{"type": "alarm", "text": "炉温报警"}],
|
||||
shift="甲班", date="2026-09-01")
|
||||
text = report.to_text()
|
||||
self.assertIn("# 交接班摘要(2026-09-01 甲班)", text)
|
||||
self.assertIn("## 生产概况", text)
|
||||
self.assertIn("## 异常与处置", text)
|
||||
self.assertIn("待跟进", text) # 缺处置记录 → 待跟进标注
|
||||
self.assertIn("- 炉温报警", text)
|
||||
|
||||
def test_to_dict(self):
|
||||
report = HandoverGenerator().generate([])
|
||||
d = report.to_dict()
|
||||
self.assertEqual(set(d), {"shift", "date", "sections",
|
||||
"needs_followup", "followup_items"})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user