Files
capy-bearer/scripts/test_capy_phase1.sh

1011 lines
60 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
site_directory="${BEARER_TEST_SITE_DIRECTORY:-site}"
bin_directory="${BEARER_TEST_BIN_DIRECTORY:-/tmp/bearer/work}"
if [[ -r /etc/bearer/settings.cfg ]]; then
configured_site=$(awk -F= '/^[[:space:]]*HTTP_DOCUMENT_ROOT[[:space:]]*=/ {sub(/^[^=]*=/, ""); print; exit}' /etc/bearer/settings.cfg)
configured_bin=$(awk -F= '/^[[:space:]]*BIN_DIRECTORY[[:space:]]*=/ {sub(/^[^=]*=/, ""); print; exit}' /etc/bearer/settings.cfg)
[[ -n "${BEARER_TEST_SITE_DIRECTORY:-}" ]] || site_directory="${configured_site:-$site_directory}"
[[ -n "${BEARER_TEST_BIN_DIRECTORY:-}" ]] || bin_directory="${configured_bin:-$bin_directory}"
fi
site_directory=$(realpath "$site_directory")
expect_equal() {
local case_name=$1 expected=$2 actual=$3
if [[ "$actual" != "$expected" ]]; then
printf '%s mismatch\nexpected: %q\nactual: %q\n' "$case_name" "$expected" "$actual" >&2
exit 1
fi
}
native_compiler_id=$(sha256sum src/capy/*.cpp src/capy/*.h src/lib/compiler.cpp src/lib/markup-context.h | sha256sum | awk '{print $1}')
grep -aFq "$native_compiler_id" bin/bearer_fastcgi.linux.bin || {
echo "Bearer binary does not contain the current native Capy compiler identity" >&2
exit 1
}
stdlib_digest=$(sha256sum src/capy/stdlib.capy | awk '{print $1}')
grep -aFq "$stdlib_digest" bin/bearer_fastcgi.linux.bin || {
echo "Bearer binary does not contain the current embedded Capy standard library" >&2
exit 1
}
output=$(scripts/bearer-cli /tests/capy-phase1.capy)
[[ "$output" == "capy-direct-ok" ]] || { echo "Capy CLI output mismatch: $output" >&2; exit 1; }
expect_equal "math fixture" "capy-math-ok" "$(scripts/bearer-cli /tests/capy-math.capy)"
expect_equal "bits fixture" "capy-bits-ok" "$(scripts/bearer-cli /tests/capy-bits.capy)"
expect_equal "byte conversion fixture" "3|0|65|255|0|5" "$(scripts/bearer-cli /tests/capy-byte-conversion.capy)"
expect_equal "scalar format fixture" "capy-format-ok" "$(scripts/bearer-cli /tests/capy-format.capy)"
expect_equal "in-Wasm string fixture" "capy-string-hostpath-ok" "$(scripts/bearer-cli /tests/capy-string-hostpath.capy)"
expect_equal "identity string conversion preserves the source" "alivealive|0" "$(scripts/bearer-cli /tests/capy-string-identity.capy)"
expect_equal "flush_output ordering and reset" "first|true|second" "$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-flush-output.capy)"
language_output=$(scripts/bearer-cli /tests/capy-language.capy)
[[ "$language_output" == "sum=30;012;ok;01" ]] || {
echo "Capy functions/locals/control-flow output mismatch: $language_output" >&2
exit 1
}
operator_output=$(scripts/bearer-cli /tests/capy-operators.capy)
[[ "$operator_output" == "false|true|Xtrue|7|-5|true|false0|true0" ]] || {
echo "Capy logical/unary/inferred-declaration output mismatch: $operator_output" >&2
exit 1
}
expect_equal "newline-independent expression parsing" "7|3|9" "$(scripts/bearer-cli /tests/capy-whitespace.capy)"
expect_equal "condition constructors and any bool extraction" "UuSsDdBbTTTTtttWC|true|false" "$(scripts/bearer-cli /tests/capy-condition-coercion.capy)"
(
condition_type_dir=$(mktemp -d "$site_directory/tests/capy-condition-type.XXXXXX")
trap 'rm -rf -- "$condition_type_dir"' EXIT
condition_type_name=${condition_type_dir##*/}
for case in \
'literal|function CLI(request : any) { if "true" {} }' \
'component|function CLI(request : any) { var name := "/tests/capy-request-context"; if component_resolve(name) {} }'; do
name=${case%%|*}; source=${case#*|}
printf '%s\n' "$source" >"$condition_type_dir/$name.capy"
set +e
condition_type_output=$(scripts/bearer-cli "/tests/$condition_type_name/$name.capy" 2>&1)
condition_type_status=$?
set -e
[[ $condition_type_status -ne 0 && "$condition_type_output" == *"$name.capy:1:"* ]] || {
echo "Capy $name condition type check did not fail: $condition_type_output" >&2
exit 1
}
done
)
set +e
component_render_output=$(scripts/bearer-cli /tests/capy-component-render-result.capy 2>&1)
component_render_status=$?
set -e
[[ $component_render_status -ne 0 ]]
[[ "$component_render_output" == *"500"* ]]
[[ "$component_render_output" == *"rendered|true|false"* ]]
[[ "$component_render_output" != *'<div class="banner">'* ]]
consistency_expected="1|-2|3|4.5|x|10.5|3|4|left|right|early|late|0"
expect_equal "type aliases, value blocks, conditional values, and wide aggregates" \
"$consistency_expected" "$(scripts/bearer-cli /tests/capy-language-consistency.capy)"
(
value_trap_dir=$(mktemp -d "$site_directory/tests/capy-value-trap.XXXXXX")
trap 'rm -rf -- "$value_trap_dir"' EXIT
value_trap_name=${value_trap_dir##*/}
cat >"$value_trap_dir/then.capy" <<'EOF'
function CLI(request : any) {
var value := if true { -> [1][1] } else { -> [1][0] }
print(value)
}
EOF
cat >"$value_trap_dir/else.capy" <<'EOF'
function CLI(request : any) {
var value := if false { -> [1][0] } else { -> [1][1] }
print(value)
}
EOF
cat >"$value_trap_dir/block.capy" <<'EOF'
function CLI(request : any) {
var value := { var values := [1]; -> values[1] }
print(value)
}
EOF
for case in then:2:34 else:2:54 block:2:48; do
name=${case%%:*}; location=${case#*:}
set +e
value_trap_output=$(scripts/bearer-cli "/tests/$value_trap_name/$name.capy" 2>&1)
value_trap_status=$?
set -e
[[ $value_trap_status -ne 0 && "$value_trap_output" == *"$name.capy:$location"* ]] || {
echo "Capy $name value trap/source mapping mismatch: $value_trap_output" >&2
exit 1
}
expect_equal "$name value trap recovery" "$consistency_expected" "$(scripts/bearer-cli /tests/capy-language-consistency.capy)"
done
)
coercion_expected="7|8|42|-9|10|4.25|true|false|12|false|1|2|103|9|4|0"
expect_equal "declared parameter coercion and constructors" "$coercion_expected" "$(scripts/bearer-cli /tests/capy-coercion.capy)"
(
dval_default_dir=$(mktemp -d "$site_directory/tests/capy-any-default.XXXXXX")
trap 'rm -rf -- "$dval_default_dir"' EXIT
cat >"$dval_default_dir/entry.capy" <<'EOF'
function fresh(opt : any = {nested: {items: [1, true, "x"]}}) any { -> opt }
function CLI(request : any) {
{
var first := fresh()
first.nested.items[0] = 2
first.nested.extra = "mutated"
var second := fresh()
print(s64(first.nested.items[0]), "|", s64(second.nested.items[0]), "|", bool(second.nested.items[1]), "|", second.nested.items[2], "|", second.nested.extra?)
}
print("|", arc_live())
}
EOF
expect_equal "DValue default identity" "2|1|true|x|false|0" "$(scripts/bearer-cli "/tests/${dval_default_dir##*/}/entry.capy")"
)
expect_equal "constructor options and precision" \
"7:7:7:7:0:7:7|7:7:7:7:0:7:7|7:7:7:7:0:7:7|7:7:7:7:0:7:7|7:7:7:7:true:7:7|true:false:true|true:true:true|11:12:13:-14:-15:-16:21:22:23:1.1000000000000001:1.2:1.3:absent:empty:true:true:false|5:5:255:255:42|1:-1:3:5:2:1:0:0|0:0:-9223372036854775808:255:0:127" \
"$(scripts/bearer-cli /tests/capy-constructors.capy)"
expect_equal "complete numeric grid" "127|-32768|255|65535|4294967295|1.5|7|8|4294967295|2.5|0" \
"$(scripts/bearer-cli /tests/capy-numeric-grid.capy)"
(
constructor_reject_dir=$(mktemp -d "$site_directory/tests/capy-constructor-reject.XXXXXX")
trap 'rm -rf -- "$constructor_reject_dir"' EXIT
printf '%s\n' 'function CLI(request : any) { print(u64("10", {base: 1.5})) }' >"$constructor_reject_dir/entry.capy"
set +e
constructor_base_output=$(scripts/bearer-cli "/tests/${constructor_reject_dir##*/}/entry.capy" 2>&1)
constructor_base_status=$?
set -e
[[ $constructor_base_status -ne 0 && "$constructor_base_output" == *"u64: base must be a whole number from 2 to 36"* ]] || {
echo "Capy did not reject a fractional constructor base: $constructor_base_output" >&2
exit 1
}
for source in \
'function CLI(request : any) { print(u64("10", {unknown: 1})) }' \
'function CLI(request : any) { print(f64("1", {base: 10})) }' \
'function CLI(request : any) { print(string("1", {base: 10})) }' \
'function CLI(request : any) { if "true" {} }'; do
printf '%s\n' "$source" >"$constructor_reject_dir/entry.capy"
if scripts/bearer-cli "/tests/${constructor_reject_dir##*/}/entry.capy" >/dev/null 2>&1; then
echo "Capy accepted an invalid constructor option or string condition" >&2
exit 1
fi
done
)
vector_expected="7|token|8|A|Ab|inside3|insideb|x|local|insidebz|0|8|2|1.5|c|12|9|p|a2true|b3|4c|4|4c|imir|function-print6|0"
expect_equal "constructors, shared vector arrays, variadics, splats, function values, and ARC" \
"$vector_expected" "$(scripts/bearer-cli /tests/capy-vector-variadic.capy)"
mutable_aggregate_expected="98335618|0|thirdfirstsecond1|aBaBctemporaryaB|2|12333|10213245789m0q|12967by|1291233abz0|89000000001parameter6new412|0"
expect_equal "stable mutable arrays and struct fields" \
"$mutable_aggregate_expected" "$(scripts/bearer-cli /tests/capy-mutable-array-struct.capy)"
expect_equal "managed parameter rebinding, nibble, and aggregate mutation" \
"go!|go|api:api/length|cc/dd?:cc/dd:zz|0|78|425|9|8" "$(scripts/bearer-cli /tests/capy-managed-parameter-rebind.capy)"
(
cycle_dir=$(mktemp -d "$site_directory/tests/capy-cycle.XXXXXX")
trap 'rm -rf -- "$cycle_dir"' EXIT
cat >"$cycle_dir/entry.capy" <<'EOF'
struct Cycle { children : [Cycle] }
function empty_cycles() [Cycle] { var values : [Cycle] = []; -> values }
function CLI(request : any) { var cycle := Cycle(empty_cycles()); cycle.children.push(cycle); print(arc_live() > 0) }
EOF
expect_equal "characterized strong aggregate cycle" "true" "$(scripts/bearer-cli "/tests/${cycle_dir##*/}/entry.capy")"
expect_equal "clean request after strong aggregate cycle" "$mutable_aggregate_expected" "$(scripts/bearer-cli /tests/capy-mutable-array-struct.capy)"
)
(
vector_trap_dir=$(mktemp -d "$site_directory/tests/capy-vector-traps.XXXXXX")
trap 'rm -rf -- "$vector_trap_dir"' EXIT
for case in \
'pop|function CLI(request : any) { var values : [s32] = []; values.pop() }' \
'insert|function CLI(request : any) { var values := [1]; values.insert(2, 2) }' \
'remove|function CLI(request : any) { var values := [1]; values.remove(-1) }' \
'reserve|function CLI(request : any) { var values := [1]; values.reserve(-1) }' \
'resize|function CLI(request : any) { var values := [1]; values.resize(-1, 0) }'; do
name=${case%%|*}; source=${case#*|}
printf '%s\n' "$source" >"$vector_trap_dir/$name.capy"
set +e
output=$(scripts/bearer-cli "/tests/${vector_trap_dir##*/}/$name.capy" 2>&1)
status=$?
set -e
[[ $status -ne 0 && "$output" == *"$name.capy:1:"* && "$output" != *"capy://stdlib.capy"* ]]
expect_equal "vector trap recovery after $name" "$vector_expected" "$(scripts/bearer-cli /tests/capy-vector-variadic.capy)"
done
)
(
coercion_trap_dir=$(mktemp -d "$site_directory/tests/capy-coercion-trap.XXXXXX")
trap 'rm -rf -- "$coercion_trap_dir"' EXIT
coercion_trap_name=${coercion_trap_dir##*/}
cat >"$coercion_trap_dir/entry.capy" <<'EOF'
function narrow(value : as s64) s64 { -> value }
function CLI(request : any) { print(narrow(1e300)) }
EOF
expect_equal "parameter conversion f64 formatting" "0" "$(scripts/bearer-cli "/tests/$coercion_trap_name/entry.capy")"
expect_equal "parameter conversion recovery" "$coercion_expected" "$(scripts/bearer-cli /tests/capy-coercion.capy)"
)
variable_expression_output=$(scripts/bearer-cli /tests/capy-variable-expressions.capy)
[[ "$variable_expression_output" == "var;true;typed;true;inferred;true;assigned;true;once;once-value;true;false;visible;equal;passed;call;and;or;2;2;0;2;0;returned;implicit;0" ]] || {
echo "Capy value-producing declaration output/ARC mismatch: $variable_expression_output" >&2
exit 1
}
(
variable_trap_dir=$(mktemp -d "$site_directory/tests/capy-variable-trap.XXXXXX")
trap 'rm -rf -- "$variable_trap_dir"' EXIT
variable_trap_name=${variable_trap_dir##*/}
cat >"$variable_trap_dir/entry.capy" <<'EOF'
function CLI(request : any) {
var owned := clone("owned")
while var again := true { var value := [1][1] }
}
EOF
set +e
variable_trap_output=$(scripts/bearer-cli "/tests/$variable_trap_name/entry.capy" 2>&1)
variable_trap_status=$?
set -e
[[ $variable_trap_status -ne 0 && "$variable_trap_output" == *"entry.capy:3:47"* ]] || {
echo "Capy declaration initializer trap/source mapping mismatch: $variable_trap_output" >&2
exit 1
}
expect_equal "declaration initializer trap recovery" "$variable_expression_output" "$(scripts/bearer-cli /tests/capy-variable-expressions.capy)"
)
backtrace_output=$(scripts/bearer-cli /tests/capy-backtrace.capy)
expected_backtrace=$'#0 __lambda_0 at tests/capy-backtrace.capy:7:17\n#1 inner at tests/capy-backtrace.capy:5:1\n#2 outer at tests/capy-backtrace.capy:1:1\n#3 CLI at tests/capy-backtrace.capy:32:1\n==\n#0 inner at tests/capy-backtrace.capy:5:1\n#1 outer at tests/capy-backtrace.capy:1:1\n--\n|0\n++\n#0 explicit_return_trace at tests/capy-backtrace.capy:20:1\n#1 CLI at tests/capy-backtrace.capy:32:1\n~~\n#0 CLI at tests/capy-backtrace.capy:32:1\n@@\n|#0 bounds at tests/capy-backtrace.capy:24:1\n#1 CLI at tests/capy-backtrace.capy:32:1||#0 bounds at tests/capy-backtrace.capy:24:1\n#1 CLI at tests/capy-backtrace.capy:32:1'
expect_equal "Capy source-mapped guest backtrace" "$expected_backtrace" "$backtrace_output"
(
backtrace_test_dir=$(mktemp -d "$site_directory/tests/capy-backtrace-test.XXXXXX")
trap 'rm -rf -- "$backtrace_test_dir"' EXIT
backtrace_test_name=${backtrace_test_dir##*/}
{
printf 'function tail() string { -> backtrace_get_frames(2147483647, 0) }\n'
for ((frame = 0; frame < 300; ++frame)); do
if ((frame == 299)); then
printf 'function ring_%d() string { -> tail() }\n' "$frame"
else
printf 'function ring_%d() string { -> ring_%d() }\n' "$frame" "$((frame + 1))"
fi
done
printf 'function CLI(request : any) { print(ring_0()) }\n'
} > "$backtrace_test_dir/ring.capy"
ring_output=$(scripts/bearer-cli "/tests/$backtrace_test_name/ring.capy")
mapfile -t ring_frames <<< "$ring_output"
[[ ${#ring_frames[@]} -eq 256 && ${#ring_output} -gt 4096 ]] || {
echo "Capy backtrace ring/two-pass output bounds mismatch" >&2
exit 1
}
expect_equal "Capy backtrace ring newest frame" "#0 tail at tests/$backtrace_test_name/ring.capy:1:1" "${ring_frames[0]}"
expect_equal "Capy backtrace ring oldest retained frame" "#255 ring_45 at tests/$backtrace_test_name/ring.capy:47:1" "${ring_frames[255]}"
)
dval_return_output=$(scripts/bearer-cli /tests/capy-any-return.capy)
[[ "$dval_return_output" == "3|0|42|1|0|000|0|9|1|0" ]] || {
echo "Capy any-loop early-return ARC mismatch: $dval_return_output" >&2
exit 1
}
wide_output=$(scripts/bearer-cli /tests/capy-wide-scalars.capy)
[[ "$wide_output" == "8|8|9|9|18446744073709551615|-9223372036854775808|-1|-3|-1|true|true|3|2|true|125|-1.5|5|3.5|0|9|0|true|truetrue|inf|falsetrue|-0|0" ]] || {
echo "Capy wide scalar operations mismatch: $wide_output" >&2
exit 1
}
expect_equal "wide scalar invalid string fallback" "0" "$(scripts/bearer-cli /tests/capy-wide-conversion-trap.capy)"
expect_equal "wide scalar recovery" "$wide_output" "$(scripts/bearer-cli /tests/capy-wide-scalars.capy)"
rm -f /tmp/capy-files-phase-* /tmp/capy-files2-*
file_output=$(scripts/bearer-cli /tests/capy-files.capy)
[[ "$file_output" == "true|5|0|capy!|5|true|2|0|true|true" ]] || {
echo "Capy file handle/ARC mismatch: $file_output" >&2
exit 1
}
filesystem_output=$(scripts/bearer-cli /tests/capy-files2.capy)
[[ "$filesystem_output" == "a.txt|true|truetruetruetruetruetruetruetrue|abc|ab|abc|truetrue3|true|a.txt,b.txt,link.txt|truefalsetruetruetruetruetrue|true|true|true|true" ]] || {
echo "Capy filesystem stdlib/policy mismatch: $filesystem_output" >&2
exit 1
}
expect_equal "filesystem recovery" "$filesystem_output" "$(scripts/bearer-cli /tests/capy-files2.capy)"
expect_equal "file/archive/split_kv adapters" "3|heXYZ|Ada:admin|na\\=me=Ada\\=Grace\\, Lovelace,role=admin|Ada=Grace, Lovelace:admin|archive data|true2truetruetrue|11|0|true" "$(scripts/bearer-cli /tests/capy-final-parity.capy)"
set +e
archive_trap_output=$(scripts/bearer-cli /tests/capy-archive-trap.capy 2>&1)
archive_trap_status=$?
set -e
[[ $archive_trap_status -ne 0 && "$archive_trap_output" == *"capy-archive-trap.capy:3:8"* && "$archive_trap_output" != *"capy://stdlib.capy"* ]]
expect_equal "archive recovery" "3|heXYZ|Ada:admin|na\\=me=Ada\\=Grace\\, Lovelace,role=admin|Ada=Grace, Lovelace:admin|archive data|true2truetruetrue|11|0|true" "$(scripts/bearer-cli /tests/capy-final-parity.capy)"
expect_equal "live MySQL stdlib adapters" "truetrue|'a\\'b'|7|true|0:0|truetruetrue|truetrue|truetruetrue|truetrue|truetruetrue7|truetruetrue|0" "$(scripts/bearer-cli /tests/capy-mysql.capy)"
expect_equal "memcache key normalization and complete response reads" "down|collision|large-ok|0" "$(scripts/bearer-cli /tests/capy-memcache.capy)"
expect_equal "shell_exec sync and on_done callback through a task" "true|sync:3|true|done 0 printf done|invalid_target|true|0" "$(scripts/bearer-cli /tests/capy-shell-callback.capy)"
for shell_exec_case in \
"capy-shell-exec-flags-trap|shell_exec: unknown key 'unknown'. Valid keys: stdin, env, timeout_ms, on_done" \
"capy-shell-exec-on-done-type-trap|shell_exec: on_done must be a string" \
"capy-shell-exec-timeout-type-trap|shell_exec: timeout_ms must be a positive number" \
"capy-shell-exec-timeout-value-trap|shell_exec: timeout_ms must be a positive number" \
"capy-shell-exec-stdin-type-trap|shell_exec: stdin must be a string" \
"capy-shell-exec-env-list-trap|shell_exec: env must be a map with string values" \
"capy-shell-exec-env-value-trap|shell_exec: env must be a map with string values"; do
shell_exec_fixture=${shell_exec_case%%|*}
shell_exec_message=${shell_exec_case#*|}
set +e
shell_exec_flags_output=$(scripts/bearer-cli "/tests/$shell_exec_fixture.capy" 2>&1)
shell_exec_flags_status=$?
set -e
[[ $shell_exec_flags_status -ne 0 && "$shell_exec_flags_output" == *"$shell_exec_message"* ]] || {
echo "Capy $shell_exec_fixture diagnostic mismatch: $shell_exec_flags_output" >&2
exit 1
}
done
expect_equal "named CLI entry point" "echo:hi" "$(scripts/bearer-cli --get /tests/capy-cli-named.capy:ECHO message=hi)"
expect_equal "default CLI entry point beside a named one" "default" "$(scripts/bearer-cli /tests/capy-cli-named.capy)"
expect_equal "task_execute runs detached, bounded by its timeout" "true|Ada|true|false|invalid_target" "$(scripts/bearer-cli /tests/capy-task-execute.capy)"
expect_equal "service missing target and complete status" "false|false|false|missing|6|0|0|0|0|false" \
"$(timeout 30 scripts/bearer-cli --get /tests/capy-services-api.capy mode=basic)"
for service_case in every:service_every spawn:port_spawn connect:port_connect listen:port_listen write:port_write close:port_close; do
service_mode=${service_case%%:*}
service_function=${service_case#*:}
set +e
service_output=$(timeout 30 scripts/bearer-cli --get /tests/capy-services-api.capy "mode=$service_mode" 2>&1)
service_status=$?
set -e
[[ $service_status -ne 0 && "$service_output" == *"$service_function: requires a service worker"* ]] || {
echo "Capy $service_function context diagnostic mismatch: $service_output" >&2
exit 1
}
done
expect_equal "unit-scope variables persist across handler calls in one workspace" "2|ab|2|2|c|100" "$(scripts/bearer-cli /tests/capy-unit-vars.capy)"
expect_equal "unit-scope variables start fresh per request" "2|ab|2|2|c|100" "$(scripts/bearer-cli /tests/capy-unit-vars.capy)"
BEARER_TEST_SITE_DIRECTORY="$site_directory" timeout 20 bash scripts/test_capy_services.sh
expect_equal "unit administration" "true|true|true|2|0" "$(scripts/bearer-cli /tests/capy-unit-admin.capy)"
expect_equal "DValue array merge" "rightyesnewright|abcd|valueitem|right|value|z|oddkeep|map|unicode|9|0" "$(scripts/bearer-cli /tests/capy-any-merge.capy)"
expect_equal "DValue value API" 'truefalseAda42tail|trueone|Bearerfalse|truearray"A"|ftruey|truefalseAdanameengineer|23truefalse|-4242-918446744073709551615|0' "$(scripts/bearer-cli /tests/capy-any-api.capy)"
set +e
expect_equal "DValue value API recovery" 'truefalseAda42tail|trueone|Bearerfalse|truearray"A"|ftruey|truefalseAdanameengineer|23truefalse|-4242-918446744073709551615|0' "$(scripts/bearer-cli /tests/capy-any-api.capy)"
expect_equal "shared mutable DValue identity, live loops, range bindings, codec copies, and ARC" \
'SR|999secondyesyesyesyesvalue10|newnewtruetruetrue|1falsefalsetrueitemtruearraynewnewvalue1|true|102132|1021|0199|7a|3|sourceresult|0' "$(scripts/bearer-cli /tests/capy-any-identity.capy)"
expect_equal "nested closure string DValue ARC" "BETA|ALPHA|0" "$(scripts/bearer-cli /tests/capy-map-arc.capy)"
sqlite_output=$(scripts/bearer-cli /tests/capy-sqlite.capy)
expect_equal "SQLite lifecycle/query" "11|1Ada|true|1|0" "$sqlite_output"
expect_equal "SQLite failed-connect diagnostic" "true|0" "$(scripts/bearer-cli /tests/capy-sqlite-failed.capy)"
for info_case in \
"capy-mysql-info-trap|mysql_info: unknown key 'missing'. Valid keys: connection, error, insert_id, affected_rows" \
"capy-sqlite-info-trap|sqlite_info: unknown key 'missing'. Valid keys: error, insert_id, affected_rows" \
"capy-posix-info-trap|posix_info: unknown key 'missing'. Valid keys: signal_name"; do
info_fixture=${info_case%%|*}
info_message=${info_case#*|}
set +e
info_trap_output=$(scripts/bearer-cli "/tests/$info_fixture.capy" 2>&1)
info_trap_status=$?
set -e
[[ $info_trap_status -ne 0 && "$info_trap_output" == *"$info_message"* ]] || {
echo "Capy $info_fixture unknown-key diagnostic mismatch: $info_trap_output" >&2
exit 1
}
done
for sqlite_case in \
"capy-sqlite-handle-trap|5:8" \
"capy-sqlite-params-trap|4:2" \
"capy-sqlite-zero-trap|3:8"; do
sqlite_fixture=${sqlite_case%%|*}
sqlite_location=${sqlite_case#*|}
set +e
sqlite_trap_output=$(scripts/bearer-cli "/tests/$sqlite_fixture.capy" 2>&1)
sqlite_trap_status=$?
set -e
[[ $sqlite_trap_status -ne 0 && "$sqlite_trap_output" == *"$sqlite_fixture.capy:$sqlite_location"* && "$sqlite_trap_output" != *"capy://stdlib.capy"* ]]
done
set +e
sized_host_trap_output=$(scripts/bearer-cli /tests/capy-sqlite-sized-host-trap.capy 2>&1)
sized_host_trap_status=$?
set -e
[[ $sized_host_trap_status -ne 0 && "$sized_host_trap_output" == *"capy-sqlite-sized-host-trap.capy:5:2"* && "$sized_host_trap_output" != *"capy://stdlib.capy" ]] || {
echo "Capy generic sized-host failure did not trap at the owned-input callsite: $sized_host_trap_output" >&2
exit 1
}
expect_equal "generic sized-host failure recovery/ARC" "$sqlite_output" "$(scripts/bearer-cli /tests/capy-sqlite.capy)"
codec_output=$(scripts/bearer-cli /tests/capy-codecs.capy)
[[ "$codec_output" == "<Ada>|1.5true|Q2FweSE=|Capy!|0|a%20b%26|a b&|&lt;&amp;&gt;&quot;&#39;|{}|3|0" ]] || {
echo "Capy codec/JSON/ARC mismatch: $codec_output" >&2
exit 1
}
expect_equal "invalid f64 constructor fallback" "0" "$(scripts/bearer-cli /tests/capy-any-f64-trap.capy)"
expect_equal "codec recovery" "$codec_output" "$(scripts/bearer-cli /tests/capy-codecs.capy)"
expect_equal "custom and default sort" 'sort-ok' "$(scripts/bearer-cli /tests/capy-sort.capy)"
expect_equal "codec/text stdlib adapters" 'Ada|Ada|6|Ada|10|document|<p><strong>bold</strong></p>|"x"|{"name": "Ada"}|&lt;&amp;&gt;&quot;|8|0' "$(scripts/bearer-cli /tests/capy-codecs-text.capy)"
set +e
codec_text_trap_output=$(scripts/bearer-cli /tests/capy-codecs-text-trap.capy 2>&1)
codec_text_trap_status=$?
set -e
[[ $codec_text_trap_status -ne 0 && "$codec_text_trap_output" == *"capy-codecs-text-trap.capy:3:2"* ]] || {
echo "Capy malformed XML did not trap at the call site: $codec_text_trap_output" >&2
exit 1
}
crypto_output=$(scripts/bearer-cli /tests/capy-crypto-random.capy)
[[ "$crypto_output" =~ ^a9993e364706816aba3e25717850c26c9cd0d89d\|20\|32\|ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\|32\|6e9ef29b75fffc5b7abae527d58fdadb2fe42e7219011976917343065f58ed4a\|414243\|truefalse\|16\|truefalse\|76\|9546680768582587775\|true\|7\|true\|true\|true\|[0-9]+\|0$ ]] || {
echo "Capy crypto/random adapter mismatch: $crypto_output" >&2
exit 1
}
regex_output=$(scripts/bearer-cli /tests/capy-regex.capy)
[[ "$regex_output" == "true|Capy|4|Capy|3TWO|false|<one> <TWO>|a::b|truetruetruefalse|false|2|:a:b:|0" ]] || {
echo "Capy regex/ARC mismatch: $regex_output" >&2
exit 1
}
for regex_case in \
"capy-regex-trap|could not compile pattern" \
"capy-regex-flag-trap|unknown regex flag 'q'" \
"capy-regex-replace-trap|substitution failed: unknown substring"; do
regex_trap=${regex_case%%|*}
regex_error=${regex_case#*|}
set +e
regex_trap_output=$(scripts/bearer-cli "/tests/$regex_trap.capy" 2>&1)
regex_trap_status=$?
set -e
[[ $regex_trap_status -ne 0 && "$regex_trap_output" == *"$regex_error"* && "$regex_trap_output" == *"$regex_trap.capy:3:8"* ]]
done
expect_equal "regex recovery" "$regex_output" "$(scripts/bearer-cli /tests/capy-regex.capy)"
if compgen -G '/tmp/capy-files-phase-*' >/dev/null || compgen -G '/tmp/capy-files2-*' >/dev/null; then
echo "Capy filesystem fixture left temporary files" >&2
rm -f /tmp/capy-files-phase-* /tmp/capy-files2-*
exit 1
fi
expect_equal "concat-only demand surface" "ab|0" "$(scripts/bearer-cli /tests/capy-string-concat-only.capy)"
expect_equal "zero-argument first" "[]|0" "$(scripts/bearer-cli /tests/capy-first-empty.capy)"
string_list_output=$(scripts/bearer-cli /tests/capy-string-lists.capy)
[[ "$string_list_output" == "a::b:|a,,b,|true|Capy|||Gr:ße||one|value|x-y|[]|[ keep ]|chosen|eplpick|5|0" ]] || {
echo "Capy split/join/ARC mismatch: $string_list_output" >&2
exit 1
}
expect_equal "numeric DValue list join conversion" "1" "$(scripts/bearer-cli /tests/capy-string-list-trap.capy)"
set +e
string_list_trap_output=$(scripts/bearer-cli /tests/capy-string-list-scalar-trap.capy 2>&1)
string_list_trap_status=$?
set -e
[[ $string_list_trap_status -ne 0 && "$string_list_trap_output" == *"capy-string-list-scalar-trap.capy:3:8"* ]]
expect_equal "split/join recovery" "$string_list_output" "$(scripts/bearer-cli /tests/capy-string-lists.capy)"
expect_equal "core utility value adapters" "falsetruefalseBETA,ALPHA,BETA|alpha|beta,alpha|truetrue|alpha|0,1,2|bearer:BEARER|Caffile1:core|0:255:truetrue|1.5:-9:42|truetrue|a=one&b=last&flag=:last:example.test:docs:two|docs/index:true:|one,two,three:A,é:example.test|alpha,beta,beta:true:SIGSEGV:0:true:40|0" "$(scripts/bearer-cli /tests/capy-coreutil.capy)"
set +e
coreutil_trap_output=$(scripts/bearer-cli /tests/capy-coreutil-trap.capy 2>&1)
coreutil_trap_status=$?
set -e
[[ $coreutil_trap_status -ne 0 && "$coreutil_trap_output" == *"capy-coreutil-trap.capy:3:2"* ]] || {
echo "Capy negative usleep did not trap at call site: $coreutil_trap_output" >&2
exit 1
}
string_output=$(scripts/bearer-cli /tests/capy-strings.capy)
[[ "$string_output" == "Capy Bearer|11|truetrue|Bearer|Bearer|Capy:Bearer|5:5:-1|5:-1|Capy Runtime|capy bearer|CAPY BEARER|3|truefalsetrue|3|0" ]] || {
echo "Capy string operations/ARC mismatch: $string_output" >&2
exit 1
}
markup_output=$(scripts/bearer-cli /tests/capy-markup.capy)
[[ "$markup_output" == "once;<p>static</p><main>&lt;side&gt;&lt;&amp;&gt;&quot;&#39;<&>\"'<strong>&lt;&amp;&gt;&quot;&#39;</strong>&lt;i&gt;&amp;lt;&amp;amp;&amp;gt;&amp;quot;&amp;#39;&lt;/i&gt;<aside>-2147483648:0:2147483647:true:false</aside><wide>-9223372036854775808:18446744073709551615:-1.5</wide></main>|-2147483648|0" ]] || {
echo "Capy markup output mismatch: $markup_output" >&2
exit 1
}
context_markup=$(scripts/bearer-cli /tests/capy-markup-context.capy)
[[ "$context_markup" == once\;* && "${context_markup#once;}" != *'once;'* &&
"$context_markup" == *'&lt;once&gt;<p title="&lt;/script&gt;&lt;style&gt;&amp;&quot;&#39;'* &&
"$context_markup" == *'\u003C\/script\u003E'* && "$context_markup" == *'\u000A\u2028\u2029'* &&
"$context_markup" == *'\3C /script\3E '* && "$context_markup" == *'\A \2028 \2029 '* &&
"$context_markup" == *'|0' ]] || {
echo "Contextual markup escaping mismatch: $context_markup" >&2
exit 1
}
loop_control_output=$(scripts/bearer-cli /tests/capy-loop-control.capy)
[[ "$loop_control_output" == "7|owned-return|0|13|0|023|0|ab|0|0002||2022|0" ]] || {
echo "Capy break/continue ARC output mismatch: $loop_control_output" >&2
exit 1
}
closure_output=$(scripts/bearer-cli /tests/capy-closures.capy)
[[ "$closure_output" == "captured:15|2|second:22|2|5|2|second:23|3|temporary:31|3|immediate:42|3|nested:7|3|0" ]] || {
echo "Capy closure output mismatch: $closure_output" >&2
exit 1
}
callable_expected=$'3:12:3:12|{"list": [null, {"closure": null}], "map": {"closure": null, "named": null}}|list:\n - null\n -\n closure: null\nmap:\n closure: null\n named: null\n|<root><list><item/><item><closure/></item></list><map><closure/><named/></map></root>|truetruefalsefalsefalsefalse|2:2:1|true|true|true|true|true'
expect_equal "callable DValue projection, capture, and ARC" "$callable_expected" "$(scripts/bearer-cli /tests/capy-any-callable.capy)"
set +e
callable_signature_output=$(scripts/bearer-cli /tests/capy-any-callable-signature-trap.capy 2>&1)
callable_signature_status=$?
set -e
[[ $callable_signature_status -ne 0 && "$callable_signature_output" == *"capy-any-callable-signature-trap.capy:9:2"* ]] || {
echo "Capy callable DValue signature mismatch did not trap at the extraction" >&2
exit 1
}
expect_equal "callable DValue trap recovery" "$callable_expected" "$(scripts/bearer-cli /tests/capy-any-callable.capy)"
expect_equal "Capy dynamic type and generic marker" "4|7|generic|9" "$(scripts/bearer-cli /tests/capy-generic-dynamic.capy)"
phase3_output=$(scripts/bearer-cli /tests/capy-phase3.capy)
[[ "$phase3_output" == "second|1|0|7|generic|5|fallback|2|name|9pair|2|pair|0|pair|0|pair|3|innerouter|4|temporary|0|nested|0|5-1pair|0|0|falsetrue0|0" ]] || {
echo "Capy generic specialization output mismatch: $phase3_output" >&2
exit 1
}
phase3_cache="$(scripts/unit_cache_directory "$bin_directory")$site_directory/tests/capy-phase3.capy"
wasm-validate "$phase3_cache.wasm"
expect_equal "Capy embedded struct reflection" "MMReflectionValue|s32|[s32]|7|string|ok|7|3|2|ready|9007199254740993|function(s32) s32|8|0|{}|0" "$(scripts/bearer-cli /tests/capy-reflection.capy)"
[[ "$(scripts/bearer-cli /tests/capy-cross.capy)" == "capy-render-ok|counted;roundtripother|1|3|0" ]] || {
echo "Capy Bearer unit dispatch failed" >&2
exit 1
}
[[ "$(scripts/bearer-cli /tests/capy-cross-caller.capy)" == "capy-component-ok|capy-named-ok" ]] || {
echo "Capy component dispatch failed" >&2
exit 1
}
request_component_output=$(scripts/bearer-cli /tests/capy-request-context-caller.capy)
[[ "$request_component_output" == "component-prop|false|0|handle|0" ]] || {
echo "Capy request props snapshot mismatch: $request_component_output" >&2
exit 1
}
component_props_output=$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-component-props.capy?name=FromCapy')
[[ "$component_props_output" == "truefalse|child|false|0|FromCapy|false|0|child|child|2" ]] || {
echo "Capy component props dispatch mismatch: $component_props_output" >&2
exit 1
}
component_trap_body=$(mktemp)
component_trap_status=$(curl -sS --max-time 30 -o "$component_trap_body" -w '%{http_code}' -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-component-props.capy?name=FromCapy&trap=1')
[[ "$component_trap_status" == "500" ]] && ! grep -q 'must-not-leak' "$component_trap_body"
rm -f "$component_trap_body"
[[ "$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-component-props.capy?name=Recovered')" == "truefalse|child|false|0|Recovered|false|0|child|child|2" ]]
(
component_cache_dir=$(mktemp -d "$site_directory/tests/capy-component-cache.XXXXXX")
chmod 755 "$component_cache_dir"
trap 'rm -rf -- "$component_cache_dir"' EXIT
component_cache_name=${component_cache_dir##*/}
cat >"$component_cache_dir/parent.capy" <<'EOF'
function RENDER(request : any) {
print(length(component_resolve("child")) > 0)
}
EOF
printf '%s\n' 'function COMPONENT(request : any) { print("child") }' >"$component_cache_dir/child.capy"
expect_equal "Capy warm component resolution" "true" "$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' "http://127.0.0.1/tests/$component_cache_name/parent.capy")"
rm "$component_cache_dir/child.capy"
expect_equal "Capy deleted component rejection" "false" "$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' "http://127.0.0.1/tests/$component_cache_name/parent.capy")"
printf '%s\n' 'function COMPONENT(request : any) { print("child") }' >"$component_cache_dir/child.capy"
expect_equal "Capy component resolution recovery" "true" "$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' "http://127.0.0.1/tests/$component_cache_name/parent.capy")"
)
(
settings=/etc/bearer/settings.cfg
settings_backup=$(mktemp)
cp --preserve=mode,ownership,timestamps "$settings" "$settings_backup"
compile_error_dir=$(mktemp -d "$site_directory/tests/capy-component-compile-error.XXXXXX")
chmod 755 "$compile_error_dir"
compile_error_name=${compile_error_dir##*/}
compile_error_artifact_dir="$(scripts/unit_cache_directory "$bin_directory")$compile_error_dir"
compile_error_body=$(mktemp)
wait_for_bearer() {
local code
for _ in $(seq 1 60); do
code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 2 -H 'Host: bearer.openfu.com' http://127.0.0.1/info/ || true)
[[ "$code" == "200" ]] && return 0
sleep 1
done
return 1
}
restart_bearer() {
systemctl restart bearer.service
wait_for_bearer
}
cleanup_compile_error_test() {
cp --preserve=mode,ownership,timestamps "$settings_backup" "$settings"
rm -f "$settings_backup" "$compile_error_body"
rm -rf -- "$compile_error_dir" "$compile_error_artifact_dir"
restart_bearer
}
trap cleanup_compile_error_test EXIT
cat >"$compile_error_dir/parent.capy" <<'EOF'
function RENDER(request : any) {
print(component("child.capy"))
}
EOF
printf '%s\n' 'function COMPONENT(request : any) { print(not_a_constant) }' >"$compile_error_dir/child.capy"
child_path=$(realpath "$compile_error_dir/child.capy")
sed -i \
-e 's#^page_runtime_error=.*#page_runtime_error=site/errors/runtime-error.capy#' \
-e 's/^SHOW_DYNAMIC_COMPILE_ERRORS=.*/SHOW_DYNAMIC_COMPILE_ERRORS=1/' "$settings"
restart_bearer
compile_error_status=$(curl -sS --max-time 30 -o "$compile_error_body" -w '%{http_code}' -H 'Host: bearer.openfu.com' \
"http://127.0.0.1/tests/$compile_error_name/parent.capy")
[[ "$compile_error_status" == "500" && -s "$compile_error_body" ]]
grep -Fq "$child_path" "$compile_error_body"
grep -Fq "unknown local" "$compile_error_body"
sed -i 's/^SHOW_DYNAMIC_COMPILE_ERRORS=.*/SHOW_DYNAMIC_COMPILE_ERRORS=0/' "$settings"
restart_bearer
compile_error_status=$(curl -sS --max-time 30 -o "$compile_error_body" -w '%{http_code}' -H 'Host: bearer.openfu.com' \
"http://127.0.0.1/tests/$compile_error_name/parent.capy")
[[ "$compile_error_status" == "500" && -s "$compile_error_body" ]]
grep -Fq "$child_path" "$compile_error_body"
! grep -Fq "unknown local" "$compile_error_body"
)
request_headers=$(mktemp)
request_http_output=$(curl -fsS --max-time 30 -D "$request_headers" -H 'Host: bearer.openfu.com' -H 'X-Capy-Schema: yes' -d 'answer=42' 'http://127.0.0.1/tests/capy-request-context.capy?name=Ada')
[[ "$request_http_output" == "POST|Ada|42|answer=42|0" ]] || {
echo "Capy HTTP request snapshot mismatch: $request_http_output" >&2
exit 1
}
grep -Eq '^HTTP/1\.[01] 201 ' "$request_headers"
grep -Eqi '^X-Capy-Context: yes' "$request_headers"
grep -Eqi '^X-Capy-Clean: first X-Injected: bad' "$request_headers"
! grep -Eqi '^X-Injected:' "$request_headers"
rm -f "$request_headers"
upload_file=$(mktemp --suffix=-request-upload.txt)
printf 'data' >"$upload_file"
upload_output=$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' -F before=1 -F "upload=@$upload_file;filename=request-upload.txt" -F after=2 -F "second=@$upload_file;filename=second.txt" 'http://127.0.0.1/tests/capy-request-context.capy?upload=1')
rm -f "$upload_file"
[[ "$upload_output" == "request-upload.txt|true|true|upload|1|2|2" ]] || {
echo "Capy upload snapshot mismatch: $upload_output" >&2
exit 1
}
request_http_second=$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' -H 'X-Capy-Schema: yes' -d 'answer=7' 'http://127.0.0.1/tests/capy-request-context.capy?name=Grace')
[[ "$request_http_second" == "POST|Grace|7|answer=7|0" ]] || {
echo "Capy request isolation mismatch: $request_http_second" >&2
exit 1
}
expect_equal "kv cache stores, counts, caches, and refuses oversized values" "fresh|4231|53|2048|truefalse|false|none|true" "$(scripts/bearer-cli /tests/capy-kv.capy)"
expect_equal "kv cache is shared across requests" "shared|4230|86|2048|truefalse|false|none|true" "$(scripts/bearer-cli /tests/capy-kv.capy)"
expect_equal "kv cache clears" "cleared" "$(scripts/bearer-cli --get /tests/capy-kv.capy mode=clear)"
expect_equal "clone copies arrays and structs deeply" "19|bz|1ada17|2grace28|13|0" "$(scripts/bearer-cli /tests/capy-clone.capy)"
expect_equal "an any is one object under every name" "Grace|loop@example.test|2|loop@example.test|Copy|copy@example.test|guest|0" "$(scripts/bearer-cli /tests/capy-any-shared.capy)"
expect_equal "current_request shares the handler value with exported functions" "Hello, Ada|true|Hello, Ada|0" "$(scripts/bearer-cli /tests/capy-current-request.capy)"
request_writeback_headers=$(mktemp)
request_writeback_output=$(curl -fsS --max-time 30 -D "$request_writeback_headers" -H 'Host: bearer.openfu.com' -d 'value=form' 'http://127.0.0.1/tests/capy-request-writeback.capy?value=query')
expect_equal "Capy shared request identity and write-back" "form|Ada|404|pending|1|component|inner|2" "$request_writeback_output"
grep -Eq '^HTTP/1\.[01] 203 ' "$request_writeback_headers"
grep -Eqi '^X-Capy-Phase5: inner' "$request_writeback_headers"
grep -Eqi '^X-Capy-Parent: pending' "$request_writeback_headers"
grep -Eiq '^Set-Cookie: capy-parent=pending(;|$)' "$request_writeback_headers"
grep -Eiq '^Set-Cookie: capy-phase5=cookie(;|$)' "$request_writeback_headers"
rm -f "$request_writeback_headers"
response_trap_body=$(mktemp)
response_trap_status=$(curl -sS --max-time 30 -o "$response_trap_body" -w '%{http_code}' -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-response-header-trap.capy)
rm -f "$response_trap_body"
[[ "$response_trap_status" == "500" ]] || {
echo "Capy malformed response header did not fail: HTTP $response_trap_status" >&2
exit 1
}
status_trap_body=$(mktemp)
status_trap_status=$(curl -sS --max-time 30 -o "$status_trap_body" -w '%{http_code}' -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-response-status-trap.capy)
rm -f "$status_trap_body"
[[ "$status_trap_status" == "500" ]] || {
echo "Capy invalid response status did not fail: HTTP $status_trap_status" >&2
exit 1
}
expect_equal "typed response status" "202" "$(curl -sS --max-time 30 -o /dev/null -w '%{http_code}' -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-response-status-typed.capy)"
expect_equal "response status recovers after a native failure" "recovered" "$(scripts/bearer-cli /tests/capy-response-recover.capy)"
expect_equal "request/response stdlib CLI" "Ada|Ada|inner|outer+inner|index|workspace/projectstruetrue|truetruetrue|true|0" "$(scripts/bearer-cli /tests/capy-request-parity.capy name=Ada)"
request_parity_headers=$(mktemp)
request_parity_output=$(curl -fsS --max-time 30 -D "$request_parity_headers" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-request-parity.capy?workspace/projects&name=Grace&status=yes')
[[ "$request_parity_output" == "Grace|Grace|inner|outer+inner|workspace/projects|workspace/projectstruetrue|truetruetrue|true|0" ]]
grep -Eq '^HTTP/1\.[01] 202 Accepted' "$request_parity_headers"
rm -f "$request_parity_headers"
session_replacement_headers=$(mktemp)
[[ "$(curl -fsS --max-time 30 -D "$session_replacement_headers" -b 'capy-session=not-a-session' -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-session.capy?action=read')" == "missing||1" ]]
grep -Eiq '^Set-Cookie: capy-session=[0-9a-f]{64}.*HttpOnly.*SameSite=Lax' "$session_replacement_headers"
rm -f "$session_replacement_headers"
session_jar=$(mktemp)
session_headers=$(mktemp)
[[ "$(curl -fsS --max-time 30 -D "$session_headers" -c "$session_jar" -b "$session_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-session.capy?action=set&value=Ada')" == "set" ]]
grep -Eiq '^Set-Cookie: capy-session=.*HttpOnly.*SameSite=Lax' "$session_headers"
grep -Eiq '^Set-Cookie: capy-extra=yes.*HttpOnly.*SameSite=Lax' "$session_headers"
[[ "$(curl -fsS --max-time 30 -c "$session_jar" -b "$session_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-session.capy?action=read')" == "Ada|yes|1" ]]
[[ "$(curl -fsS --max-time 30 -c "$session_jar" -b "$session_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-session.capy?action=remove')" == "removed" ]]
[[ "$(curl -fsS --max-time 30 -c "$session_jar" -b "$session_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-session.capy?action=read')" == "missing|yes|1" ]]
[[ "$(curl -fsS --max-time 30 -c "$session_jar" -b "$session_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-session.capy?action=set&value=Grace')" == "set" ]]
[[ "$(curl -fsS --max-time 30 -c "$session_jar" -b "$session_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-session.capy?action=destroy')" == "destroyed" ]]
[[ "$(curl -fsS --max-time 30 -c "$session_jar" -b "$session_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-session.capy?action=read')" == "missing|yes|1" ]]
rm -f "$session_jar" "$session_headers"
redirect_headers=$(mktemp)
redirect_body=$(curl -sS --max-time 30 -D "$redirect_headers" -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-redirect.capy)
grep -Eq '^HTTP/1\.[01] 302 ' "$redirect_headers"
grep -Eqi '^Location: /tests/capy-session.capy\?action=read' "$redirect_headers"
[[ "$redirect_body" == "redirected" ]]
rm -f "$redirect_headers"
csrf_jar=$(mktemp)
csrf_token=$(curl -fsS --max-time 30 -c "$csrf_jar" -b "$csrf_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-csrf.capy?action=token')
[[ "$csrf_token" =~ ^[0-9a-f]{64}$ ]]
[[ "$(curl -fsS --max-time 30 -c "$csrf_jar" -b "$csrf_jar" -H 'Host: bearer.openfu.com' "http://127.0.0.1/tests/capy-csrf.capy?action=valid&submitted=$csrf_token")" == "true" ]]
[[ "$(curl -fsS --max-time 30 -c "$csrf_jar" -b "$csrf_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-csrf.capy?action=valid&submitted=wrong')" == "false" ]]
csrf_rotated=$(curl -fsS --max-time 30 -c "$csrf_jar" -b "$csrf_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-csrf.capy?action=rotate')
[[ "$csrf_rotated" =~ ^[0-9a-f]{64}$ && "$csrf_rotated" != "$csrf_token" ]]
[[ "$(curl -fsS --max-time 30 -c "$csrf_jar" -b "$csrf_jar" -H 'Host: bearer.openfu.com' "http://127.0.0.1/tests/capy-csrf.capy?action=valid&submitted=$csrf_token")" == "false" ]]
[[ "$(curl -fsS --max-time 30 -c "$csrf_jar" -b "$csrf_jar" -H 'Host: bearer.openfu.com' "http://127.0.0.1/tests/capy-csrf.capy?action=valid&submitted=$csrf_rotated")" == "true" ]]
[[ "$(curl -fsS --max-time 30 -c "$csrf_jar" -b "$csrf_jar" -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-csrf.capy?action=field')" == "<input type=\"hidden\" name=\"submitted\" value=\"$csrf_rotated\">" ]]
rm -f "$csrf_jar"
websocket_test=$(mktemp)
trap 'rm -f "$websocket_test"' RETURN
clang++ -std=c++20 -Wall -Wextra -Werror -pedantic scripts/test_capy_websocket.cpp -o "$websocket_test"
"$websocket_test"
rm -f "$websocket_test"
expect_equal "SERVE_HTTP caller" "serve-ok" "$(scripts/bearer-cli /tests/capy-serve-http-caller.capy)"
rich_dval_output=$(scripts/bearer-cli /tests/capy-any-rich.capy)
[[ "$rich_dval_output" == "capy|Ada|9|custom-once;capy|capy|true|Ada|42|true|logic|truefalse|4|active;age;name;tags;|0=math;1=logic;|2;|4|0|falsefalse|2|0" ]] || {
echo "Capy rich DValue output mismatch: $rich_dval_output" >&2
exit 1
}
[[ "$(scripts/bearer-cli /tests/capy-any-rich-caller.capy)" == "custom-once;capy|Capy|roundtrip|3|true" ]] || {
echo "Capy-to-Capy custom DValue export failed" >&2
exit 1
}
none_output=$(scripts/bearer-cli /tests/capy-any-none.capy)
expect_equal "DValue none, safe read, conversion, codec, path update, and ARC contract" \
"false|true|true|true|true|false|false|false|false|false|true|false|Ada|[][string]|false|true|0|32|0|-64|0|64|0|6.5|false|false|false|null|true|false|true|false|false|created|replaced|old|kept|updated|changed|changed|ABR|done|false|0|&lt;Ada&gt;::|0" "$none_output"
[[ "$(scripts/bearer-cli /tests/capy-any-rich.capy)" == "$rich_dval_output" ]] || {
echo "Capy DValue workspace did not reset after strict trap" >&2
exit 1
}
for fixture_and_location in \
"capy-any-assign-list-trap:4:12"; do
fixture=${fixture_and_location%%:*}
location=${fixture_and_location#*:}
set +e
assignment_trap_output=$(scripts/bearer-cli "/tests/$fixture.capy" 2>&1)
assignment_trap_status=$?
set -e
[[ $assignment_trap_status -ne 0 && "$assignment_trap_output" == *"$fixture.capy:$location"* && "$assignment_trap_output" != *"capy://stdlib.capy"* ]] || {
echo "Capy nested DValue assignment trap/source mapping mismatch: fixture=$fixture output=$assignment_trap_output" >&2
exit 1
}
expect_equal "DValue none recovery after $fixture" "$none_output" "$(scripts/bearer-cli /tests/capy-any-none.capy)"
done
arc_output=$(scripts/bearer-cli /tests/capy-arc.capy)
expected_arc='first|0|alphaalpha|1|1|1|789|1|8|2|4|1|12|3|ownedtwo|4|temp|1|picked|1|4|2|pair42|3|pair|6|inside|9|field|1|betaalpha|2|betaalphaalphabeta|3|tempz|4|double|5|nested|6|5|0'
[[ "$arc_output" == "$expected_arc" ]] || {
echo "Capy ARC ownership output mismatch: $arc_output" >&2
exit 1
}
arc_cache="$(scripts/unit_cache_directory "$bin_directory")$site_directory/tests/capy-arc.capy"
wasm-validate "$arc_cache.wasm"
wasm-objdump -x "$arc_cache.wasm" >"$arc_cache.objdump"
grep -q 'env.bearer_alloc' "$arc_cache.objdump"
grep -q 'env.bearer_free' "$arc_cache.objdump"
grep -Eq 'mem_p2align *: 3' "$arc_cache.objdump"
rm -f "$arc_cache.objdump"
set +e
trap_output=$(scripts/bearer-cli /tests/capy-arc-trap.capy 2>&1)
trap_status=$?
set -e
[[ $trap_status -ne 0 && "$trap_output" == *'wasm `unreachable` instruction executed'* && "$trap_output" == *'capy-arc-trap.capy'* ]] || {
echo "Capy ARC trap containment did not produce a source-associated trap" >&2
echo "$trap_output" >&2
exit 1
}
[[ "$(scripts/bearer-cli /tests/capy-arc.capy)" == "$expected_arc" ]] || {
echo "Capy ARC workspace did not reset after a trapping request" >&2
exit 1
}
for array_trap in capy-array-trap capy-array-negative-trap; do
set +e
array_trap_output=$(scripts/bearer-cli "/tests/$array_trap.capy" 2>&1)
array_trap_status=$?
set -e
[[ $array_trap_status -ne 0 && "$array_trap_output" == *"$array_trap.capy:3:11"* ]] || {
echo "Capy array bounds trap/source mapping mismatch: fixture=$array_trap status=$array_trap_status output=$array_trap_output" >&2
exit 1
}
[[ "$(scripts/bearer-cli /tests/capy-arc.capy)" == "$expected_arc" ]] || {
echo "Capy ARC workspace did not reset after array bounds trap $array_trap" >&2
exit 1
}
done
render_output=$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-render.capy)
[[ "$render_output" == "capy-render-ok" ]] || {
echo "Capy HTTP RENDER output mismatch: $render_output" >&2
exit 1
}
cache="$(scripts/unit_cache_directory "$bin_directory")$site_directory/tests/capy-phase1.capy"
[[ -s "$cache.wasm" && -s "$cache.cwasm" && -s "$cache.cwasm.manifest" && -s "$cache.wasm.source-map" && -s "$cache.meta.txt" ]]
[[ $(sed -n '1p' "$cache.cwasm.manifest") == "$(sha256sum "$cache.wasm" | awk '{print $1}')" ]]
[[ $(sed -n '2p' "$cache.cwasm.manifest") == "$(sha256sum "$cache.cwasm" | awk '{print $1}')" ]]
grep -qx 'format=bearer-unit-metadata-v3' "$cache.meta.txt"
grep -Eq '^source_map_sha256=[0-9a-f]{64}$' "$cache.meta.txt"
grep -qx "wasm_core_abi_version=$(awk '/BEARER_WASM_CORE_ABI_VERSION/ {print $3; exit}' src/wasm/abi.h)" "$cache.meta.txt"
grep -qx "wasm_sha256=$(sha256sum "$cache.wasm" | awk '{print $1}')" "$cache.meta.txt"
grep -qx "exports_sha256=$(sha256sum "$cache.exports.txt" | awk '{print $1}')" "$cache.meta.txt"
bin/capyc --check-unit "$cache.wasm" "$(awk '/BEARER_WASM_CORE_ABI_VERSION/ {print $3; exit}' src/wasm/abi.h)"
wasm-objdump -x "$cache.wasm" >"$cache.objdump"
grep -q 'env.bearer_print_bytes' "$cache.objdump"
grep -q '__bearer_cli' "$cache.objdump"
grep -Eq 'mem_p2align *: 3' "$cache.objdump"
! grep -q 'wasi_snapshot_preview1' "$cache.objdump"
rm -f "$cache.objdump"
fixture="capy-compile-recovery-$$"
source_dir="$site_directory/$fixture"
artifact_dir="$(scripts/unit_cache_directory "$bin_directory")$source_dir"
cleanup() {
rm -rf "$source_dir" "$artifact_dir"
}
trap cleanup EXIT
mkdir -p "$source_dir"
for size in 63 64 127 128; do
payload=$(printf '%*s' "$size" '' | tr ' ' x)
printf 'function CLI(request : any) { print("%s") }\n' "$payload" >"$source_dir/entry.capy"
expect_equal "signed-LEB output boundary ($size bytes)" "$payload" "$(scripts/bearer-cli "/$fixture/entry.capy")"
done
render_prefix=$(printf '%*s' 64 '' | tr ' ' r)
printf 'function RENDER(request : any) { print("%s") }\nfunction CLI(request : any) { print("offset-ok") }\n' "$render_prefix" >"$source_dir/entry.capy"
expect_equal "source-map offset runtime" "offset-ok" "$(scripts/bearer-cli "/$fixture/entry.capy")"
printf '%s\n' 'function CLI(request : any) { print(not_a_constant) }' >"$source_dir/entry.capy"
set +e
failure=$(scripts/bearer-cli "/$fixture/entry.capy" 2>&1)
status=$?
set -e
[[ $status -ne 0 ]]
[[ "$failure" == *"entry.capy:1:"* && "$failure" == *"unknown local 'not_a_constant'"* ]]
[[ ! -e "$artifact_dir/entry.capy.wasm" ]]
printf '%s\n' 'function CLI(request : any) { print("capy-recovered") }' >"$source_dir/entry.capy"
expect_equal "source-map trap recovery" "capy-recovered" "$(scripts/bearer-cli "/$fixture/entry.capy")"
[[ -s "$artifact_dir/entry.capy.wasm" ]]
expect_equal "network socket/hardened HTTP adapters" "true|true|true|200|invalid_request|4" "$(scripts/bearer-cli /tests/capy-network-parity.capy)"
bash scripts/test_php_interop.sh site/tests/capy-php-interop.capy
expect_equal "time adapters" "5|0|981158400|0|0|1970|true|true|0" "$(scripts/bearer-cli /tests/capy-time-parity.capy)"
lifecycle_output=$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-lifecycle-parity.capy)
expect_equal "INIT/ONCE lifecycle" "entry-init;entry-once;child-init;child-once;child-component;child-component;render" "$lifecycle_output"
expect_equal "INIT/ONCE lifecycle in a later request workspace" \
"entry-init;entry-once;child-init;child-once;child-component;child-component;render" \
"$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-lifecycle-parity.capy)"
component_parity_output=$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' http://127.0.0.1/tests/capy-component-parity.capy)
expect_equal "component/unit DValue conversions" "Capy|false|0|child|false|0|scalar|render|unit|true" "$component_parity_output"
expect_equal "general methods receiver order/overload/generic/local shadow/function fields" "receiver;argument;method;10|s32|string|9|shadow;5|field;5|extension;6" "$(scripts/bearer-cli /tests/capy-methods.capy)"
module_output=$(scripts/bearer-cli /tests/capy-module-caller.capy)
expect_equal "Capy module capability/default input/nested BRRB/legacy/none/copied identity/handler/ARC" "counted;handler-once;handler-render;default|nested|once|capy|legacy|false|resultresult|{}|{}|0" "$module_output"
# An absolute #import is a web path under the site root, resolved the same way
# unit_call() and component() resolve one. These units are temporary because the
# artifact-golden gate compiles every tracked site/tests unit without a
# --source-root, where a web path cannot resolve.
(
absolute_import=$(mktemp "$site_directory/tests/capy-absolute-import.XXXXXX")
rm -f "$absolute_import"
absolute_import="$absolute_import.capy"
trap 'rm -f -- "$absolute_import"' EXIT
cat >"$absolute_import" <<'UNIT'
#import "/tests/capy-unit-reference-target.capy" as target
function CLI(request : any) {
var profile : target.Profile = target.Profile("absolute")
print(string(target.current_user({scope: "web-path"}).scope), "|", profile.name)
}
UNIT
expect_equal "absolute #import resolves under the site root" "web-path|absolute" \
"$(scripts/bearer-cli "/tests/$(basename "$absolute_import")")"
)
expect_equal "unit reference forms: compound target/#import alias/imported struct" \
"legacy3|none|compound|none|ref-once;ref-render;|props|Ada|none|struct|{\"bool\": true, \"raw\": true, \"string\": \"true\"}" \
"$(scripts/bearer-cli /tests/capy-unit-reference.capy)"
module_exports="$(scripts/unit_cache_directory "$bin_directory")$site_directory/tests/capy-module-target.capy.exports.txt"
grep -qx 'DValue\* echo(DValue\*);' "$module_exports"
grep -qx 'DValue\* counted(DValue\*);' "$module_exports"
grep -qx 'capy function echo(any):any' "$module_exports"
(
metadata_dir=$(mktemp -d "$site_directory/tests/capy-export-metadata.XXXXXX")
trap 'rm -rf -- "$metadata_dir"' EXIT
metadata_name=${metadata_dir##*/}
cat >"$metadata_dir/provider.capy" <<'EOF'
#exports echo, Shape, ShapeAlias
struct Shape { value : s32 }
type ShapeAlias = Shape
function echo(input : any) any { -> input }
function Shape(input : any) Shape { -> Shape(1) }
EOF
cat >"$metadata_dir/reader.capy" <<'EOF'
function CLI(request : any) {
unit_compile("provider.capy")
var info := unit_info("provider.capy")
print(string(info.function_exports["0"]), "|", string(info.function_exports["1"]), "|", string(info.type_exports["0"]), "|", string(info.type_exports["1"]))
}
EOF
cat >"$metadata_dir/importer.capy" <<'EOF'
#import"provider.capy" as provider
type ImportedShape = provider.Shape
type ImportedAlias = provider.ShapeAlias
function CLI(request : any) {
print("imported")
}
EOF
expect_equal "Capy #exports function and type metadata" "echo|Shape|struct Shape{value:s32}|alias ShapeAlias=struct:Shape" "$(scripts/bearer-cli "/tests/$metadata_name/reader.capy")"
expect_equal "Capy #import type metadata" "imported" "$(scripts/bearer-cli "/tests/$metadata_name/importer.capy")"
printf '%s\n' '#exports Shape' 'struct Shape { value : MissingType }' >"$metadata_dir/provider.capy"
set +e
import_failure=$(scripts/bearer-cli "/tests/$metadata_name/importer.capy" 2>&1)
import_status=$?
set -e
[[ $import_status -ne 0 && "$import_failure" == *"#import failed to compile"* ]] || {
echo "Capy #import dependency invalidation did not reject a broken provider: $import_failure" >&2
exit 1
}
cat >"$metadata_dir/provider.capy" <<'EOF'
#exports echo, Shape, ShapeAlias
struct Shape { value : s32 }
type ShapeAlias = Shape
function echo(input : any) any { -> input }
function Shape(input : any) Shape { -> Shape(1) }
EOF
expect_equal "Capy #import recovery" "imported" "$(scripts/bearer-cli "/tests/$metadata_name/importer.capy")"
cat >"$metadata_dir/cycle-a.capy" <<'EOF'
#import"cycle-b.capy" as b
type A = b.B
function CLI(request : any) { print("bad") }
EOF
cat >"$metadata_dir/cycle-b.capy" <<'EOF'
#import"cycle-a.capy" as a
type B = a.A
EOF
set +e
cycle_failure=$(scripts/bearer-cli "/tests/$metadata_name/cycle-a.capy" 2>&1)
cycle_status=$?
set -e
[[ $cycle_status -ne 0 && "$cycle_failure" == *"#import dependency cycle"* ]] || {
echo "Capy #import cycle was not rejected: $cycle_failure" >&2
exit 1
}
)
(
module_test_dir=$(mktemp -d "$site_directory/tests/capy-module-trap.XXXXXX")
trap 'rm -rf -- "$module_test_dir"' EXIT
module_test_name=${module_test_dir##*/}
check_module_trap() {
local name=$1 source=$2
printf '%s\n' "$source" >"$module_test_dir/caller.capy"
set +e
local output
output=$(scripts/bearer-cli "/tests/$module_test_name/caller.capy" 2>&1)
local status=$?
set -e
[[ $status -ne 0 && "$output" == *"BEARER_MODULE_"* && "$output" == *"caller.capy:"* && "$output" != *"capy://stdlib.capy"* ]] || {
echo "Capy module $name trap/source mapping mismatch: $output" >&2
exit 1
}
expect_equal "Capy module $name recovery" "counted;handler-once;handler-render;default|nested|once|capy|legacy|false|resultresult|{}|{}|0" "$(scripts/bearer-cli /tests/capy-module-caller.capy)"
}
check_module_trap missing 'function CLI(request : any) { var module := unit_load("missing.capy") }'
check_module_trap unauthorized 'function CLI(request : any) { var module := unit_load("/etc/passwd") }'
check_module_trap undeclared $'function CLI(request : any) {\n unit_call("/tests/capy-module-target.capy:hidden", "")\n}'
check_module_trap wrong_target $'function CLI(request : any) {\n var module := unit_load("/tests/capy-module-caller.capy")\n module.call("CLI")\n}'
external_unit=$(mktemp /tmp/capy-module-external.XXXXXX.capy)
trap 'rm -f -- "$external_unit"; rm -rf -- "$module_test_dir"' EXIT
printf '%s\n' '#exports echo' 'function echo(input : any) any { -> any("external") }' >"$external_unit"
check_module_trap external_source "function CLI(request : any) { var module := unit_load(\"$external_unit\"); print(string(module.call(\"echo\"))) }"
ln -s "$external_unit" "$module_test_dir/escape.capy"
check_module_trap source_symlink 'function CLI(request : any) { var module := unit_load("escape.capy"); print(string(module.call("echo"))) }'
printf '%s\n' 'function CLI(request : any) { print(not_a_constant) }' >"$module_test_dir/broken.capy"
check_module_trap failed_compile 'function CLI(request : any) { var module := unit_load("broken.capy") }'
printf '%s\n' '#exports echo' 'function echo(input : any) any { -> any("v1") }' >"$module_test_dir/target.capy"
cat >"$module_test_dir/pinned.capy" <<'EOF'
function CLI(request : any) {
var module := unit_load("target.capy")
file_put_contents("target.capy", "#exports echo\nfunction echo(input : any) any { -> any(\"v2\") }\n")
print(string(module.call("echo", "")))
}
EOF
printf '%s\n' 'function CLI(request : any) { print(string(unit_load("target.capy").call("echo", ""))) }' >"$module_test_dir/fresh.capy"
expect_equal "Capy module request pin" "v1" "$(scripts/bearer-cli "/tests/$module_test_name/pinned.capy")"
expect_equal "Capy module next-request reload" "v2" "$(scripts/bearer-cli "/tests/$module_test_name/fresh.capy")"
printf '%s\n' 'function CLI(request : any) { print(not_a_constant) }' >"$module_test_dir/target.capy"
check_module_trap failed_reload_compile 'function CLI(request : any) { var module := unit_load("target.capy") }'
printf '%s\n' '#exports echo' 'function echo(input : any) any { -> any("v3") }' >"$module_test_dir/target.capy"
expect_equal "Capy module failed-compile recovery" "v3" "$(scripts/bearer-cli "/tests/$module_test_name/fresh.capy")"
module_artifacts="$(scripts/unit_cache_directory "$bin_directory")$module_test_dir/target.capy"
printf '\377' | dd of="$module_artifacts.wasm" bs=1 seek=8 conv=notrunc status=none
check_module_trap wasm_tamper 'function CLI(request : any) { unit_call("target.capy:echo", "") }'
printf '%s\n' 'DValue* echo(DValue*);' 'not an export declaration' >"$module_artifacts.exports.txt"
check_module_trap exports_tamper 'function CLI(request : any) { unit_call("target.capy:echo", "") }'
sed -i 's/^wasm_sha256=.*/wasm_sha256=0000000000000000000000000000000000000000000000000000000000000000/' "$module_artifacts.meta.txt"
check_module_trap metadata_tamper 'function CLI(request : any) { unit_call("target.capy:echo", "") }'
printf '%s\n' '#exports echo, nested, file_relative, boom' \
'function echo(input : any) any { -> any("v4") }' \
'function nested(input : any) any { -> unit_load("nested.capy").call("echo", input) }' \
'function file_relative(input : any) any { -> any(file_get_contents("marker.txt")) }' \
'function boom(input : any) any { trap(); -> any("") }' >"$module_test_dir/target.capy"
printf '%s\n' '#exports echo' 'function echo(input : any) any { -> any("nested") }' >"$module_test_dir/nested.capy"
printf '%s' 'target-file' >"$module_test_dir/marker.txt"
cat >"$module_test_dir/provenance.capy" <<'EOF'
function CLI(request : any) {
var target := unit_load("target.capy")
print(string(target.call("nested", "")), "|", string(target.call("file_relative", "")))
}
EOF
expect_equal "Capy module target provenance" "nested|target-file" "$(scripts/bearer-cli "/tests/$module_test_name/provenance.capy")"
printf '%s\n' 'function CLI(request : any) {' ' unit_load("target.capy").call("boom", "")' '}' >"$module_test_dir/caller.capy"
set +e
target_trap_output=$(scripts/bearer-cli "/tests/$module_test_name/caller.capy" 2>&1)
target_trap_status=$?
set -e
[[ $target_trap_status -ne 0 && "$target_trap_output" == *"caller.capy:2:29"* && "$target_trap_output" != *"capy://stdlib.capy"* ]] || {
echo "Capy module target trap/source map mismatch: $target_trap_output" >&2
exit 1
}
expect_equal "Capy module trap reset recovery" "nested|target-file" "$(scripts/bearer-cli "/tests/$module_test_name/provenance.capy")"
)
echo "Capy phase 1 parser/direct-Wasm/CLI smoke passed"