#!/usr/bin/env bash set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" CLAUDE_TMUX="$SCRIPT_DIR/scripts/claude-tmux" 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_contains() { local desc="$1" needle="$2" haystack="$3" if [[ "$haystack" == *"$needle"* ]]; then echo -e "${GREEN}PASS${NC}: $desc"; ((pass++)) else echo -e "${RED}FAIL${NC}: $desc"; echo " needle: $needle"; echo " haystack: $haystack"; ((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 } # === Hermetic environment === TEST_HOME="$(mktemp -d)" STUB_BIN="$(mktemp -d)" cleanup() { rm -rf "$TEST_HOME" "$STUB_BIN" tmux kill-session -t "=Agent Runtimes" 2>/dev/null || true } trap cleanup EXIT # Stub claude-profile on PATH so LAUNCH_CMD renders deterministically. cat > "$STUB_BIN/claude-profile" <<'EOF' #!/usr/bin/env bash exit 0 EOF chmod +x "$STUB_BIN/claude-profile" export HOME="$TEST_HOME" export PATH="$STUB_BIN:$PATH" mkdir -p "$HOME/.claude-oreillyit-anthropic" echo "deep" > "$HOME/.claude-oreillyit-anthropic/last-mode" mkdir -p "$HOME/dev/claude/projects/agent-runtimes" mkdir -p "$HOME/dev/claude/octopus" echo "=== claude-tmux tests ===" echo # --- Basic dryrun: title-case name, mode from last-mode --- out=$("$CLAUDE_TMUX" agent-runtimes --dryrun 2>&1) assert_contains "dryrun shows title-cased session name" "Session name: Agent Runtimes" "$out" assert_contains "dryrun mode from last-mode (deep)" "Mode: deep" "$out" assert_contains "dryrun resolves projects/ folder" "Project: agent-runtimes (" "$out" assert_contains "dryrun launch cmd has remote-control name" '--remote-control Agent\ Runtimes' "$out" assert_contains "dryrun launch cmd passes --project basename" "--project agent-runtimes" "$out" assert_contains "dryrun attach hint quotes the name" 'tmux attach -t "Agent Runtimes"' "$out" # --- Mode override --- out=$("$CLAUDE_TMUX" agent-runtimes --mode quick --dryrun 2>&1) assert_contains "dryrun honours --mode override" "Mode: quick" "$out" # --- Name override --- out=$("$CLAUDE_TMUX" agent-runtimes --name "Custom Name" --dryrun 2>&1) assert_contains "dryrun honours --name override" "Session name: Custom Name" "$out" # --- Top-level (non-projects) folder resolves --- out=$("$CLAUDE_TMUX" octopus --dryrun 2>&1) assert_contains "dryrun resolves top-level ~/dev/claude folder" "Session name: Octopus" "$out" # --- Unknown project errors --- out=$("$CLAUDE_TMUX" no-such-project --dryrun 2>&1); rc=$? assert_exit "unknown project exits 1" 1 "$rc" assert_contains "unknown project error mentions search locations" "Project folder not found" "$out" # --- No project, non-TTY errors --- out=$("$CLAUDE_TMUX" --dryrun &1); rc=$? assert_exit "no project (non-TTY) exits 1" 1 "$rc" assert_contains "no project error is helpful" "No project given" "$out" # --- Missing profile errors --- out=$("$CLAUDE_TMUX" agent-runtimes --profile no-such-profile --dryrun 2>&1); rc=$? assert_exit "missing profile exits 1" 1 "$rc" assert_contains "missing profile error names dir" "Profile directory not found" "$out" # --- Help --- out=$("$CLAUDE_TMUX" --help 2>&1); rc=$? assert_exit "--help exits 0" 0 "$rc" assert_contains "--help shows script name" "claude-tmux" "$out" # --- Auto-increment against a live session --- if tmux new-session -d -s "Agent Runtimes" -c /tmp 2>/dev/null; then out=$("$CLAUDE_TMUX" agent-runtimes --dryrun 2>&1) assert_contains "auto-increments to #2 when base name taken" "Session name: Agent Runtimes #2" "$out" tmux kill-session -t "=Agent Runtimes" 2>/dev/null || true else echo -e "${GREEN}SKIP${NC}: auto-increment (tmux server unavailable)" fi echo echo "=== $pass passed, $fail failed ===" [[ "$fail" -eq 0 ]]