test_app.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. """
  2. 标准库匹配规则 - 实际调用测试
  3. 展示如何实际调用标准匹配逻辑进行标准检查
  4. 直接使用生产代码 core.construction_review.component.standard_matching 模块
  5. 使用说明:
  6. 1. MOCK_MODE = True: 使用模拟数据,无需数据库
  7. 2. MOCK_MODE = False: 使用真实数据库,需要确保 config/config.ini 配置正确
  8. """
  9. import sys
  10. import os
  11. # ==================== 配置区域 ====================
  12. # 设置为 True 使用 Mock 模式(无需数据库),False 使用真实数据库
  13. MOCK_MODE = True
  14. # ==================== 路径设置 ====================
  15. CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
  16. PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR))
  17. sys.path.insert(0, PROJECT_ROOT)
  18. # 真实模式下需要修改工作目录以读取配置文件
  19. if not MOCK_MODE:
  20. os.chdir(PROJECT_ROOT)
  21. import asyncio
  22. import json
  23. from conftest import (
  24. StandardRepository,
  25. StandardMatcher,
  26. MatchResultCode,
  27. )
  28. # Mock 数据
  29. MOCK_DATA = [
  30. {"id": 1, "standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017", "validity": "XH"},
  31. {"id": 2, "standard_name": "铁路工程抗震设计规范", "standard_number": "GB 50111-2006", "validity": "XH"},
  32. {"id": 3, "standard_name": "铁路混凝土工程施工质量验收标准", "standard_number": "TB 10424-2018", "validity": "XH"},
  33. {"id": 4, "standard_name": "公路水运危险性较大工程专项施工方案编制审查规程", "standard_number": "JT/T 1495-2024", "validity": "XH"},
  34. {"id": 5, "standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2016", "validity": "FZ"},
  35. {"id": 6, "standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2023", "validity": "XH"},
  36. {"id": 7, "standard_name": "缆索起重机", "standard_number": "GB/T 28756-2012", "validity": "FZ"},
  37. {"id": 8, "standard_name": "电力高处作业防坠器", "standard_number": "DL/T 1147-2009", "validity": "FZ"},
  38. ]
  39. class MockMatchingService:
  40. """模拟 StandardMatchingService 接口,使用生产代码的 Repository + Matcher"""
  41. def __init__(self, mock_data):
  42. self.repository = StandardRepository()
  43. self.repository.load_data(mock_data)
  44. self.matcher = StandardMatcher(self.repository)
  45. def check_single(self, seq_no, standard_name, standard_number):
  46. return self.matcher.match(seq_no, standard_name, standard_number)
  47. def check_standards(self, standards):
  48. results = []
  49. for idx, std in enumerate(standards, start=1):
  50. result = self.matcher.match(
  51. seq_no=idx,
  52. input_name=std.get("standard_name", ""),
  53. input_number=std.get("standard_number", "")
  54. )
  55. if result is not None:
  56. results.append(result)
  57. return results
  58. # ==================== 服务创建 ====================
  59. async def create_service():
  60. """创建并初始化服务实例"""
  61. if MOCK_MODE:
  62. print("[Mock 模式] 使用模拟数据,无需数据库连接")
  63. return MockMatchingService(MOCK_DATA)
  64. else:
  65. print("[真实模式] 连接数据库并加载标准数据...")
  66. from foundation.database.base.sql.async_mysql_conn_pool import AsyncMySQLPool
  67. db_pool = AsyncMySQLPool()
  68. await db_pool.initialize()
  69. from core.construction_review.component.standard_matching import StandardMatchingService
  70. service = StandardMatchingService(db_pool=db_pool)
  71. await service.initialize()
  72. return service
  73. # ==================== 测试函数 ====================
  74. async def test_single_standard(service):
  75. """测试单个标准检查"""
  76. print("\n" + "=" * 60)
  77. print("【测试1】单个标准检查")
  78. print("=" * 60)
  79. result = service.check_single(
  80. seq_no=1,
  81. standard_name="铁路桥涵设计规范",
  82. standard_number="TB 10002-2017"
  83. )
  84. print(f"\n序号: {result.seq_no}")
  85. print(f"原始标准: 《{result.raw_name}》({result.raw_number})")
  86. print(f"处理结果: {result.process_result}")
  87. print(f"状态码: {result.status_code}")
  88. print(f"结果消息: {result.final_result}")
  89. if result.substitute_number:
  90. print(f"替代标准: {result.substitute_name}({result.substitute_number})")
  91. async def test_batch_check(service):
  92. """测试批量标准检查 - 文档中的7个示例"""
  93. print("\n" + "=" * 60)
  94. print("【测试2】批量标准检查 - 文档中的7个示例")
  95. print("=" * 60)
  96. standards = [
  97. {"standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017"},
  98. {"standard_name": "铁路工程抗震设计规范", "standard_number": "GB 50111-2006"},
  99. {"standard_name": "铁路混凝土工程施工质量验收标准", "standard_number": "TB 10424-2018"},
  100. {"standard_name": "公路水运危险性较大工程专项施工方案编制审查规程", "standard_number": "JT/T 1495-2023"},
  101. {"standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2016"},
  102. {"standard_name": "缆索起重机", "standard_number": "GB/T 28756-2012"},
  103. {"standard_name": "电力高处作业防坠器", "standard_number": "DL/T 1147-2009"},
  104. ]
  105. results = service.check_standards(standards)
  106. print("\n检查结果汇总:")
  107. print("-" * 80)
  108. print(f"{'序号':<4} {'标准名称':<40} {'标准号':<20} {'状态':<12}")
  109. print("-" * 80)
  110. for r in results:
  111. print(f"{r.seq_no:<4} {r.raw_name:<40} {r.raw_number:<20} {r.status_code:<12}")
  112. print("\n" + "=" * 80)
  113. print("详细结果:")
  114. print("=" * 80)
  115. for r in results:
  116. print(f"\n【{r.seq_no}】{r.raw_name}")
  117. print(f" 标准号: {r.raw_number}")
  118. print(f" 状态: {r.process_result} ({r.status_code})")
  119. print(f" 结果: {r.final_result}")
  120. if r.substitute_number:
  121. print(f" -> 替代: {r.substitute_name}({r.substitute_number})")
  122. async def test_various_cases(service):
  123. """测试各种边界情况"""
  124. print("\n" + "=" * 60)
  125. print("【测试3】各种边界情况测试")
  126. print("=" * 60)
  127. test_cases = [
  128. {"name": "测试现行标准", "standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017"},
  129. {"name": "测试被替代", "standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2016"},
  130. {"name": "测试废止无替代", "standard_name": "缆索起重机", "standard_number": "GB/T 28756-2012"},
  131. {"name": "测试不匹配", "standard_name": "公路水运危险性较大工程专项施工方案编制审查规程", "standard_number": "JT/T 1495-2023"},
  132. {"name": "测试不存在", "standard_name": "不存在的标准", "standard_number": "GB/T 99999-9999"},
  133. ]
  134. for case in test_cases:
  135. result = service.check_single(
  136. seq_no=1,
  137. standard_name=case["standard_name"],
  138. standard_number=case["standard_number"]
  139. )
  140. print(f"\n--- {case['name']} ---")
  141. print(f"输入: 《{result.raw_name}》({result.raw_number})")
  142. print(f"输出: [{result.status_code}] {result.final_result}")
  143. async def export_results_to_json(service, filename="standard_check_results.json"):
  144. """导出检查结果为JSON文件"""
  145. print("\n" + "=" * 60)
  146. print("【测试4】导出结果为JSON")
  147. print("=" * 60)
  148. standards = [
  149. {"standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017"},
  150. {"standard_name": "铁路混凝土工程施工质量验收标准", "standard_number": "TB 10424-2018"},
  151. {"standard_name": "公路水运危险性较大工程专项施工方案编制审查规程", "standard_number": "JT/T 1495-2023"},
  152. {"standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2016"},
  153. ]
  154. results = service.check_standards(standards)
  155. output = []
  156. for r in results:
  157. output.append({
  158. "seq_no": r.seq_no,
  159. "raw_name": r.raw_name,
  160. "raw_number": r.raw_number,
  161. "substitute_name": r.substitute_name,
  162. "substitute_number": r.substitute_number,
  163. "process_result": r.process_result,
  164. "status_code": r.status_code,
  165. "final_result": r.final_result
  166. })
  167. with open(filename, "w", encoding="utf-8") as f:
  168. json.dump(output, f, ensure_ascii=False, indent=2)
  169. print(f"\n结果已导出到: {filename}")
  170. print(json.dumps(output, ensure_ascii=False, indent=2))
  171. # ==================== 主函数 ====================
  172. async def main():
  173. """主函数"""
  174. print("=" * 80)
  175. print("标准库匹配规则 - 实际调用测试(使用生产代码)")
  176. print("=" * 80)
  177. print(f"\n当前模式: {'Mock 测试模式(无需数据库)' if MOCK_MODE else '真实数据库模式'}")
  178. print("-" * 80)
  179. service = None
  180. try:
  181. # 创建并初始化服务
  182. service = await create_service()
  183. print(f"服务初始化成功! 数据已加载到内存\n")
  184. # 执行测试
  185. await test_single_standard(service)
  186. await test_batch_check(service)
  187. await test_various_cases(service)
  188. # await export_results_to_json(service) # 取消注释以测试JSON导出
  189. print("\n" + "=" * 80)
  190. print("所有测试执行完毕!")
  191. print("=" * 80)
  192. except Exception as e:
  193. print(f"\n错误: {e}")
  194. import traceback
  195. traceback.print_exc()
  196. if __name__ == "__main__":
  197. asyncio.run(main())