Big bang
This commit is contained in:
190
tests/test_prompt.sh
Executable file
190
tests/test_prompt.sh
Executable file
@@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env bash
|
||||
# Unit tests for prompt helper functions in lib/prompt.sh.
|
||||
#
|
||||
# All interactive functions write prompts to stderr and read from stdin.
|
||||
# Tests pipe input via stdin and capture stdout, suppressing stderr.
|
||||
|
||||
TESTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(dirname "$TESTS_DIR")"
|
||||
|
||||
source "$TESTS_DIR/framework.sh"
|
||||
source "$ROOT_DIR/lib/colors.sh"
|
||||
source "$ROOT_DIR/lib/validate.sh"
|
||||
source "$ROOT_DIR/lib/prompt.sh"
|
||||
|
||||
# Helpers: feed stdin to a function and capture its stdout
|
||||
feed() {
|
||||
# feed <input_string> <function> [args...]
|
||||
local input="$1"; shift
|
||||
printf "%s" "$input" | "$@" 2>/dev/null
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_enum: numeric selection"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "a" "$(feed "1"$'\n' _prompt_enum "V" "a,b,c" "a")" "choice 1 -> first option"
|
||||
assert_eq "b" "$(feed "2"$'\n' _prompt_enum "V" "a,b,c" "a")" "choice 2 -> second option"
|
||||
assert_eq "c" "$(feed "3"$'\n' _prompt_enum "V" "a,b,c" "a")" "choice 3 -> third option"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_enum: string selection"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "a" "$(feed "a"$'\n' _prompt_enum "V" "a,b,c" "")" "string 'a' selects a"
|
||||
assert_eq "b" "$(feed "b"$'\n' _prompt_enum "V" "a,b,c" "")" "string 'b' selects b"
|
||||
assert_eq "c" "$(feed "c"$'\n' _prompt_enum "V" "a,b,c" "")" "string 'c' selects c"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_enum: empty input uses default"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "a" "$(feed $'\n' _prompt_enum "V" "a,b,c" "a")" "empty -> first default"
|
||||
assert_eq "b" "$(feed $'\n' _prompt_enum "V" "a,b,c" "b")" "empty -> middle default"
|
||||
assert_eq "c" "$(feed $'\n' _prompt_enum "V" "a,b,c" "c")" "empty -> last default"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_enum: invalid choice then valid"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Send out-of-range number, then a valid number
|
||||
assert_eq "b" "$(printf "99\n2\n" | _prompt_enum "V" "a,b,c" "a" 2>/dev/null)" \
|
||||
"invalid index followed by valid index"
|
||||
|
||||
# Send unknown string, then valid string
|
||||
assert_eq "c" "$(printf "zzz\nc\n" | _prompt_enum "V" "a,b,c" "a" 2>/dev/null)" \
|
||||
"invalid string followed by valid string"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_enum: real-world APP_ENV"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "development" \
|
||||
"$(feed $'\n' _prompt_enum "APP_ENV" "development,staging,production" "development")" \
|
||||
"empty -> development (default)"
|
||||
|
||||
assert_eq "production" \
|
||||
"$(feed "3"$'\n' _prompt_enum "APP_ENV" "development,staging,production" "development")" \
|
||||
"choice 3 -> production"
|
||||
|
||||
assert_eq "staging" \
|
||||
"$(feed "staging"$'\n' _prompt_enum "APP_ENV" "development,staging,production" "development")" \
|
||||
"string 'staging' -> staging"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_bool: explicit inputs"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "true" "$(feed "y"$'\n' _prompt_bool "")" "y -> true"
|
||||
assert_eq "true" "$(feed "yes"$'\n' _prompt_bool "")" "yes -> true"
|
||||
assert_eq "true" "$(feed "true"$'\n' _prompt_bool "")" "true -> true"
|
||||
assert_eq "true" "$(feed "1"$'\n' _prompt_bool "")" "1 -> true"
|
||||
assert_eq "false" "$(feed "n"$'\n' _prompt_bool "")" "n -> false"
|
||||
assert_eq "false" "$(feed "no"$'\n' _prompt_bool "")" "no -> false"
|
||||
assert_eq "false" "$(feed "false"$'\n' _prompt_bool "")" "false -> false"
|
||||
assert_eq "false" "$(feed "0"$'\n' _prompt_bool "")" "0 -> false"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_bool: empty input uses default"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "true" "$(feed $'\n' _prompt_bool "true")" "empty -> true default"
|
||||
assert_eq "true" "$(feed $'\n' _prompt_bool "yes")" "empty -> yes default normalizes to true"
|
||||
assert_eq "false" "$(feed $'\n' _prompt_bool "false")" "empty -> false default"
|
||||
assert_eq "false" "$(feed $'\n' _prompt_bool "no")" "empty -> no default normalizes to false"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_bool: invalid then valid"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "true" "$(printf "banana\ny\n" | _prompt_bool "" 2>/dev/null)" \
|
||||
"invalid input followed by y"
|
||||
assert_eq "false" "$(printf "maybe\nn\n" | _prompt_bool "" 2>/dev/null)" \
|
||||
"invalid input followed by n"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_secret: matching values accepted"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "mysecret" \
|
||||
"$(printf "mysecret\nmysecret\n" | _prompt_secret "V" "" 2>/dev/null)" \
|
||||
"matching entries return value"
|
||||
|
||||
assert_eq "p@ss!#\$word" \
|
||||
"$(printf 'p@ss!#$word\np@ss!#$word\n' | _prompt_secret "V" "" 2>/dev/null)" \
|
||||
"special characters in secret preserved"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_secret: empty input uses default"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
assert_eq "defaultsecret" \
|
||||
"$(printf "\n" | _prompt_secret "V" "defaultsecret" 2>/dev/null)" \
|
||||
"empty input returns default"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "_prompt_secret: mismatch retries"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# First pair mismatches, second pair matches
|
||||
assert_eq "correct" \
|
||||
"$(printf "wrong\nmismatch\ncorrect\ncorrect\n" | _prompt_secret "V" "" 2>/dev/null)" \
|
||||
"mismatch retries until match"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "prompt_variable: string type stores value"
|
||||
# ---------------------------------------------------------------------------
|
||||
# Use process substitution (<(...)) so prompt_variable runs in the current
|
||||
# shell and its variable assignments (ENV_VALUE_*) persist.
|
||||
|
||||
ENV_VARS=("MYVAR")
|
||||
ENV_DESC_MYVAR="A test variable"
|
||||
ENV_TYPE_MYVAR="string"
|
||||
ENV_REQUIRED_MYVAR="false"
|
||||
ENV_DEFAULT_MYVAR="default_val"
|
||||
|
||||
# Accept default
|
||||
prompt_variable "MYVAR" < <(printf "\n") 2>/dev/null
|
||||
assert_eq "default_val" "$ENV_VALUE_MYVAR" "empty input stores default"
|
||||
|
||||
# Provide a value
|
||||
prompt_variable "MYVAR" < <(printf "custom\n") 2>/dev/null
|
||||
assert_eq "custom" "$ENV_VALUE_MYVAR" "typed value stored"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "prompt_variable: number type re-prompts on invalid input"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
ENV_TYPE_MYVAR="number"
|
||||
ENV_DEFAULT_MYVAR="42"
|
||||
|
||||
prompt_variable "MYVAR" < <(printf "abc\n99\n") 2>/dev/null
|
||||
assert_eq "99" "$ENV_VALUE_MYVAR" "invalid number re-prompts, then stores valid"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "prompt_variable: bool type"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
ENV_TYPE_MYVAR="bool"
|
||||
ENV_DEFAULT_MYVAR="false"
|
||||
|
||||
prompt_variable "MYVAR" < <(printf "y\n") 2>/dev/null
|
||||
assert_eq "true" "$ENV_VALUE_MYVAR" "bool y stored as true"
|
||||
|
||||
prompt_variable "MYVAR" < <(printf "\n") 2>/dev/null
|
||||
assert_eq "false" "$ENV_VALUE_MYVAR" "bool empty uses false default"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
suite "prompt_variable: enum type"
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
ENV_TYPE_MYVAR="enum:x,y,z"
|
||||
ENV_DEFAULT_MYVAR="x"
|
||||
|
||||
prompt_variable "MYVAR" < <(printf "2\n") 2>/dev/null
|
||||
assert_eq "y" "$ENV_VALUE_MYVAR" "enum choice 2 stores y"
|
||||
|
||||
prompt_variable "MYVAR" < <(printf "\n") 2>/dev/null
|
||||
assert_eq "x" "$ENV_VALUE_MYVAR" "enum empty uses default x"
|
||||
|
||||
print_summary
|
||||
Reference in New Issue
Block a user