Files
claude-archeflow-plugin/tests/archeflow-event.bats
Christian Nennemann 6a49c21bbe test: add bats test suite for lib/ helper scripts
110 tests across 10 test files covering all lib/ scripts:
- archeflow-event.sh: JSONL format, seq numbering, parent fields, validation
- archeflow-memory.sh: add/list/decay/forget/inject/extract commands
- archeflow-git.sh: branch creation, commit format, merge strategies, safety
- archeflow-report.sh: markdown output, summary mode, in-progress handling
- archeflow-progress.sh: progress.md generation, JSON mode, error handling
- archeflow-score.sh: archetype scoring, effectiveness report, validation
- archeflow-dag.sh: DAG rendering, color flags, tree structure
- archeflow-rollback.sh: arg parsing, phase validation, mutual exclusivity
- archeflow-init.sh: template listing, clone from project, arg validation
- archeflow-review.sh: diff modes, stats, branch/commit range review

Includes test_helper.bash (shared setup/teardown with temp git repos)
and scripts/run-tests.sh runner.
2026-04-06 21:20:05 +02:00

128 lines
4.4 KiB
Bash

# Tests for archeflow-event.sh — structured JSONL event logging.
#
# Validates: JSONL output format, sequence numbering, parent field handling,
# input validation, file/directory creation.
setup() {
load test_helper
_common_setup
}
teardown() {
_common_teardown
}
@test "event: exits 1 with usage when called with fewer than 4 args" {
run "$LIB_DIR/archeflow-event.sh" run1 type1 plan
[ "$status" -eq 1 ]
[[ "$output" == *"Usage"* ]]
}
@test "event: creates events directory and file on first call" {
run "$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{"task":"test"}'
[ "$status" -eq 0 ]
[ -d ".archeflow/events" ]
[ -f ".archeflow/events/test-run.jsonl" ]
}
@test "event: first event has seq=1" {
run "$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{"task":"test"}'
[ "$status" -eq 0 ]
local seq
seq=$(head -1 ".archeflow/events/test-run.jsonl" | jq -r '.seq')
[ "$seq" -eq 1 ]
}
@test "event: second event has seq=2" {
"$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{"task":"test"}' 2>/dev/null
"$LIB_DIR/archeflow-event.sh" test-run agent.complete plan creator '{"dur":100}' "1" 2>/dev/null
local count
count=$(wc -l < ".archeflow/events/test-run.jsonl")
[ "$count" -eq 2 ]
local seq2
seq2=$(tail -1 ".archeflow/events/test-run.jsonl" | jq -r '.seq')
[ "$seq2" -eq 2 ]
}
@test "event: output is valid JSONL" {
"$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{"task":"hello"}' 2>/dev/null
# jq will fail if the line is not valid JSON
jq empty ".archeflow/events/test-run.jsonl"
}
@test "event: fields are correctly populated" {
"$LIB_DIR/archeflow-event.sh" test-run agent.complete do maker '{"tokens":500}' 2>/dev/null
local event
event=$(head -1 ".archeflow/events/test-run.jsonl")
[ "$(echo "$event" | jq -r '.run_id')" = "test-run" ]
[ "$(echo "$event" | jq -r '.type')" = "agent.complete" ]
[ "$(echo "$event" | jq -r '.phase')" = "do" ]
[ "$(echo "$event" | jq -r '.agent')" = "maker" ]
[ "$(echo "$event" | jq -r '.data.tokens')" = "500" ]
}
@test "event: empty agent becomes null in JSON" {
"$LIB_DIR/archeflow-event.sh" test-run phase.transition do "" '{"from":"plan","to":"do"}' 2>/dev/null
local agent
agent=$(head -1 ".archeflow/events/test-run.jsonl" | jq -r '.agent')
[ "$agent" = "null" ]
}
@test "event: parent field is empty array for root events" {
"$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{}' 2>/dev/null
local parent
parent=$(head -1 ".archeflow/events/test-run.jsonl" | jq -c '.parent')
[ "$parent" = "[]" ]
}
@test "event: single parent is parsed correctly" {
"$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{}' 2>/dev/null
"$LIB_DIR/archeflow-event.sh" test-run agent.complete plan creator '{}' "1" 2>/dev/null
local parent
parent=$(tail -1 ".archeflow/events/test-run.jsonl" | jq -c '.parent')
[ "$parent" = "[1]" ]
}
@test "event: multiple parents (fan-in) are parsed correctly" {
"$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{}' 2>/dev/null
"$LIB_DIR/archeflow-event.sh" test-run a plan "" '{}' "1" 2>/dev/null
"$LIB_DIR/archeflow-event.sh" test-run b plan "" '{}' "1" 2>/dev/null
"$LIB_DIR/archeflow-event.sh" test-run merge plan "" '{}' "2,3" 2>/dev/null
local parent
parent=$(tail -1 ".archeflow/events/test-run.jsonl" | jq -c '.parent')
[ "$parent" = "[2,3]" ]
}
@test "event: rejects invalid JSON data" {
run "$LIB_DIR/archeflow-event.sh" test-run run.start plan "" 'not-json'
[ "$status" -eq 1 ]
[[ "$output" == *"invalid JSON"* ]]
}
@test "event: rejects invalid parent format" {
run "$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{}' "abc"
[ "$status" -eq 1 ]
[[ "$output" == *"invalid parent format"* ]]
}
@test "event: timestamp is ISO 8601 UTC format" {
"$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{}' 2>/dev/null
local ts
ts=$(head -1 ".archeflow/events/test-run.jsonl" | jq -r '.ts')
# Matches YYYY-MM-DDTHH:MM:SSZ
[[ "$ts" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ ]]
}
@test "event: default data is empty object when omitted" {
"$LIB_DIR/archeflow-event.sh" test-run run.start plan agent 2>/dev/null
local data
data=$(head -1 ".archeflow/events/test-run.jsonl" | jq -c '.data')
[ "$data" = "{}" ]
}
@test "event: confirmation message goes to stderr" {
run "$LIB_DIR/archeflow-event.sh" test-run run.start plan "" '{}' "" 2>&1
[[ "$output" == *"[archeflow-event]"* ]]
[[ "$output" == *"#1"* ]]
}