242 lines
6.5 KiB
Bash
Executable File
242 lines
6.5 KiB
Bash
Executable File
#!/usr/bin/env zsh
|
|
# ============================================================================
|
|
# Dotfiles Test Framework
|
|
# ============================================================================
|
|
# Simple unit testing for shell functions and scripts.
|
|
#
|
|
# Usage:
|
|
# ./tests/run-tests.zsh # Run all tests
|
|
# ./tests/run-tests.zsh test_utils # Run specific test file
|
|
# ============================================================================
|
|
|
|
set -e
|
|
|
|
# ============================================================================
|
|
# Configuration
|
|
# ============================================================================
|
|
|
|
SCRIPT_DIR="${0:A:h}"
|
|
DOTFILES_DIR="${SCRIPT_DIR:h}"
|
|
TESTS_DIR="$SCRIPT_DIR"
|
|
|
|
# Colors
|
|
RED=$'\033[0;31m'
|
|
GREEN=$'\033[0;32m'
|
|
YELLOW=$'\033[1;33m'
|
|
CYAN=$'\033[0;36m'
|
|
NC=$'\033[0m'
|
|
|
|
# Counters
|
|
TESTS_RUN=0
|
|
TESTS_PASSED=0
|
|
TESTS_FAILED=0
|
|
CURRENT_TEST=""
|
|
|
|
# ============================================================================
|
|
# Test Framework Functions
|
|
# ============================================================================
|
|
|
|
# Start a test group
|
|
describe() {
|
|
echo ""
|
|
echo -e "${CYAN}▶ $1${NC}"
|
|
}
|
|
|
|
# Run a single test
|
|
it() {
|
|
CURRENT_TEST="$1"
|
|
((TESTS_RUN++))
|
|
}
|
|
|
|
# Assert equality
|
|
assert_eq() {
|
|
local actual="$1"
|
|
local expected="$2"
|
|
local message="${3:-Values should be equal}"
|
|
|
|
if [[ "$actual" == "$expected" ]]; then
|
|
echo -e " ${GREEN}✓${NC} $CURRENT_TEST"
|
|
((TESTS_PASSED++))
|
|
else
|
|
echo -e " ${RED}✗${NC} $CURRENT_TEST"
|
|
echo -e " ${RED}Expected:${NC} $expected"
|
|
echo -e " ${RED}Actual:${NC} $actual"
|
|
((TESTS_FAILED++))
|
|
fi
|
|
}
|
|
|
|
# Assert not equal
|
|
assert_ne() {
|
|
local actual="$1"
|
|
local not_expected="$2"
|
|
|
|
if [[ "$actual" != "$not_expected" ]]; then
|
|
echo -e " ${GREEN}✓${NC} $CURRENT_TEST"
|
|
((TESTS_PASSED++))
|
|
else
|
|
echo -e " ${RED}✗${NC} $CURRENT_TEST"
|
|
echo -e " ${RED}Should not equal:${NC} $not_expected"
|
|
((TESTS_FAILED++))
|
|
fi
|
|
}
|
|
|
|
# Assert command succeeds
|
|
assert_success() {
|
|
local cmd="$1"
|
|
|
|
if eval "$cmd" &>/dev/null; then
|
|
echo -e " ${GREEN}✓${NC} $CURRENT_TEST"
|
|
((TESTS_PASSED++))
|
|
else
|
|
echo -e " ${RED}✗${NC} $CURRENT_TEST"
|
|
echo -e " ${RED}Command failed:${NC} $cmd"
|
|
((TESTS_FAILED++))
|
|
fi
|
|
}
|
|
|
|
# Assert command fails
|
|
assert_fail() {
|
|
local cmd="$1"
|
|
|
|
if ! eval "$cmd" &>/dev/null; then
|
|
echo -e " ${GREEN}✓${NC} $CURRENT_TEST"
|
|
((TESTS_PASSED++))
|
|
else
|
|
echo -e " ${RED}✗${NC} $CURRENT_TEST"
|
|
echo -e " ${RED}Expected failure but succeeded:${NC} $cmd"
|
|
((TESTS_FAILED++))
|
|
fi
|
|
}
|
|
|
|
# Assert string contains
|
|
assert_contains() {
|
|
local haystack="$1"
|
|
local needle="$2"
|
|
|
|
if [[ "$haystack" == *"$needle"* ]]; then
|
|
echo -e " ${GREEN}✓${NC} $CURRENT_TEST"
|
|
((TESTS_PASSED++))
|
|
else
|
|
echo -e " ${RED}✗${NC} $CURRENT_TEST"
|
|
echo -e " ${RED}String should contain:${NC} $needle"
|
|
((TESTS_FAILED++))
|
|
fi
|
|
}
|
|
|
|
# Assert file exists
|
|
assert_file_exists() {
|
|
local file="$1"
|
|
|
|
if [[ -f "$file" ]]; then
|
|
echo -e " ${GREEN}✓${NC} $CURRENT_TEST"
|
|
((TESTS_PASSED++))
|
|
else
|
|
echo -e " ${RED}✗${NC} $CURRENT_TEST"
|
|
echo -e " ${RED}File not found:${NC} $file"
|
|
((TESTS_FAILED++))
|
|
fi
|
|
}
|
|
|
|
# Assert directory exists
|
|
assert_dir_exists() {
|
|
local dir="$1"
|
|
|
|
if [[ -d "$dir" ]]; then
|
|
echo -e " ${GREEN}✓${NC} $CURRENT_TEST"
|
|
((TESTS_PASSED++))
|
|
else
|
|
echo -e " ${RED}✗${NC} $CURRENT_TEST"
|
|
echo -e " ${RED}Directory not found:${NC} $dir"
|
|
((TESTS_FAILED++))
|
|
fi
|
|
}
|
|
|
|
# Assert command exists
|
|
assert_cmd_exists() {
|
|
local cmd="$1"
|
|
|
|
if command -v "$cmd" &>/dev/null; then
|
|
echo -e " ${GREEN}✓${NC} $CURRENT_TEST"
|
|
((TESTS_PASSED++))
|
|
else
|
|
echo -e " ${RED}✗${NC} $CURRENT_TEST"
|
|
echo -e " ${RED}Command not found:${NC} $cmd"
|
|
((TESTS_FAILED++))
|
|
fi
|
|
}
|
|
|
|
# Skip a test
|
|
skip() {
|
|
local reason="${1:-No reason given}"
|
|
echo -e " ${YELLOW}○${NC} $CURRENT_TEST (SKIPPED: $reason)"
|
|
}
|
|
|
|
# ============================================================================
|
|
# Test Runner
|
|
# ============================================================================
|
|
|
|
run_test_file() {
|
|
local test_file="$1"
|
|
source "$test_file"
|
|
}
|
|
|
|
print_summary() {
|
|
echo ""
|
|
echo "─────────────────────────────────────────"
|
|
echo -e "Tests: ${CYAN}$TESTS_RUN${NC}"
|
|
echo -e "Passed: ${GREEN}$TESTS_PASSED${NC}"
|
|
echo -e "Failed: ${RED}$TESTS_FAILED${NC}"
|
|
echo "─────────────────────────────────────────"
|
|
|
|
if (( TESTS_FAILED > 0 )); then
|
|
echo -e "${RED}FAILED${NC}"
|
|
return 1
|
|
else
|
|
echo -e "${GREEN}PASSED${NC}"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
# ============================================================================
|
|
# Main
|
|
# ============================================================================
|
|
|
|
main() {
|
|
echo "╔═══════════════════════════════════════╗"
|
|
echo "║ Dotfiles Test Suite ║"
|
|
echo "╚═══════════════════════════════════════╝"
|
|
|
|
# Source the libraries we're testing
|
|
source "$DOTFILES_DIR/zsh/lib/bootstrap.zsh" 2>/dev/null || true
|
|
|
|
local specific_test="$1"
|
|
|
|
if [[ -n "$specific_test" ]]; then
|
|
# Run specific test file
|
|
if [[ -f "$TESTS_DIR/${specific_test}.zsh" ]]; then
|
|
run_test_file "$TESTS_DIR/${specific_test}.zsh"
|
|
elif [[ -f "$TESTS_DIR/test_${specific_test}.zsh" ]]; then
|
|
run_test_file "$TESTS_DIR/test_${specific_test}.zsh"
|
|
else
|
|
echo "Test file not found: $specific_test"
|
|
exit 1
|
|
fi
|
|
else
|
|
# Run all test files
|
|
for test_file in "$TESTS_DIR"/test_*.zsh(N); do
|
|
[[ -f "$test_file" ]] || continue
|
|
echo ""
|
|
echo -e "${YELLOW}Running: $(basename "$test_file")${NC}"
|
|
run_test_file "$test_file"
|
|
done
|
|
fi
|
|
|
|
print_summary
|
|
}
|
|
|
|
# Export functions for test files
|
|
export -f describe it assert_eq assert_ne assert_success assert_fail
|
|
export -f assert_contains assert_file_exists assert_dir_exists assert_cmd_exists skip
|
|
|
|
main "$@"
|