diff options
Diffstat (limited to 'tests')
| -rwxr-xr-x | tests/tmux-util/fake-tmux | 28 | ||||
| -rw-r--r-- | tests/tmux-util/test_tmux_util.py | 105 |
2 files changed, 126 insertions, 7 deletions
diff --git a/tests/tmux-util/fake-tmux b/tests/tmux-util/fake-tmux index b5a1e61..1b84956 100755 --- a/tests/tmux-util/fake-tmux +++ b/tests/tmux-util/fake-tmux @@ -151,6 +151,34 @@ case "$cmd" in attach-session|switch-client) # No state mutation needed — the call log already records intent. ;; + rename-session) + # Forms: rename-session -t <old> <new> OR rename-session <new> + old="" + new="" + while [ "$#" -gt 0 ]; do + case "$1" in + -t) shift; old="$1"; shift ;; + *) new="$1"; shift ;; + esac + done + if [ -z "$old" ] || [ -z "$new" ]; then + echo "fake-tmux rename-session: need both -t <old> and <new>" >&2 + exit 1 + fi + tmp="$STATE.tmp" + : > "$tmp" + while IFS= read -r line; do + [ -n "$line" ] || continue + first="${line%% *}" + rest="${line#* }" + if [ "$first" = "$old" ]; then + printf '%s %s\n' "$new" "$rest" >> "$tmp" + else + printf '%s\n' "$line" >> "$tmp" + fi + done < "$STATE" + mv "$tmp" "$STATE" + ;; kill-session) session="" while [ "$#" -gt 0 ]; do diff --git a/tests/tmux-util/test_tmux_util.py b/tests/tmux-util/test_tmux_util.py index afc1ebc..b3eab8d 100644 --- a/tests/tmux-util/test_tmux_util.py +++ b/tests/tmux-util/test_tmux_util.py @@ -66,7 +66,7 @@ class TmuxUtilHarness(unittest.TestCase): pids_csv = ",".join(str(p) for p in pids) if pids else "-" f.write(f"{name} {attached} {pids_csv} {activity} {windows} {cwd}\n") - def run_script(self, *args, env_extra=None): + def run_script(self, *args, env_extra=None, stdin=None): env = os.environ.copy() # Prepend the bin dir so the fakes win env["PATH"] = self.bin_dir + os.pathsep + env.get("PATH", "") @@ -76,6 +76,7 @@ class TmuxUtilHarness(unittest.TestCase): return subprocess.run( [SCRIPT] + list(args), env=env, + input=stdin, capture_output=True, text=True, timeout=10, @@ -127,12 +128,6 @@ class TestDispatch(TmuxUtilHarness): self.assertIn("unknown subcommand", result.stderr) self.assertIn("Usage: tmux-util", result.stderr) - def test_unimplemented_subcommand_exits_nonzero(self): - # rename stubs out for now; pick one to confirm the stub path. - result = self.run_script("rename") - self.assertNotEqual(result.returncode, 0) - self.assertIn("not implemented yet", result.stderr) - # ----------------------------------------------------------------------------- # Reap — Normal cases @@ -617,5 +612,101 @@ class TestPickBoundary(TmuxUtilHarness): f"unexpected attach/switch in {calls!r}") +# ----------------------------------------------------------------------------- +# rename — Normal cases +# ----------------------------------------------------------------------------- + +class TestRenameNormal(TmuxUtilHarness): + + def test_rename_picks_session_and_renames_it(self): + self.set_sessions([ + ("old", 0, ["101:zsh"], 950, 1, "/tmp/old"), + ("other", 0, ["201:zsh"], 900, 1, "/tmp/other"), + ]) + result = self.run_script( + "rename", + env_extra={"FAKE_FZF_CHOICE_LINE": "1"}, # picks "old" + stdin="new\n", + ) + self.assertEqual(result.returncode, 0, msg=result.stderr) + calls = self.tmux_calls() + self.assertTrue( + any("rename-session -t old new" in c for c in calls), + f"expected rename-session -t old new in {calls!r}", + ) + # State should reflect the rename + names = self.remaining_sessions() + self.assertIn("new", names) + self.assertIn("other", names) + self.assertNotIn("old", names) + self.assertIn("Renamed: old", result.stdout) + + +# ----------------------------------------------------------------------------- +# rename — Boundary / Error cases +# ----------------------------------------------------------------------------- + +class TestRenameBoundary(TmuxUtilHarness): + + def test_rename_no_sessions_prints_message(self): + self.set_sessions([]) + result = self.run_script("rename") + self.assertEqual(result.returncode, 0) + self.assertIn("No tmux sessions", result.stdout) + # fzf should never have been invoked + self.assertFalse(any(c.startswith("fzf ") for c in self.tmux_calls())) + + def test_rename_user_cancels_fzf_no_action(self): + self.set_sessions([ + ("old", 0, ["101:zsh"], 950, 1, "/tmp/old"), + ]) + # No FAKE_FZF_CHOICE → fzf exits 130 + result = self.run_script("rename") + self.assertEqual(result.returncode, 0, msg=result.stderr) + self.assertFalse(any("rename-session" in c for c in self.tmux_calls())) + # State unchanged + self.assertEqual(self.remaining_sessions(), ["old"]) + + def test_rename_empty_new_name_exits_nonzero(self): + self.set_sessions([ + ("old", 0, ["101:zsh"], 950, 1, "/tmp/old"), + ]) + result = self.run_script( + "rename", + env_extra={"FAKE_FZF_CHOICE_LINE": "1"}, + stdin="\n", # empty new name + ) + self.assertNotEqual(result.returncode, 0) + self.assertIn("empty new name", result.stderr) + self.assertFalse(any("rename-session" in c for c in self.tmux_calls())) + + def test_rename_same_name_is_noop(self): + self.set_sessions([ + ("old", 0, ["101:zsh"], 950, 1, "/tmp/old"), + ]) + result = self.run_script( + "rename", + env_extra={"FAKE_FZF_CHOICE_LINE": "1"}, + stdin="old\n", # same as current name + ) + self.assertEqual(result.returncode, 0, msg=result.stderr) + self.assertIn("same as old", result.stdout) + self.assertFalse(any("rename-session" in c for c in self.tmux_calls())) + + def test_rename_conflict_with_existing_exits_nonzero(self): + self.set_sessions([ + ("old", 0, ["101:zsh"], 950, 1, "/tmp/old"), + ("taken", 0, ["201:zsh"], 900, 1, "/tmp/taken"), + ]) + result = self.run_script( + "rename", + env_extra={"FAKE_FZF_CHOICE_LINE": "1"}, # picks "old" + stdin="taken\n", # collides with existing + ) + self.assertNotEqual(result.returncode, 0) + self.assertIn("already exists", result.stderr) + self.assertFalse(any("rename-session" in c for c in self.tmux_calls())) + + if __name__ == "__main__": unittest.main() |
