"""Unit: `cli.py cleanup` walks every backend (issue follow-up). Asserts cmd_cleanup queries each backend's `prepare_cleanup`, combines the y/N output, and runs each backend's `cleanup` when the operator confirms. Mocks the backends and stdin.""" from __future__ import annotations import sys import unittest from unittest.mock import patch, MagicMock from bot_bottle.cli import cleanup as cmd def _make_backend(empty: bool = True): backend = MagicMock() plan = MagicMock(empty=empty) backend.prepare_cleanup.return_value = plan backend.cleanup = MagicMock() return backend, plan class TestCmdCleanup(unittest.TestCase): def test_iterates_every_backend(self): docker, docker_plan = _make_backend(empty=False) smol, smol_plan = _make_backend(empty=False) backends_by_name = {"docker": docker, "smolmachines": smol} with patch.object( cmd, "known_backend_names", return_value=("docker", "smolmachines"), ), patch.object( cmd, "get_bottle_backend", side_effect=lambda name: backends_by_name[name], ), patch.object( cmd, "_prompt_yes", return_value=True, ): self.assertEqual(0, cmd.cmd_cleanup([])) docker.prepare_cleanup.assert_called_once() smol.prepare_cleanup.assert_called_once() docker.cleanup.assert_called_once_with(docker_plan) smol.cleanup.assert_called_once_with(smol_plan) def test_short_circuits_when_all_empty(self): docker, _ = _make_backend(empty=True) smol, _ = _make_backend(empty=True) backends_by_name = {"docker": docker, "smolmachines": smol} with patch.object( cmd, "known_backend_names", return_value=("docker", "smolmachines"), ), patch.object( cmd, "get_bottle_backend", side_effect=lambda name: backends_by_name[name], ), patch.object( cmd, "_prompt_yes", ) as prompt: self.assertEqual(0, cmd.cmd_cleanup([])) prompt.assert_not_called() docker.cleanup.assert_not_called() smol.cleanup.assert_not_called() def test_abort_at_prompt_runs_nothing(self): docker, _ = _make_backend(empty=False) smol, _ = _make_backend(empty=True) backends_by_name = {"docker": docker, "smolmachines": smol} with patch.object( cmd, "known_backend_names", return_value=("docker", "smolmachines"), ), patch.object( cmd, "get_bottle_backend", side_effect=lambda name: backends_by_name[name], ), patch.object( cmd, "_prompt_yes", return_value=False, ): self.assertEqual(0, cmd.cmd_cleanup([])) docker.cleanup.assert_not_called() smol.cleanup.assert_not_called() def test_skips_empty_plans_when_others_have_work(self): # docker has work, smolmachines doesn't — only docker.cleanup # is called. docker, docker_plan = _make_backend(empty=False) smol, _ = _make_backend(empty=True) backends_by_name = {"docker": docker, "smolmachines": smol} with patch.object( cmd, "known_backend_names", return_value=("docker", "smolmachines"), ), patch.object( cmd, "get_bottle_backend", side_effect=lambda name: backends_by_name[name], ), patch.object( cmd, "_prompt_yes", return_value=True, ): cmd.cmd_cleanup([]) docker.cleanup.assert_called_once_with(docker_plan) smol.cleanup.assert_not_called() if __name__ == "__main__": unittest.main()