main zmx / test / cwd.bats
chamard  ·  2026-09-05
  1#!/usr/bin/env bats
  2# Working directory tracking tests for zmx.
  3#
  4# zmx learns a session's cwd from the OSC 7 the shell emits, which arrives as a
  5# percent-encoded file://<host><path> URI. That URI is what `list` reports, so
  6# the host stays visible and you can tell an SSH session apart from a local one.
  7# These tests pin that output plus the thing it depends on: the URI is decoded
  8# for the chdir, so a new session lands in a directory whose name needed
  9# escaping.
 10
 11load test_helper
 12
 13# Emit an OSC 7 for $2 from inside session $1, as a shell integration would.
 14osc7_session() {
 15  local name="$1" path="$2" encoded
 16  # Percent-encode spaces, the character that actually broke the chdir. The %
 17  # is doubled because this goes through printf, which would otherwise read
 18  # "%20s" as a width specifier.
 19  encoded="${path// /%%20}"
 20  "$ZMX" run "$name" -d sh -c \
 21    "printf '\033]7;file://$(hostname)$encoded\007marker-$name\n'; sleep 30"
 22}
 23
 24@test "list: reports the cwd in OSC 7 form, host included" {
 25  local dir="$BATS_TEST_TMPDIR/zmx spaced dir"
 26  mkdir -p "$dir"
 27
 28  osc7_session test-cwd-uri "$dir"
 29  wait_for_session test-cwd-uri
 30  wait_for_output test-cwd-uri marker-test-cwd-uri
 31  wait_for_cwd test-cwd-uri "cwd=file://$(hostname)${dir// /%20}"
 32
 33  run "$ZMX" list
 34  [ "$status" -eq 0 ]
 35  [[ "$output" == *"cwd=file://$(hostname)${dir// /%20}"* ]]
 36}
 37
 38@test "list: shows a remote cwd's host, so SSH is visible" {
 39  "$ZMX" run test-cwd-remote -d sh -c \
 40    "printf '\033]7;file://some-remote-box/home/me\007marker-remote\n'; sleep 30"
 41  wait_for_session test-cwd-remote
 42  wait_for_output test-cwd-remote marker-remote
 43  wait_for_cwd test-cwd-remote "cwd=file://some-remote-box/home/me"
 44
 45  run "$ZMX" list
 46  [ "$status" -eq 0 ]
 47  [[ "$output" == *"cwd=file://some-remote-box/home/me"* ]]
 48}
 49
 50@test "list: reports an OSC 7 URI even when given a plain path" {
 51  # `zmx run` hands the daemon the client's cwd as a path, so this covers the
 52  # encode direction rather than the decode one.
 53  cd "$BATS_TEST_TMPDIR"
 54  "$ZMX" run test-cwd-encode -d sleep 30
 55  wait_for_session test-cwd-encode
 56
 57  run "$ZMX" list
 58  [ "$status" -eq 0 ]
 59  [[ "$output" == *"cwd=file://$(hostname)/"* ]]
 60}
 61
 62@test "new session starts in a cwd whose name needed escaping" {
 63  local dir="$BATS_TEST_TMPDIR/zmx spaced dir"
 64  mkdir -p "$dir"
 65
 66  cd "$dir"
 67  "$ZMX" run test-cwd-chdir -d sh -c 'pwd; sleep 30'
 68  wait_for_session test-cwd-chdir
 69  wait_for_output test-cwd-chdir "zmx spaced dir"
 70
 71  # `pwd` inside the session is what the daemon actually chdir'd into. Compare
 72  # basenames because macOS resolves /tmp to /private/tmp.
 73  run "$ZMX" history test-cwd-chdir
 74  [ "$status" -eq 0 ]
 75  [[ "$output" == *"/zmx spaced dir"* ]]
 76}
 77
 78@test "unchanged OSC 7 is not logged again after output or queries" {
 79  local name=test-cwd-unchanged uri=file://localhost/tmp
 80  "$ZMX" run "$name" -d sh -c \
 81    'printf "\033]7;file://localhost/tmp\007cwd-ready\n"; cat'
 82  wait_for_output "$name" cwd-ready
 83  wait_for_cwd "$name" "cwd=$uri"
 84
 85  "$ZMX" send "$name" $'ordinary-output\n'
 86  wait_for_output "$name" ordinary-output
 87  printf '\033]7;%s\007repeated-cwd\n' "$uri" | "$ZMX" print "$name"
 88  wait_for_output "$name" repeated-cwd
 89  wait_for_cwd "$name" "cwd=$uri"
 90
 91  [ "$(grep -Fc "set cwd=$uri path=/tmp" "$ZMX_DIR/logs/$name.log")" -eq 1 ]
 92}
 93
 94@test "OSC 7 tracks changed directories and returning to a previous directory" {
 95  local name=test-cwd-changes uri
 96  "$ZMX" run "$name" -d cat
 97  wait_for_session "$name"
 98
 99  for uri in file://localhost/tmp/a%20b file://some-remote-box/home/me file://localhost/tmp/a%20b; do
100    printf '\033]7;%s\007' "$uri" | "$ZMX" print "$name"
101    wait_for_cwd "$name" "cwd=$uri"
102  done
103}