diff options
Diffstat (limited to 'tests')
| -rwxr-xr-x | tests/tmux-util/fake-fzf | 30 | ||||
| -rw-r--r-- | tests/tmux-util/test_tmux_util.py | 74 |
2 files changed, 101 insertions, 3 deletions
diff --git a/tests/tmux-util/fake-fzf b/tests/tmux-util/fake-fzf new file mode 100755 index 0000000..476bf7f --- /dev/null +++ b/tests/tmux-util/fake-fzf @@ -0,0 +1,30 @@ +#!/bin/sh +# Fake fzf for testing tmux-util. +# +# Control via env vars: +# FAKE_FZF_CHOICE_LINE — 1-based line index into stdin; that line is +# printed as the selection and exit 0. +# FAKE_FZF_CHOICE — print this literal string as the selection and +# exit 0 (ignored if FAKE_FZF_CHOICE_LINE is set). +# (neither set) — exit 130 (user cancelled). +# +# Every invocation is logged to $FAKE_TMUX_DIR/calls.log as one line. + +: "${FAKE_TMUX_DIR:?FAKE_TMUX_DIR must be set}" +printf 'fzf %s\n' "$*" >> "$FAKE_TMUX_DIR/calls.log" + +if [ -n "${FAKE_FZF_CHOICE_LINE:-}" ]; then + awk -v n="$FAKE_FZF_CHOICE_LINE" 'NR == n { print; exit }' + exit 0 +fi + +if [ -n "${FAKE_FZF_CHOICE:-}" ]; then + # Drain stdin so the pipe upstream doesn't SIGPIPE + cat >/dev/null + printf '%s\n' "$FAKE_FZF_CHOICE" + exit 0 +fi + +# Cancelled +cat >/dev/null +exit 130 diff --git a/tests/tmux-util/test_tmux_util.py b/tests/tmux-util/test_tmux_util.py index e313af6..afc1ebc 100644 --- a/tests/tmux-util/test_tmux_util.py +++ b/tests/tmux-util/test_tmux_util.py @@ -33,7 +33,7 @@ class TmuxUtilHarness(unittest.TestCase): # bin dir with the fakes symlinked under their canonical names self.bin_dir = os.path.join(self.tmp, "bin") os.makedirs(self.bin_dir) - for name in ("tmux", "kill", "sleep"): + for name in ("tmux", "kill", "sleep", "fzf"): fake = os.path.join(FAKES_DIR, f"fake-{name}") os.chmod(fake, os.stat(fake).st_mode | stat.S_IEXEC) os.symlink(fake, os.path.join(self.bin_dir, name)) @@ -128,8 +128,8 @@ class TestDispatch(TmuxUtilHarness): self.assertIn("Usage: tmux-util", result.stderr) def test_unimplemented_subcommand_exits_nonzero(self): - # go/pick/find/rename stub out for now; pick one to confirm the stub path. - result = self.run_script("pick") + # 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) @@ -549,5 +549,73 @@ class TestFindBoundary(TmuxUtilHarness): self.assertIn("missing pattern", result.stderr) +# ----------------------------------------------------------------------------- +# pick — Normal cases +# ----------------------------------------------------------------------------- + +class TestPickNormal(TmuxUtilHarness): + + def test_pick_attaches_chosen_session_outside_tmux(self): + self.set_sessions([ + ("foo", 1, ["101:zsh"], 950, 1, "/tmp/foo"), + ("bar", 0, ["201:zsh"], 900, 1, "/tmp/bar"), + ]) + # Pick the second line (bar) + env = {k: v for k, v in os.environ.items() if k != "TMUX"} + result = subprocess.run( + [SCRIPT, "pick"], + env={**env, "PATH": self.bin_dir + os.pathsep + env.get("PATH", ""), + "FAKE_TMUX_DIR": self.tmp, "FAKE_FZF_CHOICE_LINE": "2"}, + capture_output=True, text=True, timeout=10, + ) + self.assertEqual(result.returncode, 0, msg=result.stderr) + calls = self.tmux_calls() + self.assertTrue(any("attach-session -t bar" in c for c in calls), + f"expected attach-session -t bar in {calls!r}") + + def test_pick_switches_client_inside_tmux(self): + self.set_sessions([ + ("foo", 1, ["101:zsh"], 950, 1, "/tmp/foo"), + ("bar", 0, ["201:zsh"], 900, 1, "/tmp/bar"), + ]) + result = self.run_script("pick", env_extra={ + "TMUX": "/tmp/fake-tmux-socket,1234,0", + "FAKE_FZF_CHOICE_LINE": "1", # first line → foo + }) + self.assertEqual(result.returncode, 0, msg=result.stderr) + calls = self.tmux_calls() + self.assertTrue(any("switch-client -t foo" in c for c in calls), + f"expected switch-client -t foo in {calls!r}") + self.assertFalse(any("attach-session" in c for c in calls), + f"unexpected attach-session in {calls!r}") + + +# ----------------------------------------------------------------------------- +# pick — Boundary cases +# ----------------------------------------------------------------------------- + +class TestPickBoundary(TmuxUtilHarness): + + def test_pick_no_sessions_prints_message(self): + self.set_sessions([]) + result = self.run_script("pick") + 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()), + f"unexpected fzf call in {self.tmux_calls()!r}") + + def test_pick_user_cancels_fzf_returns_zero_no_attach(self): + self.set_sessions([ + ("foo", 1, ["101:zsh"], 950, 1, "/tmp/foo"), + ]) + # No FAKE_FZF_CHOICE / FAKE_FZF_CHOICE_LINE → fzf exits 130 (cancelled) + result = self.run_script("pick") + self.assertEqual(result.returncode, 0, msg=result.stderr) + calls = self.tmux_calls() + self.assertFalse(any("attach-session" in c or "switch-client" in c for c in calls), + f"unexpected attach/switch in {calls!r}") + + if __name__ == "__main__": unittest.main() |
