#!/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="$(mktemp)" ERR="$(mktemp)" PROFILE="really-long-list-$(uuid)" seq 999999 | \ ./src/remembering \ -p "$PROFILE" \ -- head -n1 \ 1>"$OUT" 2>"$ERR" STATUS=$? assert_status 0 assert_empty_stderr assert_stdout '1' 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