"""FactorEngine 与 Metadata 集成测试。 测试 add_factor_by_name 方法的功能。 """ import pytest from src.factors import FactorEngine from src.factors.metadata import FactorManager class TestFactorEngineMetadataIntegration: """测试 FactorEngine 与 Metadata 的集成功能。""" @pytest.fixture def metadata_file(self): """使用 data 目录下的 factors.jsonl 文件。""" return "data/factors.jsonl" def test_init_without_metadata(self): """测试不启用 metadata 时初始化引擎。""" engine = FactorEngine() assert engine._metadata is None def test_init_with_metadata(self, metadata_file): """测试启用 metadata 时初始化引擎。""" engine = FactorEngine(metadata_path=metadata_file) assert engine._metadata is not None assert isinstance(engine._metadata, FactorManager) def test_add_factor_by_name_success(self, metadata_file): """测试从 metadata 成功添加因子。""" engine = FactorEngine(metadata_path=metadata_file) # 添加 return_5 因子 result = engine.add_factor_by_name("return_5") # 验证链式调用返回自身 assert result is engine # 验证因子已注册 assert "return_5" in engine.list_registered() def test_add_factor_by_name_with_alias(self, metadata_file): """测试使用别名添加因子。""" engine = FactorEngine(metadata_path=metadata_file) # 使用不同名称注册 metadata 中的因子 engine.add_factor_by_name("my_ma", "ma_5") # 验证使用别名注册的因子 assert "my_ma" in engine.list_registered() assert "ma_5" not in engine.list_registered() def test_add_factor_by_name_not_found(self, metadata_file): """测试添加不存在的因子时抛出异常。""" engine = FactorEngine(metadata_path=metadata_file) with pytest.raises(ValueError) as exc_info: engine.add_factor_by_name("nonexistent_factor") assert "未找到因子" in str(exc_info.value) assert "nonexistent_factor" in str(exc_info.value) def test_add_factor_by_name_without_metadata(self): """测试未配置 metadata 时调用 add_factor_by_name 抛出异常。""" engine = FactorEngine() # 不传入 metadata_path with pytest.raises(RuntimeError) as exc_info: engine.add_factor_by_name("return_5") assert "未配置 metadata 路径" in str(exc_info.value) def test_chain_calls(self, metadata_file): """测试链式调用。""" engine = FactorEngine(metadata_path=metadata_file) # 链式添加多个因子 ( engine.add_factor_by_name("return_5") .add_factor_by_name("ma_5") .add_factor_by_name("custom_ma20", "ma_20") ) # 验证所有因子都已注册 assert "return_5" in engine.list_registered() assert "ma_5" in engine.list_registered() assert "custom_ma20" in engine.list_registered() def test_add_factor_by_name_preserves_existing_add_factor(self, metadata_file): """测试 add_factor_by_name 不影响原有的 add_factor 方法。""" engine = FactorEngine(metadata_path=metadata_file) # 使用 add_factor 添加字符串表达式 engine.add_factor("manual_factor", "ts_mean(close, 10)") # 使用 add_factor_by_name 添加 metadata 因子 engine.add_factor_by_name("return_5") # 验证两者都正常工作 assert "manual_factor" in engine.list_registered() assert "return_5" in engine.list_registered() if __name__ == "__main__": pytest.main([__file__, "-v"])