Skip to content

Commit 356331b

Browse files
authored
Merge pull request #21 from ooloth/feature/error-handling-tests
Add comprehensive error handling tests for bash utilities
2 parents eac5615 + 376083e commit 356331b

File tree

2 files changed

+180
-3
lines changed

2 files changed

+180
-3
lines changed

.claude/tasks/2025-07-07-bash-migration.md

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
# Bash Migration Epic
22

3-
## Current Status (July 7, 2025)
3+
## Current Status (July 11, 2025)
44

55
**Task**: Migrate dotfiles installation infrastructure from custom zsh to industry-standard bash + shellcheck + bats
66
**Approach**: Enhanced 3-phase migration with setup.bash at the center for maximum tooling leverage
7-
**Current**: Phase 1 enhanced scope - migrating setup.bash + core scripts + shared utilities
7+
**Current**: Phase 1 nearing completion - core utilities and 4 installation scripts migrated, setup.bash pending
88

99
## Migration Strategy
1010

1111
### Phase 1: Setup + Core Infrastructure Migration (IN PROGRESS - Enhanced Scope)
1212
**Goal**: Migrate setup.bash + core installation scripts + shared utilities for maximum tooling leverage
1313

14-
#### ✅ PR #13: GitHub Installation Testing (MERGED)
14+
#### Completed PRs
15+
16+
##### ✅ PR #13: GitHub Installation Testing (MERGED)
1517
- **Files Created**:
1618
- `lib/github-utils.bash` - GitHub SSH utilities (shellcheck clean)
1719
- `bin/install/github.bash` - Bash replacement for github.zsh
@@ -22,6 +24,46 @@
2224
- **Benefits Demonstrated**: Better error catching, industry-standard tooling, cleaner syntax
2325
- **Status**: MERGED - established complete migration pattern with 20 passing tests
2426

27+
##### ✅ PR #15: SSH Installation Testing (MERGED)
28+
- **Files Created**:
29+
- `lib/ssh-utils.bash` - SSH utilities with comprehensive functionality
30+
- `bin/install/ssh.bash` - Bash replacement for ssh.zsh
31+
- `test/install/test-ssh-utils.bats` - 14 utility function tests
32+
- `test/install/test-ssh-installation.bats` - 7 integration tests
33+
- **Test Results**: All 21 tests passing, shellcheck compliance verified
34+
- **Improvements**: Better macOS version detection for ssh-add keychain flag
35+
- **Status**: MERGED - SSH installation fully migrated to bash
36+
37+
##### ✅ PR #17: Homebrew Utilities Migration (MERGED)
38+
- **Files Created**:
39+
- `lib/homebrew-utils.bash` - Homebrew shared utilities
40+
- `bin/install/homebrew.bash` - Bash replacement for homebrew.zsh
41+
- `test/install/test-homebrew-utils.bats` - Comprehensive utility tests
42+
- **Status**: MERGED - Homebrew installation fully migrated with shared utilities
43+
44+
##### ✅ PR #18: Core Utility Libraries Migration (MERGED)
45+
- **Files Migrated**:
46+
- `bin/lib/machine-detection.bash` - Dynamic hostname-based machine detection
47+
- `bin/lib/prerequisite-validation.bash` - System prerequisites validation
48+
- Test files for all core utilities
49+
- **Status**: MERGED - Core utilities successfully migrated to bash
50+
51+
##### ✅ PR #19: Dry-run and Error Handling Utilities (MERGED)
52+
- **Files Created**:
53+
- `bin/lib/dry-run-utils.bash` - Complete dry-run functionality
54+
- `bin/lib/error-handling.bash` - Error handling and retry mechanisms
55+
- `test/setup/test-dry-run-utils-bash.bats` - 20 tests for dry-run utilities
56+
- **Test Results**: 20/20 tests passing, zero shellcheck warnings
57+
- **Status**: MERGED - Dry-run and error handling utilities in bash
58+
- **Note**: Error handling tests still needed
59+
60+
##### ✅ PR #20: Symlink Utilities Extraction (MERGED)
61+
- **Files Created**:
62+
- `lib/symlink-utils.bash` - Symlink management utilities
63+
- `bin/install/symlinks.bash` - Bash replacement for symlinks installation
64+
- `test/setup/test-symlink-utils-bash.bats` - Comprehensive symlink tests
65+
- **Status**: MERGED - Symlink functionality fully migrated to bash
66+
2567
### Phase 2: Remaining Script Migration (Pending)
2668
**Goal**: Migrate remaining installation scripts using established three-tier architecture
2769

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env bats
2+
3+
# Test error handling utilities (bash implementation)
4+
5+
# Load the error handling utilities
6+
load "../../bin/lib/error-handling.bash"
7+
8+
# Test capture_error with no command provided
9+
@test "capture_error returns error when no command provided" {
10+
run capture_error
11+
[ "$status" -eq 1 ]
12+
[[ "$output" =~ "Error: No command provided to capture_error" ]]
13+
}
14+
15+
# Test capture_error with successful command
16+
@test "capture_error executes successful command and returns 0" {
17+
run capture_error "echo 'Hello World'"
18+
[ "$status" -eq 0 ]
19+
[[ "$output" == "Hello World" ]]
20+
}
21+
22+
# Test capture_error with failing command
23+
@test "capture_error handles failing command and provides context" {
24+
run capture_error "exit 42" "Test operation"
25+
[ "$status" -eq 42 ]
26+
[[ "$output" =~ "Error: Test operation failed (exit code: 42)" ]]
27+
[[ "$output" =~ "Command: exit 42" ]]
28+
}
29+
30+
# Test capture_error preserves command output before showing error
31+
@test "capture_error shows command output before error message" {
32+
run capture_error "echo 'Output before failure' && exit 1" "Command with output"
33+
[ "$status" -eq 1 ]
34+
[[ "${lines[0]}" == "Output before failure" ]]
35+
[[ "$output" =~ "Error: Command with output failed" ]]
36+
}
37+
38+
# Test retry_with_backoff with no command provided
39+
@test "retry_with_backoff returns error when no command provided" {
40+
run retry_with_backoff
41+
[ "$status" -eq 1 ]
42+
[[ "$output" =~ "Error: No command provided to retry_with_backoff" ]]
43+
}
44+
45+
# Test retry_with_backoff with successful command on first try
46+
@test "retry_with_backoff succeeds on first attempt" {
47+
run retry_with_backoff "exit 0"
48+
[ "$status" -eq 0 ]
49+
}
50+
51+
# Test retry_with_backoff exhausts all attempts and fails
52+
@test "retry_with_backoff fails after exhausting max attempts" {
53+
run retry_with_backoff "exit 1" 2 0
54+
[ "$status" -eq 1 ]
55+
}
56+
57+
# Test handle_error with no command provided
58+
@test "handle_error returns error when no command provided" {
59+
run handle_error
60+
[ "$status" -eq 1 ]
61+
[[ "$output" =~ "Error: No command provided to handle_error" ]]
62+
}
63+
64+
# Test handle_error displays error message and generic suggestion
65+
@test "handle_error displays error message and generic suggestion" {
66+
run handle_error "test-command" "999" "Custom error message"
67+
[ "$status" -eq 1 ]
68+
[[ "$output" =~ "❌ Error occurred while running: test-command" ]]
69+
[[ "$output" =~ "Error: Custom error message" ]]
70+
[[ "$output" =~ "💡 Suggestion: Check the command syntax and try again" ]]
71+
}
72+
73+
# Test handle_error provides permission-specific suggestion
74+
@test "handle_error provides permission-specific suggestion for EACCES" {
75+
run handle_error "test-command" "EACCES" "Permission denied"
76+
[ "$status" -eq 1 ]
77+
[[ "$output" =~ "❌ Error occurred while running: test-command" ]]
78+
[[ "$output" =~ "Error: Permission denied" ]]
79+
[[ "$output" =~ "💡 Suggestion: Try running with sudo or check file permissions" ]]
80+
}
81+
82+
# Test handle_error provides file-not-found suggestion
83+
@test "handle_error provides file-not-found suggestion for ENOENT" {
84+
run handle_error "test-command" "ENOENT" "No such file or directory"
85+
[ "$status" -eq 1 ]
86+
[[ "$output" =~ "❌ Error occurred while running: test-command" ]]
87+
[[ "$output" =~ "Error: No such file or directory" ]]
88+
[[ "$output" =~ "💡 Suggestion: Check if the file or directory exists" ]]
89+
}
90+
91+
# Test handle_error provides network-specific suggestion
92+
@test "handle_error provides network-specific suggestion for ECONNREFUSED" {
93+
run handle_error "test-command" "ECONNREFUSED" "Connection refused"
94+
[ "$status" -eq 1 ]
95+
[[ "$output" =~ "❌ Error occurred while running: test-command" ]]
96+
[[ "$output" =~ "Error: Connection refused" ]]
97+
[[ "$output" =~ "💡 Suggestion: Check your internet connection or try again later" ]]
98+
}
99+
100+
# Test handle_error provides disk-space suggestion
101+
@test "handle_error provides disk-space suggestion for ENOSPC" {
102+
run handle_error "test-command" "ENOSPC" "No space left on device"
103+
[ "$status" -eq 1 ]
104+
[[ "$output" =~ "❌ Error occurred while running: test-command" ]]
105+
[[ "$output" =~ "Error: No space left on device" ]]
106+
[[ "$output" =~ "💡 Suggestion: Free up disk space and try again" ]]
107+
}
108+
109+
# Test retry_with_backoff succeeds on second attempt
110+
@test "retry_with_backoff succeeds on second attempt after one failure" {
111+
# Create a file that tracks attempts
112+
local attempt_file=$(mktemp)
113+
echo "0" > "$attempt_file"
114+
115+
# Command that fails first time, succeeds second time
116+
local test_command="
117+
current=\$(cat '$attempt_file')
118+
next=\$((current + 1))
119+
echo \$next > '$attempt_file'
120+
[ \$next -eq 2 ]
121+
"
122+
123+
run retry_with_backoff "$test_command" 3 0
124+
[ "$status" -eq 0 ]
125+
126+
# Clean up
127+
rm -f "$attempt_file"
128+
}
129+
130+
# Test capture_error with default context
131+
@test "capture_error uses default context when none provided" {
132+
run capture_error "exit 1"
133+
[ "$status" -eq 1 ]
134+
[[ "$output" =~ "Error: Command execution failed" ]]
135+
}

0 commit comments

Comments
 (0)