raw ยท 5422 bytes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | import sys import unittest from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from test_claims import git from test_cli import WF from test_setup import GitCli NONE = {"CLAUDE_CODE_MESSAGING_SOCKET": ""} class StartTest(GitCli): def setUp(self): super().setUp() self.wt = self.root / ".worktrees" / "slow" def start(self, *extra, code=0): got, out, err = self.wf("start", "t-three", "--worktree", ".worktrees/slow", "--branch", "slow/t-three", *extra, project=False, env=NONE) self.assertEqual(got, code, out + err) self.assertNotIn("Traceback", err) return out, err def branch(self): return (self.wt / ".git").is_file() and \ subprocess_out(self.wt, "branch", "--show-current") def test_new_worktree_setup_progress_ctx_finish_line(self): out, _ = self.start() self.assertEqual(self.branch(), "slow/t-three") self.assertEqual((self.wt / "log.txt").read_text(), "ran\n") # worktree_setup ran there self.assertIn("**t-three** [P2] (<1h) (in progress: slow/t-three): Three.", self.tasks()) self.assertIn("worktree: .worktrees/slow (new, branch slow/t-three from master)\n", out) self.assertEqual(out.count("- **t-three**"), 1, out) self.assertIn("worktree_setup: 2 commands ok in .worktrees/slow\n", out) self.assertIn("- **t-three** [P2] (<1h) (in progress: slow/t-three): Three.\n\nSection: Pending\n", out) self.assertTrue(out.endswith( f"Finish (after the work; fill in the quoted parts and the paths):\n" f" cd {self.wt} && (make test) && python3 {WF} finish t-three -m \"<entry>\" --commit \"<msg + footer>\" <paths>\n"), out) def test_existing_branch_new_worktree_reports_wip(self): git(self.root, "branch", "slow/t-three") out, _ = self.start() self.assertEqual(self.branch(), "slow/t-three") self.assertIn("worktree: .worktrees/slow (new, existing branch slow/t-three: earlier WIP, read the notes)\n", out) def test_existing_clean_worktree_switches(self): git(self.root, "worktree", "add", "-q", "--detach", str(self.wt), "master") out, _ = self.start() self.assertEqual(self.branch(), "slow/t-three") self.assertIn("worktree: .worktrees/slow (switched to new branch slow/t-three from master)\n", out) (self.wt / "log.txt").unlink() # setup output, not ignored here out, _ = self.start() # rerun: already there self.assertIn("worktree: .worktrees/slow (on slow/t-three)\n", out) def test_dirty_worktree_refused_without_recovery(self): git(self.root, "worktree", "add", "-q", "--detach", str(self.wt), "master") (self.wt / "DESIGN.md").write_text("changed\n") _, err = self.start(code=1) self.assertEqual(err, "wf: worktree .worktrees/slow has uncommitted changes: M DESIGN.md " "(hand back, or --recovery when a dead worker left them)\n") self.assertNotIn("in progress", self.tasks()) self.assertFalse((self.wt / "log.txt").exists()) def test_recovery_keeps_dirty_wip_and_shows_it(self): git(self.root, "worktree", "add", "-q", str(self.wt), "-b", "slow/t-three") (self.wt / "DESIGN.md").write_text("changed\n") out, _ = self.start("--recovery") self.assertEqual((self.wt / "DESIGN.md").read_text(), "changed\n") self.assertIn("recovery: uncommitted:\n M DESIGN.md\n", out) self.assertIn("recovery: commits master..HEAD: none\n", out) self.assertIn("(in progress: slow/t-three)", self.tasks()) def test_recovery_dirty_on_other_branch_refused(self): git(self.root, "worktree", "add", "-q", "--detach", str(self.wt), "master") (self.wt / "DESIGN.md").write_text("changed\n") _, err = self.start("--recovery", code=1) self.assertIn("uncommitted changes on another branch", err) def test_setup_failure_stops_before_progress(self): (self.root / "workflow.toml").write_text(self.toml.replace('"echo ran >> log.txt"', '"false"')) git(self.root, "commit", "-qam", "red setup") _, err = self.start(code=1) self.assertIn("worktree_setup 'false' failed", err) self.assertNotIn("in progress", self.tasks()) def test_unknown_id_creates_nothing(self): got, out, err = self.wf("start", "t-nope", "--worktree", ".worktrees/slow", "--branch", "b", project=False, env=NONE) self.assertEqual(got, 1, out + err) self.assertFalse(self.wt.exists()) def test_inside_worktree_refused(self): git(self.root, "worktree", "add", "-q", "--detach", str(self.wt), "master") got, out, err = self.wf("start", "t-three", "--worktree", str(self.wt), "--branch", "b", project=False, cwd=self.wt, env=NONE) self.assertEqual((got, err), (1, "wf: start runs in the main tree (it creates the worktree)\n")) def subprocess_out(cwd, *args): import subprocess return subprocess.run(["git", "-C", str(cwd), *args], capture_output=True, text=True).stdout.strip() if __name__ == "__main__": unittest.main() |