* fix: progress detection improvements (#141, #144) - Fix checkbox regex to exclude date entries like [2026-01-29] (#144) - Add git commit detection: files changed in commits now count as progress (#141) - Add 13 regression tests for progress detection and checkbox regex - Update test count from 452 to 465 Fixes #141, Fixes #144 * fix(test): increase grep context to capture echo -1 line * fix: count both committed and working tree changes as progress When commits are made, now unions: - Files changed in commits (loop_start_sha..current_sha) - Unstaged changes (git diff HEAD) - Staged changes (git diff --cached) Uses sort -u to deduplicate before counting. --------- Co-authored-by: Test User <test@example.com>
This commit is contained in:
parent
3366ac64d8
commit
aa753c9158
7 changed files with 474 additions and 28 deletions
|
|
@ -432,7 +432,7 @@ Ralph uses advanced error detection with two-stage filtering to eliminate false
|
|||
| `test_cli_modern.bats` | 29 | Modern CLI commands (Phase 1.1) + build_claude_command fix |
|
||||
| `test_json_parsing.bats` | 45 | JSON output format parsing + Claude CLI format + session management + array format |
|
||||
| `test_session_continuity.bats` | 28 | Session lifecycle management + circuit breaker integration + issue #91 fix |
|
||||
| `test_exit_detection.bats` | 35 | Exit signal detection + EXIT_SIGNAL-based completion indicators |
|
||||
| `test_exit_detection.bats` | 53 | Exit signal detection + EXIT_SIGNAL-based completion indicators + progress detection |
|
||||
| `test_rate_limiting.bats` | 15 | Rate limiting behavior |
|
||||
| `test_loop_execution.bats` | 20 | Integration tests |
|
||||
| `test_edge_cases.bats` | 20 | Edge case handling |
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -3,7 +3,7 @@
|
|||
[](https://github.com/frankbria/ralph-claude-code/actions/workflows/test.yml)
|
||||
[](LICENSE)
|
||||

|
||||

|
||||

|
||||
[](https://github.com/frankbria/ralph-claude-code/issues)
|
||||
[](https://github.com/hesreallyhim/awesome-claude-code)
|
||||
[](https://x.com/FrankBria18044)
|
||||
|
|
@ -18,7 +18,7 @@ Ralph is an implementation of the Geoffrey Huntley's technique for Claude Code t
|
|||
|
||||
**Version**: v0.11.4 - Active Development
|
||||
**Core Features**: Working and tested
|
||||
**Test Coverage**: 452 tests, 100% pass rate
|
||||
**Test Coverage**: 465 tests, 100% pass rate
|
||||
|
||||
### What's Working Now
|
||||
- Autonomous development loops with intelligent exit detection
|
||||
|
|
@ -43,6 +43,8 @@ Ralph is an implementation of the Geoffrey Huntley's technique for Claude Code t
|
|||
### Recent Improvements
|
||||
|
||||
**v0.11.4 - Bug Fixes & Compatibility** (latest)
|
||||
- Fixed progress detection: Git commits within a loop now count as progress (#141)
|
||||
- Fixed checkbox regex: Date entries `[2026-01-29]` no longer counted as checkboxes (#144)
|
||||
- Fixed session hijacking: Use `--resume <session_id>` instead of `--continue` (#151)
|
||||
- Fixed EXIT_SIGNAL override: `STATUS: COMPLETE` with `EXIT_SIGNAL: false` now continues working (#146)
|
||||
- Fixed ralph-import hanging indefinitely (added `--print` flag for non-interactive mode)
|
||||
|
|
@ -50,6 +52,7 @@ Ralph is an implementation of the Geoffrey Huntley's technique for Claude Code t
|
|||
- Fixed cross-platform date commands for macOS with Homebrew coreutils
|
||||
- Added configurable circuit breaker thresholds via environment variables (#99)
|
||||
- Added tmux support for non-zero `base-index` configurations
|
||||
- Added 13 new regression tests for progress detection and checkbox regex
|
||||
|
||||
**v0.11.3 - Live Streaming & Beads Fix**
|
||||
- Added live streaming output mode with `--live` flag for real-time Claude Code visibility (#125)
|
||||
|
|
@ -608,7 +611,7 @@ If you want to run the test suite:
|
|||
# Install BATS testing framework
|
||||
npm install -g bats bats-support bats-assert
|
||||
|
||||
# Run all tests (452 tests)
|
||||
# Run all tests (465 tests)
|
||||
npm test
|
||||
|
||||
# Run specific test suites
|
||||
|
|
@ -633,7 +636,7 @@ bats tests/integration/test_installation.bats
|
|||
```
|
||||
|
||||
Current test status:
|
||||
- **452 tests** across 15 test files
|
||||
- **465 tests** across 15 test files
|
||||
- **100% pass rate** (452/452 passing)
|
||||
- Comprehensive unit and integration tests
|
||||
- Specialized tests for JSON parsing, CLI flags, circuit breaker, EXIT_SIGNAL behavior, enable wizard, and installation workflows
|
||||
|
|
@ -740,7 +743,7 @@ cd ralph-claude-code
|
|||
|
||||
# Install dependencies and run tests
|
||||
npm install
|
||||
npm test # All 452 tests must pass
|
||||
npm test # All 465 tests must pass
|
||||
```
|
||||
|
||||
### Priority Contribution Areas
|
||||
|
|
|
|||
|
|
@ -204,11 +204,13 @@ should_exit_gracefully() {
|
|||
fi
|
||||
|
||||
# 4. Check fix_plan.md for completion
|
||||
# Bug #3 Fix: Support indented markdown checkboxes with [[:space:]]* pattern
|
||||
# Fix #144: Only match valid markdown checkboxes, not date entries like [2026-01-29]
|
||||
# Valid patterns: "- [ ]" (uncompleted) and "- [x]" or "- [X]" (completed)
|
||||
if [[ -f "$RALPH_DIR/fix_plan.md" ]]; then
|
||||
local total_items=$(grep -cE "^[[:space:]]*- \[" "$RALPH_DIR/fix_plan.md" 2>/dev/null || echo "0")
|
||||
local completed_items=$(grep -cE "^[[:space:]]*- \[x\]" "$RALPH_DIR/fix_plan.md" 2>/dev/null || echo "0")
|
||||
|
||||
local uncompleted_items=$(grep -cE "^[[:space:]]*- \[ \]" "$RALPH_DIR/fix_plan.md" 2>/dev/null || echo "0")
|
||||
local completed_items=$(grep -cE "^[[:space:]]*- \[[xX]\]" "$RALPH_DIR/fix_plan.md" 2>/dev/null || echo "0")
|
||||
local total_items=$((uncompleted_items + completed_items))
|
||||
|
||||
if [[ $total_items -gt 0 ]] && [[ $completed_items -eq $total_items ]]; then
|
||||
log_status "WARN" "Exit condition: All fix_plan.md items completed ($completed_items/$total_items)"
|
||||
echo "plan_complete"
|
||||
|
|
|
|||
|
|
@ -358,8 +358,37 @@ analyze_response() {
|
|||
fi
|
||||
|
||||
# Check for file changes via git (supplements JSON data)
|
||||
# Fix #141: Detect both uncommitted changes AND committed changes
|
||||
if command -v git &>/dev/null && git rev-parse --git-dir >/dev/null 2>&1; then
|
||||
local git_files=$(git diff --name-only 2>/dev/null | wc -l)
|
||||
local git_files=0
|
||||
local loop_start_sha=""
|
||||
local current_sha=""
|
||||
|
||||
if [[ -f "$RALPH_DIR/.loop_start_sha" ]]; then
|
||||
loop_start_sha=$(cat "$RALPH_DIR/.loop_start_sha" 2>/dev/null || echo "")
|
||||
fi
|
||||
current_sha=$(git rev-parse HEAD 2>/dev/null || echo "")
|
||||
|
||||
# Check if commits were made (HEAD changed)
|
||||
if [[ -n "$loop_start_sha" && -n "$current_sha" && "$loop_start_sha" != "$current_sha" ]]; then
|
||||
# Commits were made - count union of committed files AND working tree changes
|
||||
git_files=$(
|
||||
{
|
||||
git diff --name-only "$loop_start_sha" "$current_sha" 2>/dev/null
|
||||
git diff --name-only HEAD 2>/dev/null # unstaged changes
|
||||
git diff --name-only --cached 2>/dev/null # staged changes
|
||||
} | sort -u | wc -l
|
||||
)
|
||||
else
|
||||
# No commits - check for uncommitted changes (staged + unstaged)
|
||||
git_files=$(
|
||||
{
|
||||
git diff --name-only 2>/dev/null # unstaged changes
|
||||
git diff --name-only --cached 2>/dev/null # staged changes
|
||||
} | sort -u | wc -l
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ $git_files -gt 0 ]]; then
|
||||
has_progress=true
|
||||
files_modified=$git_files
|
||||
|
|
@ -500,8 +529,36 @@ analyze_response() {
|
|||
done
|
||||
|
||||
# 6. Check for file changes (git integration)
|
||||
# Fix #141: Detect both uncommitted changes AND committed changes
|
||||
if command -v git &>/dev/null && git rev-parse --git-dir >/dev/null 2>&1; then
|
||||
files_modified=$(git diff --name-only 2>/dev/null | wc -l)
|
||||
local loop_start_sha=""
|
||||
local current_sha=""
|
||||
|
||||
if [[ -f "$RALPH_DIR/.loop_start_sha" ]]; then
|
||||
loop_start_sha=$(cat "$RALPH_DIR/.loop_start_sha" 2>/dev/null || echo "")
|
||||
fi
|
||||
current_sha=$(git rev-parse HEAD 2>/dev/null || echo "")
|
||||
|
||||
# Check if commits were made (HEAD changed)
|
||||
if [[ -n "$loop_start_sha" && -n "$current_sha" && "$loop_start_sha" != "$current_sha" ]]; then
|
||||
# Commits were made - count union of committed files AND working tree changes
|
||||
files_modified=$(
|
||||
{
|
||||
git diff --name-only "$loop_start_sha" "$current_sha" 2>/dev/null
|
||||
git diff --name-only HEAD 2>/dev/null # unstaged changes
|
||||
git diff --name-only --cached 2>/dev/null # staged changes
|
||||
} | sort -u | wc -l
|
||||
)
|
||||
else
|
||||
# No commits - check for uncommitted changes (staged + unstaged)
|
||||
files_modified=$(
|
||||
{
|
||||
git diff --name-only 2>/dev/null # unstaged changes
|
||||
git diff --name-only --cached 2>/dev/null # staged changes
|
||||
} | sort -u | wc -l
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ $files_modified -gt 0 ]]; then
|
||||
has_progress=true
|
||||
((confidence_score+=20))
|
||||
|
|
|
|||
|
|
@ -492,15 +492,12 @@ should_exit_gracefully() {
|
|||
fi
|
||||
|
||||
# 5. Check fix_plan.md for completion
|
||||
# Bug #3 Fix: Support indented markdown checkboxes with [[:space:]]* pattern
|
||||
# Fix #144: Only match valid markdown checkboxes, not date entries like [2026-01-29]
|
||||
# Valid patterns: "- [ ]" (uncompleted) and "- [x]" or "- [X]" (completed)
|
||||
if [[ -f "$RALPH_DIR/fix_plan.md" ]]; then
|
||||
local total_items=$(grep -cE "^[[:space:]]*- \[" "$RALPH_DIR/fix_plan.md" 2>/dev/null)
|
||||
local completed_items=$(grep -cE "^[[:space:]]*- \[x\]" "$RALPH_DIR/fix_plan.md" 2>/dev/null)
|
||||
|
||||
# Handle case where grep returns no matches (exit code 1)
|
||||
[[ -z "$total_items" ]] && total_items=0
|
||||
[[ -z "$completed_items" ]] && completed_items=0
|
||||
|
||||
local uncompleted_items=$(grep -cE "^[[:space:]]*- \[ \]" "$RALPH_DIR/fix_plan.md" 2>/dev/null || echo "0")
|
||||
local completed_items=$(grep -cE "^[[:space:]]*- \[[xX]\]" "$RALPH_DIR/fix_plan.md" 2>/dev/null || echo "0")
|
||||
local total_items=$((uncompleted_items + completed_items))
|
||||
|
||||
if [[ $total_items -gt 0 ]] && [[ $completed_items -eq $total_items ]]; then
|
||||
log_status "WARN" "Exit condition: All fix_plan.md items completed ($completed_items/$total_items)" >&2
|
||||
|
|
@ -1013,6 +1010,14 @@ execute_claude_code() {
|
|||
local calls_made=$(cat "$CALL_COUNT_FILE" 2>/dev/null || echo "0")
|
||||
calls_made=$((calls_made + 1))
|
||||
|
||||
# Fix #141: Capture git HEAD SHA at loop start to detect commits as progress
|
||||
# Store in file for access by progress detection after Claude execution
|
||||
local loop_start_sha=""
|
||||
if command -v git &>/dev/null && git rev-parse --git-dir &>/dev/null 2>&1; then
|
||||
loop_start_sha=$(git rev-parse HEAD 2>/dev/null || echo "")
|
||||
fi
|
||||
echo "$loop_start_sha" > "$RALPH_DIR/.loop_start_sha"
|
||||
|
||||
log_status "LOOP" "Executing Claude Code (Call $calls_made/$MAX_CALLS_PER_HOUR)"
|
||||
local timeout_seconds=$((CLAUDE_TIMEOUT_MINUTES * 60))
|
||||
log_status "INFO" "⏳ Starting Claude Code execution... (timeout: ${CLAUDE_TIMEOUT_MINUTES}m)"
|
||||
|
|
@ -1279,7 +1284,41 @@ EOF
|
|||
log_analysis_summary
|
||||
|
||||
# Get file change count for circuit breaker
|
||||
local files_changed=$(git diff --name-only 2>/dev/null | wc -l || echo 0)
|
||||
# Fix #141: Detect both uncommitted changes AND committed changes
|
||||
local files_changed=0
|
||||
local loop_start_sha=""
|
||||
local current_sha=""
|
||||
|
||||
if [[ -f "$RALPH_DIR/.loop_start_sha" ]]; then
|
||||
loop_start_sha=$(cat "$RALPH_DIR/.loop_start_sha" 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
if command -v git &>/dev/null && git rev-parse --git-dir &>/dev/null 2>&1; then
|
||||
current_sha=$(git rev-parse HEAD 2>/dev/null || echo "")
|
||||
|
||||
# Check if commits were made (HEAD changed)
|
||||
if [[ -n "$loop_start_sha" && -n "$current_sha" && "$loop_start_sha" != "$current_sha" ]]; then
|
||||
# Commits were made - count union of committed files AND working tree changes
|
||||
# This catches cases where Claude commits some files but still has other modified files
|
||||
files_changed=$(
|
||||
{
|
||||
git diff --name-only "$loop_start_sha" "$current_sha" 2>/dev/null
|
||||
git diff --name-only HEAD 2>/dev/null # unstaged changes
|
||||
git diff --name-only --cached 2>/dev/null # staged changes
|
||||
} | sort -u | wc -l
|
||||
)
|
||||
[[ "$VERBOSE_PROGRESS" == "true" ]] && log_status "DEBUG" "Detected $files_changed unique files changed (commits + working tree) since loop start"
|
||||
else
|
||||
# No commits - check for uncommitted changes (staged + unstaged)
|
||||
files_changed=$(
|
||||
{
|
||||
git diff --name-only 2>/dev/null # unstaged changes
|
||||
git diff --name-only --cached 2>/dev/null # staged changes
|
||||
} | sort -u | wc -l
|
||||
)
|
||||
fi
|
||||
fi
|
||||
|
||||
local has_errors="false"
|
||||
|
||||
# Two-stage error detection to avoid JSON field false positives
|
||||
|
|
|
|||
|
|
@ -75,13 +75,15 @@ should_exit_gracefully() {
|
|||
fi
|
||||
|
||||
# 4. Check fix_plan.md for completion
|
||||
# Fix #144: Only match valid markdown checkboxes, not date entries like [2026-01-29]
|
||||
if [[ -f "$RALPH_DIR/fix_plan.md" ]]; then
|
||||
local total_items=$(grep -c "^- \[" "$RALPH_DIR/fix_plan.md" 2>/dev/null)
|
||||
local completed_items=$(grep -c "^- \[x\]" "$RALPH_DIR/fix_plan.md" 2>/dev/null)
|
||||
|
||||
# Handle case where grep returns no matches (exit code 1)
|
||||
[[ -z "$total_items" ]] && total_items=0
|
||||
[[ -z "$completed_items" ]] && completed_items=0
|
||||
local uncompleted_items
|
||||
local completed_items
|
||||
uncompleted_items=$(grep -cE "^[[:space:]]*- \[ \]" "$RALPH_DIR/fix_plan.md" 2>/dev/null || echo "0")
|
||||
uncompleted_items=$(echo "$uncompleted_items" | tr -d '[:space:]')
|
||||
completed_items=$(grep -cE "^[[:space:]]*- \[[xX]\]" "$RALPH_DIR/fix_plan.md" 2>/dev/null || echo "0")
|
||||
completed_items=$(echo "$completed_items" | tr -d '[:space:]')
|
||||
local total_items=$((uncompleted_items + completed_items))
|
||||
|
||||
if [[ $total_items -gt 0 ]] && [[ $completed_items -eq $total_items ]]; then
|
||||
echo "plan_complete"
|
||||
|
|
@ -878,3 +880,346 @@ EOF
|
|||
result=$(should_exit_gracefully_with_denials || true)
|
||||
assert_equal "$result" ""
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# CHECKBOX REGEX FIX TESTS (Issue #144)
|
||||
# =============================================================================
|
||||
# These tests verify that date entries like [2026-01-29] are NOT counted as
|
||||
# checkboxes, preventing false "plan_complete" exits when fix_plan.md contains
|
||||
# dated entries that match the old [*] pattern.
|
||||
|
||||
# Test 41: Date entries should NOT be counted as checkboxes
|
||||
@test "fix_plan.md date entries are not counted as checkboxes" {
|
||||
cat > "$RALPH_DIR/fix_plan.md" << 'EOF'
|
||||
# Fix Plan
|
||||
|
||||
## Changelog
|
||||
- [2026-01-29] Initial version
|
||||
- [2026-01-30] Added feature X
|
||||
- [2026-01-31] Bug fixes
|
||||
|
||||
## Tasks
|
||||
- [ ] Task 1 pending
|
||||
- [ ] Task 2 pending
|
||||
EOF
|
||||
|
||||
result=$(should_exit_gracefully || true)
|
||||
# Should NOT exit - there are 2 uncompleted tasks
|
||||
assert_equal "$result" ""
|
||||
}
|
||||
|
||||
# Test 42: Date entries mixed with completed tasks should not cause false exit
|
||||
@test "fix_plan.md with dates and completed tasks counts correctly" {
|
||||
cat > "$RALPH_DIR/fix_plan.md" << 'EOF'
|
||||
# Fix Plan
|
||||
|
||||
## Changelog
|
||||
- [2026-01-29] Initial version
|
||||
|
||||
## Tasks
|
||||
- [x] Task 1 complete
|
||||
- [ ] Task 2 pending
|
||||
EOF
|
||||
|
||||
result=$(should_exit_gracefully || true)
|
||||
# 1 completed, 1 pending - should NOT exit
|
||||
assert_equal "$result" ""
|
||||
}
|
||||
|
||||
# Test 43: Non-checkbox bracket patterns (NOTE, TODO, FIXME) should be excluded
|
||||
@test "fix_plan.md bracket patterns like [NOTE] are not checkboxes" {
|
||||
cat > "$RALPH_DIR/fix_plan.md" << 'EOF'
|
||||
# Fix Plan
|
||||
|
||||
## Notes
|
||||
- [NOTE] Remember to update docs
|
||||
- [TODO] Consider refactoring later
|
||||
- [FIXME] Known issue with edge case
|
||||
- [WIP] Work in progress
|
||||
|
||||
## Tasks
|
||||
- [ ] Task 1 pending
|
||||
EOF
|
||||
|
||||
result=$(should_exit_gracefully || true)
|
||||
# Only 1 real task (pending) - should NOT exit
|
||||
assert_equal "$result" ""
|
||||
}
|
||||
|
||||
# Test 44: Case-insensitive completed checkboxes ([x] and [X])
|
||||
@test "fix_plan.md counts both [x] and [X] as completed" {
|
||||
cat > "$RALPH_DIR/fix_plan.md" << 'EOF'
|
||||
# Fix Plan
|
||||
- [x] Task 1 with lowercase x
|
||||
- [X] Task 2 with uppercase X
|
||||
- [x] Task 3 with lowercase x
|
||||
EOF
|
||||
|
||||
result=$(should_exit_gracefully)
|
||||
# All 3 tasks completed - should exit with plan_complete
|
||||
assert_equal "$result" "plan_complete"
|
||||
}
|
||||
|
||||
# Test 45: Indented date entries should not be counted
|
||||
@test "fix_plan.md indented date entries are not checkboxes" {
|
||||
cat > "$RALPH_DIR/fix_plan.md" << 'EOF'
|
||||
# Fix Plan
|
||||
|
||||
## Releases
|
||||
- [2026-01-29] v1.0.0 released
|
||||
- [2026-01-30] v1.0.1 patch
|
||||
|
||||
## Tasks
|
||||
- [x] All done
|
||||
EOF
|
||||
|
||||
result=$(should_exit_gracefully)
|
||||
# Only 1 real task (completed) - should exit
|
||||
assert_equal "$result" "plan_complete"
|
||||
}
|
||||
|
||||
# Test 46: Empty checkbox [ ] with spaces should be counted as uncompleted
|
||||
@test "fix_plan.md empty checkboxes with extra spaces" {
|
||||
cat > "$RALPH_DIR/fix_plan.md" << 'EOF'
|
||||
# Fix Plan
|
||||
- [ ] Task with single space (valid)
|
||||
- [ ] Task with double space (invalid format, not counted)
|
||||
- [x] Completed task
|
||||
EOF
|
||||
|
||||
result=$(should_exit_gracefully || true)
|
||||
# 1 uncompleted, 1 completed - should NOT exit
|
||||
assert_equal "$result" ""
|
||||
}
|
||||
|
||||
# Test 47: Version numbers in brackets should not be counted
|
||||
@test "fix_plan.md version numbers like [v1.0] are not checkboxes" {
|
||||
cat > "$RALPH_DIR/fix_plan.md" << 'EOF'
|
||||
# Fix Plan
|
||||
|
||||
## Version History
|
||||
- [v1.0] Initial release
|
||||
- [v1.1] Added features
|
||||
- [v2.0] Major update
|
||||
|
||||
## Tasks
|
||||
- [x] Task complete
|
||||
EOF
|
||||
|
||||
result=$(should_exit_gracefully)
|
||||
# Only 1 real task (completed) - should exit
|
||||
assert_equal "$result" "plan_complete"
|
||||
}
|
||||
|
||||
# Test 48: Issue/PR references should not be counted
|
||||
@test "fix_plan.md issue references like [#123] are not checkboxes" {
|
||||
cat > "$RALPH_DIR/fix_plan.md" << 'EOF'
|
||||
# Fix Plan
|
||||
|
||||
## Related Issues
|
||||
- [#141] Progress detection bug
|
||||
- [#144] Checkbox regex false positives
|
||||
- [PR#155] Setup improvements
|
||||
|
||||
## Tasks
|
||||
- [ ] Fix issue #141
|
||||
- [ ] Fix issue #144
|
||||
EOF
|
||||
|
||||
result=$(should_exit_gracefully || true)
|
||||
# 2 uncompleted tasks - should NOT exit
|
||||
assert_equal "$result" ""
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# GIT COMMIT DETECTION TESTS (Issue #141)
|
||||
# =============================================================================
|
||||
# These tests verify that when Claude commits within a loop, the committed files
|
||||
# are counted as progress even though there are no uncommitted changes.
|
||||
|
||||
# Helper function to detect progress including git commits
|
||||
detect_progress_with_commits() {
|
||||
local loop_start_sha="$1"
|
||||
local current_sha="$2"
|
||||
local files_changed=0
|
||||
|
||||
# Check for committed changes since loop start
|
||||
if [[ -n "$loop_start_sha" && -n "$current_sha" && "$loop_start_sha" != "$current_sha" ]]; then
|
||||
# Files changed in commits between loop start and current HEAD
|
||||
files_changed=$(git diff --name-only "$loop_start_sha" "$current_sha" 2>/dev/null | wc -l || echo 0)
|
||||
files_changed=$(echo "$files_changed" | tr -d ' ')
|
||||
else
|
||||
# Fall back to uncommitted changes
|
||||
files_changed=$(git diff --name-only 2>/dev/null | wc -l || echo 0)
|
||||
files_changed=$(echo "$files_changed" | tr -d ' ')
|
||||
fi
|
||||
|
||||
echo "$files_changed"
|
||||
}
|
||||
|
||||
# Test 49: Git commit detection - files changed in commit count as progress
|
||||
@test "git commit detection counts committed files as progress" {
|
||||
# Skip if git is not available
|
||||
if ! command -v git &>/dev/null; then
|
||||
skip "git not available"
|
||||
fi
|
||||
|
||||
# Initialize a git repo
|
||||
git init --quiet
|
||||
git config user.email "test@test.com"
|
||||
git config user.name "Test"
|
||||
|
||||
# Create initial commit
|
||||
echo "initial" > file1.txt
|
||||
git add file1.txt
|
||||
git commit --quiet -m "Initial commit"
|
||||
|
||||
local loop_start_sha=$(git rev-parse HEAD)
|
||||
|
||||
# Simulate Claude making changes and committing within the loop
|
||||
echo "modified" > file1.txt
|
||||
echo "new file" > file2.txt
|
||||
git add file1.txt file2.txt
|
||||
git commit --quiet -m "Claude's work"
|
||||
|
||||
local current_sha=$(git rev-parse HEAD)
|
||||
|
||||
# Detect progress
|
||||
local files_changed=$(detect_progress_with_commits "$loop_start_sha" "$current_sha")
|
||||
|
||||
# Should detect 2 files changed
|
||||
[ "$files_changed" -eq 2 ]
|
||||
}
|
||||
|
||||
# Test 50: Git commit detection - no progress when SHA unchanged
|
||||
@test "git commit detection returns 0 when no commits made" {
|
||||
# Skip if git is not available
|
||||
if ! command -v git &>/dev/null; then
|
||||
skip "git not available"
|
||||
fi
|
||||
|
||||
# Initialize a git repo
|
||||
git init --quiet
|
||||
git config user.email "test@test.com"
|
||||
git config user.name "Test"
|
||||
|
||||
# Create initial commit
|
||||
echo "initial" > file1.txt
|
||||
git add file1.txt
|
||||
git commit --quiet -m "Initial commit"
|
||||
|
||||
local loop_start_sha=$(git rev-parse HEAD)
|
||||
local current_sha=$(git rev-parse HEAD)
|
||||
|
||||
# No uncommitted changes either
|
||||
local files_changed=$(detect_progress_with_commits "$loop_start_sha" "$current_sha")
|
||||
|
||||
# Should detect 0 files (no commits, no uncommitted changes)
|
||||
[ "$files_changed" -eq 0 ]
|
||||
}
|
||||
|
||||
# Test 51: Git commit detection - falls back to uncommitted when no commit
|
||||
@test "git commit detection falls back to uncommitted changes" {
|
||||
# Skip if git is not available
|
||||
if ! command -v git &>/dev/null; then
|
||||
skip "git not available"
|
||||
fi
|
||||
|
||||
# Initialize a git repo
|
||||
git init --quiet
|
||||
git config user.email "test@test.com"
|
||||
git config user.name "Test"
|
||||
|
||||
# Create initial commit with two tracked files
|
||||
echo "initial1" > file1.txt
|
||||
echo "initial2" > file2.txt
|
||||
git add file1.txt file2.txt
|
||||
git commit --quiet -m "Initial commit"
|
||||
|
||||
local loop_start_sha=$(git rev-parse HEAD)
|
||||
|
||||
# Make uncommitted changes to tracked files (no commit)
|
||||
echo "modified1" > file1.txt
|
||||
echo "modified2" > file2.txt
|
||||
|
||||
local current_sha=$(git rev-parse HEAD) # Same as loop_start_sha
|
||||
|
||||
# Detect progress - should fall back to uncommitted changes
|
||||
# Note: git diff only shows modified tracked files, not untracked files
|
||||
local files_changed=$(detect_progress_with_commits "$loop_start_sha" "$current_sha")
|
||||
|
||||
# Should detect 2 uncommitted modified files
|
||||
[ "$files_changed" -eq 2 ]
|
||||
}
|
||||
|
||||
# Test 52: Git commit detection - multiple commits within loop
|
||||
@test "git commit detection counts files across multiple commits" {
|
||||
# Skip if git is not available
|
||||
if ! command -v git &>/dev/null; then
|
||||
skip "git not available"
|
||||
fi
|
||||
|
||||
# Initialize a git repo
|
||||
git init --quiet
|
||||
git config user.email "test@test.com"
|
||||
git config user.name "Test"
|
||||
|
||||
# Create initial commit
|
||||
echo "initial" > file1.txt
|
||||
git add file1.txt
|
||||
git commit --quiet -m "Initial commit"
|
||||
|
||||
local loop_start_sha=$(git rev-parse HEAD)
|
||||
|
||||
# First commit within loop
|
||||
echo "change1" > file1.txt
|
||||
git add file1.txt
|
||||
git commit --quiet -m "First change"
|
||||
|
||||
# Second commit within loop
|
||||
echo "new" > file2.txt
|
||||
git add file2.txt
|
||||
git commit --quiet -m "Second change"
|
||||
|
||||
# Third commit within loop
|
||||
echo "another" > file3.txt
|
||||
git add file3.txt
|
||||
git commit --quiet -m "Third change"
|
||||
|
||||
local current_sha=$(git rev-parse HEAD)
|
||||
|
||||
# Detect progress
|
||||
local files_changed=$(detect_progress_with_commits "$loop_start_sha" "$current_sha")
|
||||
|
||||
# Should detect 3 files (one per commit)
|
||||
[ "$files_changed" -eq 3 ]
|
||||
}
|
||||
|
||||
# Test 53: Git commit detection handles empty loop_start_sha
|
||||
@test "git commit detection handles missing loop_start_sha" {
|
||||
# Skip if git is not available
|
||||
if ! command -v git &>/dev/null; then
|
||||
skip "git not available"
|
||||
fi
|
||||
|
||||
# Initialize a git repo
|
||||
git init --quiet
|
||||
git config user.email "test@test.com"
|
||||
git config user.name "Test"
|
||||
|
||||
# Create initial commit
|
||||
echo "initial" > file1.txt
|
||||
git add file1.txt
|
||||
git commit --quiet -m "Initial commit"
|
||||
|
||||
# Make uncommitted changes
|
||||
echo "modified" > file1.txt
|
||||
|
||||
local current_sha=$(git rev-parse HEAD)
|
||||
|
||||
# Detect progress with empty loop_start_sha
|
||||
local files_changed=$(detect_progress_with_commits "" "$current_sha")
|
||||
|
||||
# Should fall back to uncommitted changes (1 file)
|
||||
[ "$files_changed" -eq 1 ]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ EOF
|
|||
echo "test" > "$test_file"
|
||||
|
||||
# Verify the function code handles stat failure by checking the implementation
|
||||
run grep -A25 'get_session_file_age_hours' "${BATS_TEST_DIRNAME}/../../ralph_loop.sh"
|
||||
run grep -A35 'get_session_file_age_hours' "${BATS_TEST_DIRNAME}/../../ralph_loop.sh"
|
||||
[[ "$output" == *'echo "-1"'* ]]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue