132 lines
6.1 KiB
Bash
Executable File
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
|