""" 标准库匹配规则单元测试 - 内存处理版本 测试文档中定义的5种匹配情况 """ import sys import os # 添加项目根目录到 Python 路径 current_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(os.path.dirname(current_dir)) if project_root not in sys.path: sys.path.insert(0, project_root) import pytest import asyncio from utils_test.standard_new_Test.standard_service import ( StandardRepository, StandardMatcher, StandardMatchingService, MatchResultCode, ValidityStatus, StandardRecord ) @pytest.fixture def mock_repository(): """创建模拟的数据仓库""" repo = StandardRepository() mock_data = [ # 情况1: 正常现行标准 {"id": 1, "standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017", "validity": "XH"}, {"id": 2, "standard_name": "铁路工程抗震设计规范", "standard_number": "GB 50111-2006", "validity": "XH"}, {"id": 3, "standard_name": "铁路混凝土工程施工质量验收标准", "standard_number": "TB 10424-2018", "validity": "XH"}, # 情况4: 不匹配(年份错误)- 输入2023,实际2024 {"id": 4, "standard_name": "公路水运危险性较大工程专项施工方案编制审查规程", "standard_number": "JT/T 1495-2024", "validity": "XH"}, # 情况2: 被替代(废止+有现行替代) {"id": 5, "standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2016", "validity": "FZ"}, {"id": 6, "standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2023", "validity": "XH"}, # 情况3: 废止无替代 {"id": 7, "standard_name": "缆索起重机", "standard_number": "GB/T 28756-2012", "validity": "FZ"}, {"id": 8, "standard_name": "电力高处作业防坠器", "standard_number": "DL/T 1147-2009", "validity": "FZ"}, ] repo.load_data(mock_data) return repo @pytest.fixture def matcher(mock_repository): """创建匹配器实例""" return StandardMatcher(mock_repository) @pytest.fixture def mock_service(): """创建使用Mock数据的服务""" service = StandardMatchingService(db_pool=None) # 同步初始化(测试时使用event loop) loop = asyncio.get_event_loop() loop.run_until_complete(service.initialize()) return service class TestStandardRepository: """测试数据仓库""" def test_load_data(self, mock_repository): """测试数据加载""" assert len(mock_repository.get_all_records()) == 8 def test_find_by_number_exact(self, mock_repository): """测试精确匹配标准号""" result = mock_repository.find_by_number_exact("TB 10002-2017") assert result is not None assert result.standard_name == "铁路桥涵设计规范" def test_find_by_name_exact(self, mock_repository): """测试精确匹配名称""" result = mock_repository.find_by_name_exact("铁路桥涵设计规范") assert result is not None assert result.standard_number == "TB 10002-2017" def test_find_current_by_name(self, mock_repository): """测试查询现行标准""" results = mock_repository.find_current_by_name("起重机 钢丝绳 保养、维护、检验和报废") assert len(results) == 1 assert results[0].standard_number == "GB/T 5972-2023" class TestStandardMatcher: """测试匹配器""" def test_case1_ok(self, matcher): """情况1: 状态正常""" result = matcher.match(1, "铁路桥涵设计规范", "TB 10002-2017") assert result.status_code == MatchResultCode.OK.value assert result.final_result == "无问题" def test_case2_substituted(self, matcher): """情况2: 被替代""" result = matcher.match(1, "起重机 钢丝绳 保养、维护、检验和报废", "GB/T 5972-2016") assert result.status_code == MatchResultCode.SUBSTITUTED.value assert result.substitute_number == "GB/T 5972-2023" assert "已废止" in result.final_result def test_case3_abolished(self, matcher): """情况3: 废止无替代""" result = matcher.match(1, "缆索起重机", "GB/T 28756-2012") assert result.status_code == MatchResultCode.ABOLISHED.value assert "无现行状态" in result.final_result def test_case4_mismatch(self, matcher): """情况4: 不匹配""" result = matcher.match(1, "公路水运危险性较大工程专项施工方案编制审查规程", "JT/T 1495-2023") assert result.status_code == MatchResultCode.MISMATCH.value assert result.substitute_number == "JT/T 1495-2024" def test_case5_not_found(self, matcher): """情况5: 不存在""" result = matcher.match(1, "不存在的标准", "GB/T 99999-9999") assert result.status_code == MatchResultCode.NOT_FOUND.value class TestStandardMatchingService: """测试服务类""" def test_check_single(self, mock_service): """测试单个检查""" result = mock_service.check_single(1, "铁路桥涵设计规范", "TB 10002-2017") assert result.status_code == MatchResultCode.OK.value def test_check_standards_batch(self, mock_service): """测试批量检查""" standards = [ {"standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017"}, {"standard_name": "缆索起重机", "standard_number": "GB/T 28756-2012"}, {"standard_name": "不存在的标准", "standard_number": "GB/T 99999-9999"}, ] results = mock_service.check_standards(standards) assert len(results) == 3 assert results[0].status_code == MatchResultCode.OK.value assert results[1].status_code == MatchResultCode.ABOLISHED.value assert results[2].status_code == MatchResultCode.NOT_FOUND.value class TestDocumentExamples: """测试文档中列出的7个示例""" @pytest.fixture def doc_matcher(self): """文档测试专用匹配器""" repo = StandardRepository() mock_data = [ {"id": 1, "standard_name": "铁路桥涵设计规范", "standard_number": "TB 10002-2017", "validity": "XH"}, {"id": 2, "standard_name": "铁路工程抗震设计规范", "standard_number": "GB 50111-2006", "validity": "XH"}, {"id": 3, "standard_name": "铁路混凝土工程施工质量验收标准", "standard_number": "TB 10424-2018", "validity": "XH"}, {"id": 4, "standard_name": "公路水运危险性较大工程专项施工方案编制审查规程", "standard_number": "JT/T 1495-2024", "validity": "XH"}, {"id": 5, "standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2016", "validity": "FZ"}, {"id": 6, "standard_name": "起重机 钢丝绳 保养、维护、检验和报废", "standard_number": "GB/T 5972-2023", "validity": "XH"}, {"id": 7, "standard_name": "缆索起重机", "standard_number": "GB/T 28756-2012", "validity": "FZ"}, {"id": 8, "standard_name": "电力高处作业防坠器", "standard_number": "DL/T 1147-2009", "validity": "FZ"}, ] repo.load_data(mock_data) return StandardMatcher(repo) def test_example_1_railway_bridge(self, doc_matcher): """(1)《铁路桥涵设计规范》(TB 10002-2017) - 正常""" result = doc_matcher.match(1, "铁路桥涵设计规范", "TB 10002-2017") assert result.status_code == MatchResultCode.OK.value def test_example_2_seismic_design(self, doc_matcher): """(2)《铁路工程抗震设计规范》(GB 50111-2006) - 正常""" result = doc_matcher.match(1, "铁路工程抗震设计规范", "GB 50111-2006") assert result.status_code == MatchResultCode.OK.value def test_example_3_concrete(self, doc_matcher): """(3)《铁路混凝土工程施工质量验收标准》(TB 10424-2018) - 正常""" result = doc_matcher.match(1, "铁路混凝土工程施工质量验收标准", "TB 10424-2018") assert result.status_code == MatchResultCode.OK.value def test_example_4_highway_mismatch(self, doc_matcher): """(4)年份不匹配 - 应为2024""" result = doc_matcher.match(1, "公路水运危险性较大工程专项施工方案编制审查规程", "JT/T 1495-2023") assert result.status_code == MatchResultCode.MISMATCH.value assert result.substitute_number == "JT/T 1495-2024" def test_example_5_crane_wire_substituted(self, doc_matcher): """(5)被替代 GB/T 5972-2016 -> GB/T 5972-2023""" result = doc_matcher.match(1, "起重机 钢丝绳 保养、维护、检验和报废", "GB/T 5972-2016") assert result.status_code == MatchResultCode.SUBSTITUTED.value assert result.substitute_number == "GB/T 5972-2023" def test_example_6_cable_crane_abolished(self, doc_matcher): """(6)废止无替代""" result = doc_matcher.match(1, "缆索起重机", "GB/T 28756-2012") assert result.status_code == MatchResultCode.ABOLISHED.value def test_example_7_safety_device_abolished(self, doc_matcher): """(7)废止无替代""" result = doc_matcher.match(1, "电力高处作业防坠器", "DL/T 1147-2009") assert result.status_code == MatchResultCode.ABOLISHED.value if __name__ == "__main__": pytest.main([__file__, "-v"])