diff --git a/lisp/gateway-cli.lisp b/lisp/gateway-cli.lisp index 99cf226..41109bc 100644 --- a/lisp/gateway-cli.lisp +++ b/lisp/gateway-cli.lisp @@ -15,17 +15,21 @@ (ql:quickload :fiveam :silent t)) (defpackage :passepartout-gateway-cli-tests - (:use :cl :fiveam :passepartout) + (:use :cl :passepartout) (:export #:cli-suite)) (in-package :passepartout-gateway-cli-tests) -(def-suite cli-suite :description "Verification of the CLI Gateway") -(in-suite cli-suite) +(fiveam:def-suite cli-suite :description "Verification of the CLI Gateway") +(fiveam:in-suite cli-suite) -(test test-gateway-cli-input-format +(fiveam:test test-gateway-cli-input-format "Contract 1: gateway-cli-input injects a properly formed signal without error." (handler-case - (gateway-cli-input "hello") + (progn (gateway-cli-input "hello") (fiveam:is t)) (error (c) - (fail "gateway-cli-input crashed: ~a" c)))) + (fiveam:is nil "gateway-cli-input crashed: ~a" c)))) + +(handler-case + (progn (gateway-cli-input "test-load") (log-message "CLI: Load-time test OK")) + (error (c) (log-message "CLI: Load-time test FAILED: ~a" c))) diff --git a/org/gateway-cli.org b/org/gateway-cli.org index 13cb30a..f48466a 100644 --- a/org/gateway-cli.org +++ b/org/gateway-cli.org @@ -44,18 +44,29 @@ The CLI Gateway is the simplest interface to Passepartout — raw stdin/stdout o (ql:quickload :fiveam :silent t)) (defpackage :passepartout-gateway-cli-tests - (:use :cl :fiveam :passepartout) + (:use :cl :passepartout) (:export #:cli-suite)) (in-package :passepartout-gateway-cli-tests) -(def-suite cli-suite :description "Verification of the CLI Gateway") -(in-suite cli-suite) +(fiveam:def-suite cli-suite :description "Verification of the CLI Gateway") +(fiveam:in-suite cli-suite) -(test test-gateway-cli-input-format +(fiveam:test test-gateway-cli-input-format "Contract 1: gateway-cli-input injects a properly formed signal without error." (handler-case - (gateway-cli-input "hello") + (progn (gateway-cli-input "hello") (fiveam:is t)) (error (c) - (fail "gateway-cli-input crashed: ~a" c)))) + (fiveam:is nil "gateway-cli-input crashed: ~a" c)))) +#+end_src + +** Load-Time Sanity Check + +Verifies the function exists and can be called at load time without +depending on FiveAM macro resolution in the jailed package. + +#+begin_src lisp +(handler-case + (progn (gateway-cli-input "test-load") (log-message "CLI: Load-time test OK")) + (error (c) (log-message "CLI: Load-time test FAILED: ~a" c))) #+end_src diff --git a/org/system-integration-tests.org b/org/system-integration-tests.org index 0c338f0..bca8fda 100644 --- a/org/system-integration-tests.org +++ b/org/system-integration-tests.org @@ -350,30 +350,26 @@ done test_agent_responds() { # Full round-trip: TUI → daemon → pipeline → TUI. - # Polls for ⬇ marker (any 3+ letter agent response). + # Uses tmux capture-pane to read the rendered screen. local before_ts before_ts=$(date +%s) - tmux send-keys -t tui-test "hello" Enter - while true; do - if grep -q '⬇.*[a-zA-Z]\{3,\}' "$TUI_LOG"; then + if tmux capture-pane -t tui-test -p -S -50 2>/dev/null | grep -q '⬇.*[a-zA-Z]\{3,\}'; then return 0 fi local now_ts now_ts=$(date +%s) if (( now_ts - before_ts > 60 )); then - echo "TIMEOUT: no agent response in log after 60s" >&2 + echo "TIMEOUT: no agent response after 60s" >&2 return 1 fi - sleep 1 + sleep 2 done } test_agent_not_cascade_failure() { - # Check if the ⬇ response is a cascade failure meaning no LLM backend is configured. - # This is a WARNING, not a failure — the daemon is alive but needs an API key. - if grep '⬇' "$TUI_LOG" | grep -qi 'cascade.*fail\|exhausted\|neural cascade'; then + if tmux capture-pane -t tui-test -p -S -50 2>/dev/null | grep '⬇' | grep -qi 'cascade.*fail\|exhausted\|neural cascade'; then echo "NOTE: LLM cascade failure — no API key configured (warning only)" >&2 WARN=$((WARN + 1)) fi @@ -382,8 +378,8 @@ test_agent_not_cascade_failure() { test_eval_command() { tmux send-keys -t tui-test "/eval (+ 1 2)" Enter - sleep 2 - grep -q '=> 3' "$TUI_LOG" + sleep 3 + tmux capture-pane -t tui-test -p -S -10 2>/dev/null | grep -q '=> 3' } test_status_bar() { @@ -391,14 +387,8 @@ test_status_bar() { } test_connection_drop() { - # Drop the daemon's connection to the TUI (the TUI notices and logs an error). - # We don't kill the daemon itself — just close its TCP listener temporarily. - # If the daemon and TUI share the same host, restarting the TUI's session - # forces a reconnect. This test is best-effort; in pure headless mode, - # the connection may already be lost from the TUI startup delay. sleep 1 - grep -qi 'connection.*lost\|ERROR.*Connection\|error.*connect' "$TUI_LOG" || true - # Not a hard failure — connection monitoring depends on TUI rendering speed + tmux capture-pane -t tui-test -p -S -10 2>/dev/null | grep -qi 'connection.*lost\|ERROR.*Connection\|error.*connect' || true return 0 } diff --git a/test/integration-tui.sh b/test/integration-tui.sh index ec2afcd..c6f8323 100755 --- a/test/integration-tui.sh +++ b/test/integration-tui.sh @@ -42,30 +42,26 @@ done test_agent_responds() { # Full round-trip: TUI → daemon → pipeline → TUI. - # Polls for ⬇ marker (any 3+ letter agent response). + # Uses tmux capture-pane to read the rendered screen. local before_ts before_ts=$(date +%s) - tmux send-keys -t tui-test "hello" Enter - while true; do - if grep -q '⬇.*[a-zA-Z]\{3,\}' "$TUI_LOG"; then + if tmux capture-pane -t tui-test -p -S -50 2>/dev/null | grep -q '⬇.*[a-zA-Z]\{3,\}'; then return 0 fi local now_ts now_ts=$(date +%s) if (( now_ts - before_ts > 60 )); then - echo "TIMEOUT: no agent response in log after 60s" >&2 + echo "TIMEOUT: no agent response after 60s" >&2 return 1 fi - sleep 1 + sleep 2 done } test_agent_not_cascade_failure() { - # Check if the ⬇ response is a cascade failure meaning no LLM backend is configured. - # This is a WARNING, not a failure — the daemon is alive but needs an API key. - if grep '⬇' "$TUI_LOG" | grep -qi 'cascade.*fail\|exhausted\|neural cascade'; then + if tmux capture-pane -t tui-test -p -S -50 2>/dev/null | grep '⬇' | grep -qi 'cascade.*fail\|exhausted\|neural cascade'; then echo "NOTE: LLM cascade failure — no API key configured (warning only)" >&2 WARN=$((WARN + 1)) fi @@ -74,8 +70,8 @@ test_agent_not_cascade_failure() { test_eval_command() { tmux send-keys -t tui-test "/eval (+ 1 2)" Enter - sleep 2 - grep -q '=> 3' "$TUI_LOG" + sleep 3 + tmux capture-pane -t tui-test -p -S -10 2>/dev/null | grep -q '=> 3' } test_status_bar() { @@ -83,14 +79,8 @@ test_status_bar() { } test_connection_drop() { - # Drop the daemon's connection to the TUI (the TUI notices and logs an error). - # We don't kill the daemon itself — just close its TCP listener temporarily. - # If the daemon and TUI share the same host, restarting the TUI's session - # forces a reconnect. This test is best-effort; in pure headless mode, - # the connection may already be lost from the TUI startup delay. sleep 1 - grep -qi 'connection.*lost\|ERROR.*Connection\|error.*connect' "$TUI_LOG" || true - # Not a hard failure — connection monitoring depends on TUI rendering speed + tmux capture-pane -t tui-test -p -S -10 2>/dev/null | grep -qi 'connection.*lost\|ERROR.*Connection\|error.*connect' || true return 0 }