"""公开 API 的表面测试。 ``chongming_task`` 的 ``__init__`` 是**嵌入其他应用**的入口,因此它本身的正确性 值得一条用例:漏导出某个名字、或者导出顺序导致循环导入,都会让集成方第一步就失败。 """ from __future__ import annotations import chongming_task def test_version_is_exposed() -> None: assert chongming_task.__version__ def test_all_has_no_duplicates() -> None: """重复导出会让"到底哪个生效"变得不确定。 顺序**不在这里**断言:``__all__`` 的排序由 ruff 的 ``RUF022``(isort 风格, 全大写常量优先)负责,那是 lint 的职责。写一条与 linter 规则不一致的断言, 只会让两边互相打架。 """ names = chongming_task.__all__ assert len(names) == len(set(names)) def test_every_exported_name_resolves() -> None: """``__all__`` 里写了却取不到,等于给集成方埋了一个 ImportError。""" missing = [name for name in chongming_task.__all__ if not hasattr(chongming_task, name)] assert missing == [] def test_primary_integration_surface_is_importable() -> None: """这一段就是 README 里"嵌入你自己的应用"的最小示例。""" from chongming_task import ( # noqa: F401 - 只为验证可导入 Controller, InMemoryTaskStore, SqliteTaskStore, TaskStatus, TaskStore, run_task, ) controller = Controller(max_parallel=2) assert controller.registry.names() == () assert TaskStatus.PENDING.value == "pending" assert callable(run_task) def test_store_implementations_satisfy_the_protocol() -> None: """存储实现必须满足契约——第三方后端也照这条自证。""" from chongming_task import InMemoryTaskStore, SqliteTaskStore, TaskStore assert isinstance(InMemoryTaskStore(), TaskStore) store = SqliteTaskStore(":memory:") try: assert isinstance(store, TaskStore) finally: # 不关掉连接会在解释器退出时触发 ResourceWarning;本项目的 pytest 配置 # 把 warning 升级为 error,因此泄漏是会被抓住的。 store.close() def test_controller_accepts_a_store() -> None: """存储已经接线。 这条用例原先钉的是"尚未接线"——当 ``Controller(store=...)`` 真的开始工作时, 它会自己失败并提示删掉。现在它钉的是接线本身。 """ from chongming_task import Controller, InMemoryTaskStore store = InMemoryTaskStore() controller = Controller(store=store, max_parallel=2) assert controller.store is store assert controller.persist_failures == () assert controller.owner def test_private_helpers_are_not_exported() -> None: """以下划线开头的实现细节不应出现在公开表面上。""" leaked = [name for name in chongming_task.__all__ if name.startswith("_")] assert leaked == []