Outputs cryptographically random strings using only characters safe for unquoted use in bash, YAML, and JSON: [A-Za-z0-9._+\-:@^~] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
121 lines
2.8 KiB
Bash
Executable File
121 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -uo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
GEN_SECRET="$SCRIPT_DIR/scripts/gen-secret"
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
NC='\033[0m'
|
|
|
|
pass=0
|
|
fail=0
|
|
|
|
assert_eq() {
|
|
local desc="$1" expected="$2" actual="$3"
|
|
if [[ "$expected" == "$actual" ]]; then
|
|
echo -e "${GREEN}PASS${NC}: $desc"
|
|
((pass++))
|
|
else
|
|
echo -e "${RED}FAIL${NC}: $desc"
|
|
echo " expected: $expected"
|
|
echo " actual: $actual"
|
|
((fail++))
|
|
fi
|
|
}
|
|
|
|
assert_match() {
|
|
local desc="$1" pattern="$2" actual="$3"
|
|
if [[ "$actual" =~ $pattern ]]; then
|
|
echo -e "${GREEN}PASS${NC}: $desc"
|
|
((pass++))
|
|
else
|
|
echo -e "${RED}FAIL${NC}: $desc"
|
|
echo " pattern: $pattern"
|
|
echo " actual: $actual"
|
|
((fail++))
|
|
fi
|
|
}
|
|
|
|
assert_exit() {
|
|
local desc="$1" expected="$2" actual="$3"
|
|
if [[ "$expected" -eq "$actual" ]]; then
|
|
echo -e "${GREEN}PASS${NC}: $desc"
|
|
((pass++))
|
|
else
|
|
echo -e "${RED}FAIL${NC}: $desc"
|
|
echo " expected exit: $expected"
|
|
echo " actual exit: $actual"
|
|
((fail++))
|
|
fi
|
|
}
|
|
|
|
echo "=== gen-secret tests ==="
|
|
echo
|
|
|
|
# --- Dryrun tests ---
|
|
|
|
out=$("$GEN_SECRET" --dryrun 2>&1)
|
|
assert_eq "dryrun default length" \
|
|
'[dryrun] Would generate a 32-character secret from charset: [A-Za-z0-9._+\-:@^~]' \
|
|
"$out"
|
|
|
|
out=$("$GEN_SECRET" -n 16 2>&1)
|
|
assert_eq "dryrun custom length" \
|
|
'[dryrun] Would generate a 16-character secret from charset: [A-Za-z0-9._+\-:@^~]' \
|
|
"$out"
|
|
|
|
# --- Help ---
|
|
|
|
out=$("$GEN_SECRET" --help 2>&1)
|
|
rc=$?
|
|
assert_exit "help exits 0" 0 "$rc"
|
|
assert_match "help mentions LENGTH" "LENGTH" "$out"
|
|
|
|
# --- Default generation ---
|
|
|
|
out=$("$GEN_SECRET" 2>&1)
|
|
rc=$?
|
|
assert_exit "default exits 0" 0 "$rc"
|
|
assert_eq "default length is 32" 32 "${#out}"
|
|
assert_match "default uses safe charset" '^[A-Za-z0-9._+:@^~-]+$' "$out"
|
|
|
|
# --- Custom length ---
|
|
|
|
out=$("$GEN_SECRET" 64 2>&1)
|
|
assert_eq "custom length 64" 64 "${#out}"
|
|
|
|
out=$("$GEN_SECRET" 1 2>&1)
|
|
assert_eq "minimum length 1" 1 "${#out}"
|
|
|
|
# --- Error cases ---
|
|
|
|
out=$("$GEN_SECRET" 0 2>&1)
|
|
rc=$?
|
|
assert_exit "length 0 exits 1" 1 "$rc"
|
|
assert_match "length 0 error message" "positive integer" "$out"
|
|
|
|
out=$("$GEN_SECRET" -5 2>&1)
|
|
rc=$?
|
|
assert_exit "negative length exits 1" 1 "$rc"
|
|
|
|
out=$("$GEN_SECRET" abc 2>&1)
|
|
rc=$?
|
|
assert_exit "non-numeric exits 1" 1 "$rc"
|
|
assert_match "non-numeric error message" "positive integer" "$out"
|
|
|
|
out=$("$GEN_SECRET" 10 20 2>&1)
|
|
rc=$?
|
|
assert_exit "too many args exits 1" 1 "$rc"
|
|
assert_match "too many args error message" "Too many arguments" "$out"
|
|
|
|
# --- Summary ---
|
|
|
|
echo
|
|
total=$((pass + fail))
|
|
echo -e "Results: ${GREEN}${pass}${NC}/${total} passed"
|
|
if [[ $fail -gt 0 ]]; then
|
|
echo -e "${RED}${fail} test(s) failed${NC}"
|
|
exit 1
|
|
fi
|