Created
September 8, 2019 17:37
-
-
Save 0xee/e5644097fa7e233d3a70c49cdc2634bb to your computer and use it in GitHub Desktop.
Bash prompt test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Checks if the bash prompt is setup correctly, i.e. if all non-printable | |
# characters are escaped correctly using \[...\] and if wide characters | |
# (eg. emoji) are displayed correctly by the terminal. | |
# | |
# Should work on any bash prompt, including ones containing colors, multiple | |
# lines, unicode characters, etc. | |
# | |
# The tests are performed by running a shell in a clean tmux session, | |
# optionally also running a custom setup command ($1, if provided). The setup | |
# command is just typed into the shell, so even ssh to another host is | |
# possible. | |
# | |
# The tests can be watched by attaching to the tmux session from another | |
# terminal, eg. like this: | |
# | |
# > while true; do tmux attach -t test-bash-config; sleep 1; done | |
# | |
# In this case it might be useful to increase the delay in the pause function | |
# to see what happens in slow motion. This can also help if the tests fail | |
# due to slow execution. | |
# optional setup command which will be executed in the | |
setup="$1" | |
export -n TMUX | |
session="test-bash-config" | |
p="$session:0.0" | |
tmux kill-session -t $session | |
tmux new-session -d -s $session | |
function pause { | |
sleep 0.01 | |
} | |
function send { | |
tmux send-keys -t $p "$@" | |
pause | |
} | |
function getLine { | |
offset=${1:-0} | |
tmux copy-mode -t $p | |
pause | |
for _ in $(seq $offset); do | |
send Up | |
pause | |
done | |
send -X select-line | |
pause | |
send -X copy-selection-and-cancel | |
pause | |
tmux show-buffer | |
} | |
# set terminal width to 40 characters to get a deterministic terminal size | |
tmux setw -t $session:0 force-width 40 | |
sleep 1 | |
if [[ -n "$setup" ]]; then | |
send "$setup" | |
send Enter | |
sleep 2 | |
fi | |
send "cd ~" | |
send Enter | |
echo "Determining prompt" | |
pause | |
send X | |
promptWithDelim="$(getLine)" | |
send C-c | |
prompt="${promptWithDelim%X}" | |
echo "Detected prompt: '$prompt'" | |
echo | |
echo "Test 1:" | |
# Send as many characters as the terminal is wide and check if they wrap | |
# correctly to the next line. The previous line should then contain the prompt | |
# and the beginning of the typed sequence. | |
send true # clear error indicators from prompt | |
send Enter | |
pause | |
send xxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy | |
pause | |
line="$(getLine 1)" | |
send C-c | |
send Enter | |
echo "Expected: '$prompt ?xxxy.*'" | |
echo "Actual: '$line'" | |
if grep -e "${prompt} \?xxxy.*" <<<"$line"; then | |
echo "Success" | |
else | |
echo "Fail" | |
fi | |
echo | |
echo "Test 2:" | |
# Run a command that is exactly the width of the terminal, run another command, | |
# and check if the first command can be reproduced by typing arrow up two | |
# times. The previous line should contain the prompt and the beginning of the | |
# command. | |
send Enter | |
send "echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | |
send Enter | |
send "echo yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" | |
send Enter | |
send Up | |
send Up | |
line="$(getLine 1)" | |
echo "Expected: '$prompt ?echo x.*'" | |
echo "Actual: '$line'" | |
if grep -e "${prompt} \?echo x.*" <<<"$line"; then | |
echo "Success" | |
else | |
echo "Fail" | |
fi | |
echo "Cleaning up" | |
tmux kill-session -t $session |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment