Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions tests/helpers/setup.bash
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ add_ts_commit() {
git -C "$REPO" commit -m "add $file" >/dev/null 2>&1
}

add_java_commit() {
local file="${1:-App.java}"
mkdir -p "$REPO/$(dirname "$file")"
echo "public class App { public static void main(String[] args) {} }" > "$REPO/$file"
git -C "$REPO" add -A >/dev/null 2>&1
local ts
ts=$(future_timestamp)
GIT_COMMITTER_DATE="@$ts" GIT_AUTHOR_DATE="@$ts" \
git -C "$REPO" commit -m "add $file" >/dev/null 2>&1
}

add_irrelevant_commit() {
local file="${1:-data.txt}"
echo "some data" > "$REPO/$file"
Expand Down Expand Up @@ -173,6 +184,45 @@ EOF
git -C "$REPO" commit -m "add package.json" --allow-empty >/dev/null 2>&1
}

# Create codeflash.toml (Java). configured=true adds [tool.codeflash].
create_codeflash_toml() {
local configured="${1:-true}"
if [ "$configured" = "true" ]; then
cat > "$REPO/codeflash.toml" << 'EOF'
[tool.codeflash]
module-root = "src/main/java"
tests-root = "src/test/java"
EOF
else
cat > "$REPO/codeflash.toml" << 'EOF'
# empty config
EOF
fi
git -C "$REPO" add -A >/dev/null 2>&1
git -C "$REPO" commit -m "add codeflash.toml" --allow-empty >/dev/null 2>&1
}

# Create a mock codeflash binary in MOCK_BIN (for Java tests without venv).
# Usage: setup_mock_codeflash [installed=true]
setup_mock_codeflash() {
local installed="${1:-true}"
mkdir -p "$MOCK_BIN"

if [ "$installed" = "true" ]; then
cat > "$MOCK_BIN/codeflash" << 'MOCK'
#!/bin/bash
echo "codeflash 0.1.0"
exit 0
MOCK
else
cat > "$MOCK_BIN/codeflash" << 'MOCK'
#!/bin/bash
exit 127
MOCK
fi
chmod +x "$MOCK_BIN/codeflash"
}

# Create .claude/settings.json with Bash(*codeflash*) auto-allowed
create_auto_allow() {
mkdir -p "$REPO/.claude"
Expand Down
114 changes: 114 additions & 0 deletions tests/test_suggest_optimize.bats
Original file line number Diff line number Diff line change
Expand Up @@ -462,4 +462,118 @@ setup() {
run run_hook false "PATH=$MOCK_BIN:$PATH"
assert_block
assert_reason_contains "npx codeflash --subagent"
}

# ═══════════════════════════════════════════════════════════════════════════════
# Java projects
# ═══════════════════════════════════════════════════════════════════════════════

# Setup: codeflash.toml with [tool.codeflash]. Mock codeflash binary in PATH.
# One .java file committed after session start.
# Validates: The Java "happy path" — codeflash.toml is configured, codeflash
# binary is available in PATH. The hook instructs Claude to run
# `codeflash --subagent` in the background.
# Expected: Block with reason containing "codeflash --subagent" and
# "run_in_background".
@test "java: configured + codeflash installed → run codeflash" {
add_java_commit
create_codeflash_toml true
setup_mock_codeflash true

run run_hook false "PATH=$MOCK_BIN:$PATH" "CODEFLASH_API_KEY=cf-test-key"
assert_block
assert_reason_contains "codeflash --subagent"
assert_reason_contains "run_in_background"
}

# Setup: codeflash.toml with [tool.codeflash]. No codeflash binary in PATH.
# One .java commit.
# Validates: When codeflash is configured but the binary is not installed,
# the hook should prompt to install it with pip.
# Expected: Block with reason containing "pip install codeflash".
@test "java: configured + NOT installed → install prompt" {
add_java_commit
create_codeflash_toml true

# Use PATH without codeflash: MOCK_BIN (empty) + system dirs, but not dirs containing codeflash
run run_hook false "PATH=$MOCK_BIN:/usr/bin:/bin" "CODEFLASH_API_KEY=cf-test-key"
assert_block
assert_reason_contains "pip install codeflash"
}

# Setup: codeflash.toml exists but has NO [tool.codeflash] section.
# Mock codeflash binary is available. One .java commit.
# Validates: When codeflash is installed but not configured, the hook should
# prompt to run `codeflash init --yes` for auto-configuration.
# Expected: Block with reason containing "codeflash init --yes".
@test "java: NOT configured + installed → setup prompt" {
add_java_commit
create_codeflash_toml false
setup_mock_codeflash true

run run_hook false "PATH=$MOCK_BIN:$PATH" "CODEFLASH_API_KEY=cf-test-key"
assert_block
assert_reason_contains "init --yes"
}

# Setup: codeflash.toml exists but has NO [tool.codeflash] section.
# No codeflash binary in PATH. One .java commit.
# Validates: When neither configured nor installed, the hook should prompt
# to install first then configure.
# Expected: Block with reason containing "pip install codeflash".
@test "java: NOT configured + NOT installed → install prompt" {
add_java_commit
create_codeflash_toml false

# Use PATH without codeflash: MOCK_BIN (empty) + system dirs, but not dirs containing codeflash
run run_hook false "PATH=$MOCK_BIN:/usr/bin:/bin" "CODEFLASH_API_KEY=cf-test-key"
assert_block
assert_reason_contains "pip install codeflash"
}

# Setup: codeflash.toml with [tool.codeflash]. Mock codeflash in PATH.
# No .claude/settings.json exists. One .java commit.
# Validates: Java path also appends auto-allow instructions when settings.json
# is missing.
# Expected: Block with reason containing "permissions.allow".
@test "java: includes auto-allow instructions when settings.json missing" {
add_java_commit
create_codeflash_toml true
setup_mock_codeflash true

run run_hook false "PATH=$MOCK_BIN:$PATH" "CODEFLASH_API_KEY=cf-test-key"
assert_block
assert_reason_contains "permissions.allow"
}

# Setup: codeflash.toml configured. Mock codeflash in PATH.
# .claude/settings.json already has Bash(*codeflash*). One .java commit.
# Validates: Java path omits auto-allow when already configured.
# Expected: Block with reason NOT containing "permissions.allow".
@test "java: omits auto-allow when already configured" {
add_java_commit
create_codeflash_toml true
setup_mock_codeflash true
create_auto_allow

run run_hook false "PATH=$MOCK_BIN:$PATH" "CODEFLASH_API_KEY=cf-test-key"
assert_block
assert_reason_not_contains "permissions.allow"
}

# Setup: codeflash.toml with [tool.codeflash] exists alongside pyproject.toml.
# One .java commit. Mock codeflash in PATH.
# Validates: codeflash.toml takes precedence over pyproject.toml in project
# detection, ensuring Java projects are correctly identified.
# Expected: Block with "Java files" in reason (not "Python files").
@test "java: codeflash.toml takes precedence over pyproject.toml" {
add_java_commit
create_codeflash_toml true
create_pyproject true
setup_mock_codeflash true

run run_hook false "PATH=$MOCK_BIN:$PATH" "CODEFLASH_API_KEY=cf-test-key"
assert_block
assert_reason_contains "Java files"
assert_reason_not_contains "Python files"
}
Loading