Files
interactive-env/tests/test_validate.sh
2026-03-10 00:14:14 -05:00

132 lines
6.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Unit tests for lib/validate.sh
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"
# Shorthand wrappers to reduce repetition
ok() { assert_success "$1" validate_value "VAR" "$2" "$3" "$4"; }
bad() { assert_failure "$1" validate_value "VAR" "$2" "$3" "$4"; }
# ---------------------------------------------------------------------------
suite "validate: required field"
# ---------------------------------------------------------------------------
bad "empty value is invalid when required" "" "string" "true"
ok "non-empty value is valid when required" "x" "string" "true"
ok "empty value is valid when optional" "" "string" "false"
# ---------------------------------------------------------------------------
suite "validate: number"
# ---------------------------------------------------------------------------
ok "positive integer" "42" "number" "false"
ok "zero" "0" "number" "false"
ok "negative integer" "-7" "number" "false"
ok "decimal" "3.14" "number" "false"
ok "negative decimal" "-0.5" "number" "false"
bad "plain string" "abc" "number" "false"
bad "mixed alphanumeric" "42abc" "number" "false"
bad "leading decimal" ".5" "number" "false"
bad "multiple dots" "1.2.3" "number" "false"
ok "empty optional number" "" "number" "false"
bad "empty required number" "" "number" "true"
# ---------------------------------------------------------------------------
suite "validate: bool"
# ---------------------------------------------------------------------------
ok "true" "true" "bool" "false"
ok "false" "false" "bool" "false"
ok "yes" "yes" "bool" "false"
ok "no" "no" "bool" "false"
ok "1" "1" "bool" "false"
ok "0" "0" "bool" "false"
ok "y" "y" "bool" "false"
ok "n" "n" "bool" "false"
ok "TRUE (uppercase)" "TRUE" "bool" "false"
ok "FALSE (uppercase)" "FALSE" "bool" "false"
bad "banana" "banana" "bool" "false"
bad "yes-no" "yes-no" "bool" "false"
ok "empty optional bool" "" "bool" "false"
bad "empty required bool" "" "bool" "true"
# ---------------------------------------------------------------------------
suite "validate: url"
# ---------------------------------------------------------------------------
# URL validation only warns — it always returns 0
ok "http URL passes" "http://example.com" "url" "false"
ok "https URL passes" "https://example.com" "url" "false"
ok "non-URL still passes (warn only)" "not-a-url" "url" "false"
ok "empty optional url" "" "url" "false"
bad "empty required url" "" "url" "true"
# ---------------------------------------------------------------------------
suite "validate: email"
# ---------------------------------------------------------------------------
ok "simple email" "user@example.com" "email" "false"
ok "subdomain email" "user@mail.example.com" "email" "false"
ok "plus addressing" "user+tag@example.com" "email" "false"
bad "missing @" "userexample.com" "email" "false"
bad "missing domain" "user@" "email" "false"
bad "missing TLD" "user@example" "email" "false"
bad "spaces in email" "user @example.com" "email" "false"
ok "empty optional email" "" "email" "false"
bad "empty required email" "" "email" "true"
# ---------------------------------------------------------------------------
suite "validate: enum"
# ---------------------------------------------------------------------------
ok "first option" "a" "enum:a,b,c" "false"
ok "middle option" "b" "enum:a,b,c" "false"
ok "last option" "c" "enum:a,b,c" "false"
bad "not in list" "d" "enum:a,b,c" "false"
bad "partial match" "ab" "enum:a,b,c" "false"
bad "case mismatch" "A" "enum:a,b,c" "false"
ok "single-option enum" "only" "enum:only" "false"
bad "not the single option" "other" "enum:only" "false"
ok "empty optional enum" "" "enum:a,b,c" "false"
bad "empty required enum" "" "enum:a,b,c" "true"
# Enum with real-world values
ok "development" "development" "enum:development,staging,production" "true"
ok "staging" "staging" "enum:development,staging,production" "true"
ok "production" "production" "enum:development,staging,production" "true"
bad "test env" "test" "enum:development,staging,production" "true"
# ---------------------------------------------------------------------------
suite "validate: string and secret (no structural validation)"
# ---------------------------------------------------------------------------
ok "any string value" "anything goes" "string" "false"
ok "string with specials" "f@o=bar!#$%" "string" "false"
ok "any secret value" "s3cr3t!@#" "secret" "false"
ok "empty optional string" "" "string" "false"
bad "empty required string" "" "string" "true"
# ---------------------------------------------------------------------------
suite "normalize_bool"
# ---------------------------------------------------------------------------
assert_eq "true" "$(normalize_bool "true")" "true -> true"
assert_eq "true" "$(normalize_bool "yes")" "yes -> true"
assert_eq "true" "$(normalize_bool "1")" "1 -> true"
assert_eq "true" "$(normalize_bool "y")" "y -> true"
assert_eq "true" "$(normalize_bool "TRUE")" "TRUE -> true (case insensitive)"
assert_eq "true" "$(normalize_bool "YES")" "YES -> true (case insensitive)"
assert_eq "false" "$(normalize_bool "false")" "false -> false"
assert_eq "false" "$(normalize_bool "no")" "no -> false"
assert_eq "false" "$(normalize_bool "0")" "0 -> false"
assert_eq "false" "$(normalize_bool "n")" "n -> false"
assert_eq "false" "$(normalize_bool "FALSE")" "FALSE -> false (case insensitive)"
assert_eq "banana" "$(normalize_bool "banana")" "unknown value passes through"
print_summary