test_user_standards.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. """
  2. 测试用户提供的4个标准规范
  3. 验证归一化匹配逻辑是否有效
  4. 直接使用生产代码 core.construction_review.component.standard_matching 模块
  5. """
  6. import asyncio
  7. import sys
  8. import os
  9. # 添加项目根目录到 Python 路径
  10. current_dir = os.path.dirname(os.path.abspath(__file__))
  11. project_root = os.path.dirname(os.path.dirname(current_dir))
  12. if project_root not in sys.path:
  13. sys.path.insert(0, project_root)
  14. from conftest import (
  15. StandardRepository,
  16. StandardMatcher,
  17. MatchResultCode,
  18. )
  19. # Mock 数据
  20. MOCK_DATA = [
  21. {"id": 1, "standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017", "validity": "XH"},
  22. {"id": 2, "standard_name": "铁路工程抗震设计规范", "standard_number": "GB 50111-2006", "validity": "XH"},
  23. {"id": 3, "standard_name": "铁路混凝土工程施工质量验收标准", "standard_number": "TB 10424-2018", "validity": "XH"},
  24. {"id": 4, "standard_name": "公路水运危险性较大工程专项施工方案编制审查规程", "standard_number": "JT/T 1495-2024", "validity": "XH"},
  25. ]
  26. def create_matcher():
  27. """创建加载了 Mock 数据的匹配器"""
  28. repo = StandardRepository()
  29. repo.load_data(MOCK_DATA)
  30. return StandardMatcher(repo)
  31. def check_standards(matcher, standards):
  32. """批量检查(模拟 StandardMatchingService.check_standards)"""
  33. results = []
  34. for idx, std in enumerate(standards, start=1):
  35. result = matcher.match(
  36. seq_no=idx,
  37. input_name=std.get("standard_name", ""),
  38. input_number=std.get("standard_number", "")
  39. )
  40. if result is not None:
  41. results.append(result)
  42. return results
  43. async def test_user_standards():
  44. """测试用户提供的4个标准"""
  45. matcher = create_matcher()
  46. # 用户提供的4个标准
  47. test_standards = [
  48. {"standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017"},
  49. {"standard_name": "铁路工程抗震设计规范", "standard_number": "GB 50111-2006"},
  50. {"standard_name": "铁路混凝土工程施工质量验收标准", "standard_number": "TB 10424-2018"},
  51. {"standard_name": "公路水运危险性较大工程专项施工方案编制审查规程", "standard_number": "JT/T 1495-2023"},
  52. ]
  53. print("=" * 80)
  54. print("测试用户提供的4个标准(使用生产代码归一化匹配)")
  55. print("=" * 80)
  56. results = check_standards(matcher, test_standards)
  57. all_passed = True
  58. for i, result in enumerate(results, 1):
  59. print(f"\n【{i}】{result.raw_name}")
  60. print(f" 标准号: {result.raw_number}")
  61. print(f" 状态码: {result.status_code}")
  62. print(f" 处理结果: {result.process_result}")
  63. print(f" 最终结果: {result.final_result}")
  64. # 验证预期结果
  65. if i <= 3:
  66. # 前3个应该是 OK
  67. if result.status_code != MatchResultCode.OK.value:
  68. print(f" [失败] 期望 OK,实际 {result.status_code}")
  69. all_passed = False
  70. else:
  71. print(f" [通过]")
  72. else:
  73. # 第4个应该是 MISMATCH(因为Mock数据中是2024版)
  74. if result.status_code != MatchResultCode.MISMATCH.value:
  75. print(f" [失败] 期望 MISMATCH,实际 {result.status_code}")
  76. all_passed = False
  77. else:
  78. print(f" [通过]")
  79. print("\n" + "=" * 80)
  80. if all_passed:
  81. print("[成功] 所有测试通过!")
  82. else:
  83. print("[失败] 部分测试失败!")
  84. print("=" * 80)
  85. return all_passed
  86. def test_with_bookname_variations():
  87. """测试书名号变体(归一化匹配)"""
  88. print("\n" + "=" * 80)
  89. print("测试书名号变体匹配(生产代码归一化)")
  90. print("=" * 80)
  91. repo = StandardRepository()
  92. mock_data = [
  93. {"id": 1, "standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017", "validity": "XH"},
  94. ]
  95. repo.load_data(mock_data)
  96. matcher = StandardMatcher(repo)
  97. # 测试各种名称变体
  98. test_cases = [
  99. ("铁路桥涵设计规范", "TB 10002-2017", "无书名号"),
  100. ("《铁路桥涵设计规范》", "TB 10002-2017", "带书名号"),
  101. ("铁路桥涵 设计规范", "TB 10002-2017", "带空格(归一化去除后匹配)"),
  102. ("《铁路桥涵 设计规范》", "TB 10002-2017", "带书名号和空格(归一化去除后匹配)"),
  103. ]
  104. all_passed = True
  105. for name, number, desc in test_cases:
  106. result = matcher.match(1, name, number)
  107. # 归一化会去除所有空白,所以带空格的变体也应匹配成功
  108. if result is not None and result.status_code == MatchResultCode.OK.value:
  109. status = "[OK]"
  110. else:
  111. status = "[FAIL]"
  112. all_passed = False
  113. print(f"\n{status} {desc}")
  114. print(f" 输入名称: {name}")
  115. if result:
  116. print(f" 结果: {result.status_code}")
  117. else:
  118. print(f" 结果: None(跳过审查)")
  119. return all_passed
  120. if __name__ == "__main__":
  121. # 运行异步测试
  122. result1 = asyncio.run(test_user_standards())
  123. # 运行书名号变体测试
  124. result2 = test_with_bookname_variations()
  125. print("\n" + "=" * 80)
  126. if result1 and result2:
  127. print("[成功] 所有测试通过!")
  128. sys.exit(0)
  129. else:
  130. print("[警告] 部分测试失败!")
  131. sys.exit(1)