test_app.py 9.5 KB

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