#!/bin/sh
set -eu
. tests/lib.sh
export XDG_DATA_HOME="$PWD/tests/test-profiles"
export LANG=C.UTF-8
INPUT='a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
w
x
y
z'
pick_x() {
OUT="$(mkstemp)"
ERR="$(mkstemp)"
PICK="$1"
echo "${2:-$INPUT}" | \
./src/remembering \
-p "$PROFILE" \
-- sh -c "tee -a /dev/stderr | grep -F \"$PICK\"" \
1>"$OUT" 2>"$ERR"
STATUS=$?
assert_status 0
assert_stdout "$PICK"
}
assert_first() {
FIRST="$(head -n1 "$ERR")"
if [ "$FIRST" != "$1" ]; then
printf '\n%s: Previous choice did not appear at the beginning of the list:\n\nexpected: %s\ngot: %s\n' \
"$(ERROR)" "$1" "$FIRST" >&2
exit 1
fi
}
BASE_PROFILE='0 profile a
0 profile b
0 profile c
0 profile d
0 profile e'
BASE_PROFILE_A_PICKED='1 profile a
0 profile b
0 profile c
0 profile d
0 profile e'
assert_profile() {
if [ "$(cat "$XDG_DATA_HOME/remembering/$1")" != "$2" ]; then
printf '\n%s: Bad profile merge (%s).\n\nExpected:\n%s\nGot\n%s\n' \
"$(ERROR)" "$PROFILE" "$2" "$(cat "$XDG_DATA_HOME/remembering/$1")" >&2
print_debug_info
exit 1
fi
}
test_picking_first_makes_it_be_always_first() {
testing 'picking first makes it be always first'
N="$LINENO"
OUT="$(mkstemp)"
ERR="$(mkstemp)"
PROFILE="always-picks-first-$(uuid)"
for _ in $(seq 10); do
printf 'always-picked\nnever-picked\n' | \
./src/remembering \
-p "$PROFILE" \
-- head -n1 \
1>"$OUT" 2>"$ERR"
STATUS=$?
assert_status 0
assert_empty_stderr
assert_stdout 'always-picked'
done
test_ok
}
test_promoting_values() {
testing 'promoting values'
N="$LINENO"
PROFILE="promoting-$(uuid)"
pick_x h
pick_x z # just to get the new STDIN
assert_first h
pick_x h
pick_x z
assert_first h
test_ok
}
test_higher_values_loose_tie() {
testing 'higher values loose tie'
N="$LINENO"
PROFILE="higher-loose-tie-$(uuid)"
pick_x f
pick_x f
pick_x g
pick_x g
pick_x z
assert_first f
test_ok
}
test_smaller_values_win_tie() {
testing 'smaller values win tie'
N="$LINENO"
PROFILE="smaller-win-tie-$(uuid)"
pick_x d
pick_x d
pick_x c
pick_x c
pick_x z
assert_first c
test_ok
}
test_many_sequential_picks() {
testing 'many sequential pick'
N="$LINENO"
PROFILE="many-sequential-picks-$(uuid)"
pick_x b
pick_x r
pick_x l
pick_x r
pick_x s
pick_x a
pick_x d
pick_x m
pick_x g
pick_x g
pick_x l
pick_x l
pick_x f
pick_x f
pick_x f
pick_x l
pick_x a
pick_x z
assert_first l
EXPECTED='l
f
a
g
r
b
d
m
s'
ACTUAL="$(head -n9 "$ERR")"
if [ "$ACTUAL" != "$EXPECTED" ]; then
printf '\n%s: Bad order!\n\nexpected: %s\ngot: %s\n' \
"$(ERROR)" \
"$(echo "$EXPECTED" | tr '\n' ' ')" \
"$(echo "$ACTUAL" | tr '\n' ' ')" \
>&2
exit 1
fi
test_ok
}
test_pick_inexisting_value() {
testing 'pick inexisting value'
N="$LINENO"
OUT="$(mkstemp)"
ERR="$(mkstemp)"
PROFILE="pick-inexisting-value-$(uuid)"
echo '0 profile a
0 profile b
0 profile c
0 profile d
0 profile e' > "$XDG_DATA_HOME/remembering/$PROFILE"
INPUT='a
b
c
d
e'
echo "$INPUT" | \
./src/remembering \
-p "$PROFILE" \
-- echo f \
1>"$OUT" 2>"$ERR"
STATUS=$?
assert_status 0
assert_stdout f
assert_profile "$PROFILE" '0 profile a
0 profile b
0 profile c
0 profile d
0 profile e
1 profile f'
test_ok
}
test_stdin_profile_merging() {
testing 'STDIN/profile merging'
N="$LINENO"
PROFILE="stdin-profile-merging-$(uuid)"
echo '0 profile a
0 profile b
0 profile c
0 profile z' > "$XDG_DATA_HOME/remembering/$PROFILE"
INPUT='a
b
c
d
e'
EXPECTED='a
b
c
d
e'
pick_x a "$INPUT"
assert_stderr "$EXPECTED"
test_ok
}
test_stdin_is_larger_than_profile() {
testing 'STDIN is larger than profile'
N="$LINENO"
PROFILE="stdin-is-larger-than-profile-$(uuid)"
echo '0 profile a' > "$XDG_DATA_HOME/remembering/$PROFILE"
INPUT='a
b
c
d
e'
pick_x a "$INPUT"
assert_profile "$PROFILE" "$BASE_PROFILE_A_PICKED"
test_ok
}
test_stdin_is_smaller_than_profile() {
testing 'STDIN is smaller than profile'
N="$LINENO"
PROFILE="stdin-is-smaller-than-profile-$(uuid)"
echo "$BASE_PROFILE" > "$XDG_DATA_HOME/remembering/$PROFILE"
INPUT='a'
pick_x a "$INPUT"
assert_profile "$PROFILE" "$BASE_PROFILE_A_PICKED"
test_ok
}
test_stdin_is_empty() {
testing 'STDIN is empty'
N="$LINENO"
PROFILE="stdin-is-empty-$(uuid)"
echo "$BASE_PROFILE" > "$XDG_DATA_HOME/remembering/$PROFILE"
OUT="$(mkstemp)"
ERR="$(mkstemp)"
printf '' | \
./src/remembering \
-p "$PROFILE" \
-- sh -c 'tee -a /dev/stderr | head -n1' \
1>"$OUT" 2>"$ERR"
STATUS=$?
assert_status 0
assert_stderr ''
assert_stdout ''
assert_profile "$PROFILE" "$BASE_PROFILE"
test_ok
}
test_profile_does_not_exist() {
testing 'profile does not exist'
N="$LINENO"
PROFILE="profile-does-not-exist-$(uuid)"
INPUT='a
b
c
d
e'
pick_x a "$INPUT"
assert_profile "$PROFILE" "$BASE_PROFILE_A_PICKED"
test_ok
}
test_profile_is_empty() {
testing 'profile is empty'
N="$LINENO"
PROFILE="profile-is-empty-$(uuid)"
printf '' > "$XDG_DATA_HOME/remembering/$PROFILE"
INPUT='a
b
c
d
e'
pick_x a "$INPUT"
assert_profile "$PROFILE" "$BASE_PROFILE_A_PICKED"
test_ok
}
test_names_with_spaces() {
testing 'names with spaces'
N="$LINENO"
PROFILE="names-with-spaces-$(uuid)"
INPUT='a b c
d e f'
EXPECTED='1 profile a b c
0 profile d e f'
pick_x 'a b c' "$INPUT"
assert_profile "$PROFILE" "$EXPECTED"
test_ok
}
test_really_long_list() {
testing 'really long list'
N="$LINENO"
OUT="$(mkstemp)"
ERR="$(mkstemp)"
PROFILE="really-long-list-$(uuid)"
N=999999
seq "$N" | \
./src/remembering \
-p "$PROFILE" \
-- tail -n1 \
1>"$OUT" 2>"$ERR"
STATUS=$?
assert_status 0
assert_empty_stderr
assert_stdout "$N"
test_ok
}
test_utf8_commands() {
testing 'UTF-8 commands'
N="$LINENO"
PROFILE="utf8-commands-$(uuid)"
INPUT='❤️
á
è
ŭ 😀'
EXPECTED='0 profile á
0 profile è
1 profile ŭ 😀
0 profile ❤️'
pick_x 'ŭ 😀' "$INPUT"
assert_profile "$PROFILE" "$EXPECTED"
test_ok
}
test_picking_first_makes_it_be_always_first
test_promoting_values
test_higher_values_loose_tie
test_smaller_values_win_tie
test_many_sequential_picks
test_pick_inexisting_value
test_stdin_profile_merging
test_stdin_is_larger_than_profile
test_stdin_is_smaller_than_profile
test_stdin_is_empty
test_profile_does_not_exist
test_profile_is_empty
test_names_with_spaces
test_really_long_list
test_utf8_commands