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
16 changes: 13 additions & 3 deletions tests/claude-code/test-helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ run_claude() {
cmd+=(--allowed-tools="$allowed_tools")
fi

# Run Claude in headless mode with timeout
if timeout "$timeout" "${cmd[@]}" > "$output_file" 2>&1; then
# Run Claude in headless mode with timeout.
# stdin is redirected from /dev/null: the prompt is passed as an argument,
# so these calls never want piped input. Without this, an inherited
# non-TTY stdin that never closes (CI, or the suite run under a harness)
# makes `claude -p` wait on it and the whole script hits its timeout
# instead of reporting assertion results.
if timeout "$timeout" "${cmd[@]}" < /dev/null > "$output_file" 2>&1; then
cat "$output_file"
rm -f "$output_file"
return 0
Expand All @@ -32,12 +37,17 @@ run_claude() {
# Usage: assert_contains "output" "pattern" "test name"
# Matching is case-insensitive: patterns are prose keywords, and models
# freely capitalize skill terms ("Do Not Trust", "Spec Compliance").
# Newlines are flattened before matching: patterns link two keywords with
# `.*` ("implementer.*fix"), but grep is line-based, so an answer that puts
# those keywords in different paragraphs failed despite being correct. Only
# assert_contains flattens, and flattening can only turn a FAIL into a PASS,
# so no currently-passing assertion changes meaning.
assert_contains() {
local output="$1"
local pattern="$2"
local test_name="${3:-test}"

if echo "$output" | grep -qi "$pattern"; then
if echo "$output" | tr '\n' ' ' | grep -qi "$pattern"; then
echo " [PASS] $test_name"
return 0
else
Expand Down
6 changes: 3 additions & 3 deletions tests/claude-code/test-subagent-driven-development.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# No drill coverage: this test asks the agent to *describe* SDD (string-
# matches its verbal explanation against expected keywords like
# "self-review", "skeptical", "worktree", "Step 1", "loop"). Drill scenarios
# "self-review", "skeptical", "worktree", "Setup", "loop"). Drill scenarios
# test behavior (real subagent dispatch, plan-following, review loops),
# not description-recall. Kept by design.
set -euo pipefail
Expand Down Expand Up @@ -83,7 +83,7 @@ else
exit 1
fi

if assert_contains "$output" "Step 1\|beginning\|start\|Load Plan" "Read at beginning"; then
if assert_contains "$output" "Setup\|Step 1\|beginning\|start\|Load Plan" "Read at beginning"; then
: # pass
else
exit 1
Expand Down Expand Up @@ -136,7 +136,7 @@ output=$(run_claude "In subagent-driven-development, how does the controller pro
Controller provides: <directly or by file>
Implementer must read plan file: <yes or no>" "$CLAUDE_PROMPT_TIMEOUT")

if assert_contains "$output" "provide.*directly\|full.*text\|paste\|include.*prompt" "Provides text directly"; then
if assert_contains "$output" "Controller provides:.\{0,24\}file\|brief file\|brief path" "Provides the task via a brief file"; then
: # pass
else
exit 1
Expand Down