cmd_template_replace test.

This commit is contained in:
Nicholas Marriott
2026-07-17 09:29:40 +01:00
parent 43092f8d54
commit 5cd43626ef

View File

@@ -0,0 +1,181 @@
#!/bin/sh
# Exercise cmd_template_replace through command-prompt, which passes prompt
# input as argv to args_make_commands. This covers the quoting modes, indexed
# replacements, and cases where replacements are intentionally not made.
PATH=/bin:/usr/bin
TERM=screen
LC_ALL=C.UTF-8
LANG=C.UTF-8
export TERM LC_ALL LANG
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
TMP=$(mktemp -d) || exit 1
TMUX_TMPDIR="$TMP"
export TMUX_TMPDIR
OUT="$TEST_TMUX -LtestA$$ -f/dev/null"
IN="$TEST_TMUX -LtestB$$ -f/dev/null"
cleanup()
{
$OUT kill-server 2>/dev/null
$IN kill-server 2>/dev/null
rm -rf "$TMP"
}
trap cleanup EXIT
fail()
{
echo "[FAIL] $1"
exit 1
}
settle()
{
sleep 0.5
}
wait_option()
{
option=$1
expected=$2
i=0
while [ "$i" -lt 30 ]; do
value=$($IN show -gqv "$option" 2>/dev/null || true)
[ "$value" = "$expected" ] && return 0
i=$((i + 1))
sleep 0.2
done
fail "expected $option to be '$expected' but got '$value'"
}
accept_prompt()
{
key=$1
value=$2
$OUT send-keys "$key" || exit 1
settle
$OUT send-keys -l "$value" || exit 1
$OUT send-keys Enter || exit 1
settle
}
accept_two_prompts()
{
key=$1
first=$2
second=$3
$OUT send-keys "$key" || exit 1
settle
$OUT send-keys -l "$first" || exit 1
$OUT send-keys Enter || exit 1
settle
$OUT send-keys -l "$second" || exit 1
$OUT send-keys Enter || exit 1
settle
}
reset_options()
{
for option in \
@r @first @second @plain @raw_tail @one @two @two_again \
@double_index @marker; do
$IN set -g "$option" SENTINEL || exit 1
done
$IN set -g @marker unchanged || exit 1
}
$IN new -d -x80 -y24 "sh -c 'exec sleep 1000'" || exit 1
$IN set -g status on || exit 1
$IN set -g status-keys emacs || exit 1
$IN set -g window-size manual || exit 1
$IN bind -n M-s command-prompt -p '(single)' "set -g @r '%%'" ||
exit 1
$IN bind -n M-f command-prompt -p '(first)' \
"set -g @first '%%' ; set -g @second '%%'" ||
exit 1
$IN bind -n M-d command-prompt -p '(double)' 'set -g @r "%%%"' ||
exit 1
$IN bind -n M-r command-prompt -p '(raw)' "set -g @r %1" ||
exit 1
$IN bind -n M-a command-prompt -p '(all)' \
"set -g @first %1 ; set -g @second %1" ||
exit 1
$IN bind -n M-m command-prompt -p 'one,two' \
"set -g @one %1 ; set -g @two %2 ; set -g @two_again %2" ||
exit 1
$IN bind -n M-i command-prompt -p 'one,two' 'set -g @double_index "%2%"' ||
exit 1
$IN bind -n M-n command-prompt -p '(none)' \
"set -g @plain no-template-markers" ||
exit 1
$OUT new -d -x80 -y24 || exit 1
$OUT set -g status off || exit 1
$OUT set -g window-size manual || exit 1
$OUT send-keys -l "$IN attach" || exit 1
$OUT send-keys Enter || exit 1
sleep 1
reset_options
# %% is for templates already inside single quotes. A single quote in the
# replacement must stay data and must not close the surrounding quotes.
payload="can't ; set -g @marker changed ; done"
accept_prompt M-s "$payload"
wait_option @r "$payload"
wait_option @marker unchanged
# Only the first %% is replaced.
reset_options
payload="first'value"
accept_prompt M-f "$payload"
wait_option @first "$payload"
wait_option @second %%
# %%% keeps the previous double-quote escaping behaviour.
reset_options
payload='a"$;~\z'
accept_prompt M-d "$payload"
wait_option @r "$payload"
# %1 is intentionally left raw as an escape hatch.
reset_options
$IN set -g @raw_tail unchanged || exit 1
accept_prompt M-r 'raw ; set -g @raw_tail yes'
wait_option @r raw
wait_option @raw_tail yes
# All instances of %1 are replaced.
reset_options
accept_prompt M-a repeat
wait_option @first repeat
wait_option @second repeat
# %1 and %2 select different prompt values, and all instances of %2 are
# replaced.
reset_options
accept_two_prompts M-m one two
wait_option @one one
wait_option @two two
wait_option @two_again two
# %idx% uses double-quote escaping for indexed replacements.
reset_options
payload='b"$;~\y'
accept_two_prompts M-i ignored "$payload"
wait_option @double_index "$payload"
# A template without replacement markers is left alone.
reset_options
accept_prompt M-n 'unused ; set -g @marker changed'
wait_option @plain no-template-markers
wait_option @marker unchanged
exit 0