"""显式消费范围和CLI入口的生命周期证据,不连接真实数据库。""" from contextlib import contextmanager from types import SimpleNamespace import pytest from muse.共享.错误 import 配置错误 from muse.接入.cli import 入口 @pytest.fixture def 装配范围(生命周期记录): """显式消费范围:进入应用生命周期后原样返回装配,退出时先于依赖夹具收尾。""" from contextlib import ExitStack 栈 = ExitStack() def 进入(app): 栈.enter_context(app.生命周期()) return app yield 进入 栈.close() @pytest.fixture def 生命周期记录(): events = [] yield events assert events[-1] == "close" assert events.count("open") == events.count("close") @pytest.mark.case_id("NC-O06-EXPLICIT-FIXTURE-CLOSE") def test_显式范围在依赖夹具退出前关闭(装配范围, 生命周期记录): class App: @contextmanager def 生命周期(self): 生命周期记录.append("open") try: yield finally: 生命周期记录.append("close") app = App() assert 装配范围(app) is app assert 生命周期记录 == ["open"] # 结束后的close顺序由生命周期记录fixture最终检查,防止DROP测试库时尚有池。 @pytest.mark.case_id("NC-O06-CLI-LIFESPAN") @pytest.mark.parametrize("failed", [False, True]) def test_CLI业务成功与异常都退出范围(monkeypatch, failed): events = [] class App: @contextmanager def 生命周期(self): events.append("open") try: yield finally: events.append("close") app = App() monkeypatch.setattr(入口, "读取配置", lambda _: object()) monkeypatch.setattr(入口, "构建默认运行", lambda _: app) def command(*args, **kwargs): assert events == ["open"] if failed: raise 配置错误("synthetic failure") return {"state": "completed"} monkeypatch.setattr("muse.接入.cli.任务命令.运行任务命令", command) assert 入口.main(["任务", "synthetic.toml", "查看", "task"]) == int(failed) assert events == ["open", "close"] @pytest.mark.case_id("NC-O06-CLI-NO-IO") @pytest.mark.parametrize( "command", [["--help"], ["自检", "synthetic.toml"], ["探索", "synthetic.toml", "列表"]] ) def test_帮助自检与私人文件探索不启动数据库(monkeypatch, command): def forbidden(*args, **kwargs): pytest.fail("此入口不应启动数据库provider或读取其凭据") app = SimpleNamespace(生命周期=forbidden) monkeypatch.setattr(入口, "读取配置", lambda _: object()) monkeypatch.setattr(入口, "构建", lambda _: app) monkeypatch.setattr(入口, "自检", lambda _: {"state": "assembled"}) monkeypatch.setattr( "muse.接入.cli.作品命令.运行探索命令", lambda *args, **kwargs: {"items": []} ) monkeypatch.setattr("muse.基础设施.数据库.连接.解析连接串", forbidden) if command == ["--help"]: with pytest.raises(SystemExit) as result: 入口.main(command) assert result.value.code == 0 else: assert 入口.main(command) == 0