test_user_standards.py 5.4 KB

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