#!/bin/bash # # signature_test.sh — one klammer, one interface (engine suite, tst/). # # A klammer may be defined separately for each target. When it is, every # target's definition carries its own parameter list, and those lists must # agree: a klammer's interface is a property of the KLAMMER, not of the # target it is being rendered to. If they disagree, the same document would # bind arguments differently — or fail — depending only on the target, which # is exactly the thing an author must be able to rely on not happening. # # The engine enforces this rather than warning about it, and the remedy it # names is the .k declaration: declare the parameters once, and give each # target a "::" instance with no parameter list of its own. That is the # migration from repeating an argument list per target to declaring it once. # # These are engine tests, so they use -k none and define their own targets # inline: a target is a Machine construct (@@@target), not owned by any # klammer set. # # Usage: ./signature_test.sh (needs KLAMMERTEXT_HOME set; ktext on PATH) # Exit code: 0 if all tests pass, 1 otherwise. PASS=0 FAIL=0 KTEXT=ktext K=${KLAMMERTEXT_HOME:?KLAMMERTEXT_HOME must be set} red=$'\033[31m' green=$'\033[32m' bold=$'\033[1m' reset=$'\033[0m' pass() { echo "${green}PASS${reset} $1"; PASS=$((PASS+1)); } fail() { echo "${red}FAIL${reset} $1" echo " expected: $2" echo " got: $3" FAIL=$((FAIL+1)) } TARGETS='@@@target ta | Target A @@@ @@@target tb | Target B @@@ ' # accepted NAME SRC — the definitions are consistent and the klammer applies. accepted() { local name="$1" src="$2" out out=$("$KTEXT" -k none -s "$TARGETS$src" -t ta -d 2>&1) if echo "$out" | grep -qi "error"; then fail "$name" "no error" "$(echo "$out" | grep -i -A1 error | tail -1)" else pass "$name" fi } # rejected NAME SRC PATTERN — the drift is caught, and the message says how. rejected() { local name="$1" src="$2" want="$3" out out=$("$KTEXT" -k none -s "$TARGETS$src" -t ta -d 2>&1) if ! echo "$out" | grep -qi "error"; then fail "$name" "a definition error" "accepted" elif ! echo "$out" | grep -qF "$want"; then fail "$name" "message containing: $want" "$(echo "$out" | head -6 | tail -3)" else pass "$name" fi } echo "${bold}Klammer signature consistency${reset}" echo "=============================" echo accepted " 1. identical parameter lists" \ '@@k1.ta s :n : [*s*] @@ @@k1.tb s :n : [*s*] @@ @k1 x @' rejected " 2. positional names differ" \ '@@k2.ta s : [*s*] @@ @@k2.tb t : [*t*] @@ @k2 x @' 'are not the same for every target' rejected " 3. option names differ" \ '@@k3.ta s :one : [*s*] @@ @@k3.tb s :two : [*s*] @@ @k3 x @' 'are not the same for every target' rejected " 4. defaults differ" \ '@@k4.ta s :n abc : [*s*] @@ @@k4.tb s :n xyz : [*s*] @@ @k4 x @' 'are not the same for every target' rejected " 5. argument types differ" \ '@@k5.ta s :n.int : [*s*] @@ @@k5.tb s :n.word : [*s*] @@ @k5 x @' 'are not the same for every target' echo echo "-- the message must show HOW they differ, not just where" # With more than two targets the designer would otherwise have to diff the # definitions by hand; each target's own signature is listed beside its name. name=" 6. each target's signature is shown" out=$("$KTEXT" -k none -s "$TARGETS"'@@k6.ta s :one : [*s*] @@ @@k6.tb s :two : [*s*] @@ @k6 x @' -t ta -d 2>&1) if echo "$out" | grep -q "ta .*s :one" && echo "$out" | grep -q "tb .*s :two"; then pass "$name" else fail "$name" "both signatures listed by target" "$(echo "$out" | head -8 | tail -4)" fi # The error path once printed internal katom detail through msg(), which is # debugging scaffolding and must never reach a user-facing message. name=" 7. no internal debug output on the error path" out=$("$KTEXT" -k none -s "$TARGETS"'@@k7.k s : a declaration @@ @@k7.ta s2 :other : [*s2*] @@ @k7 x @' -t ta -d 2>&1) if echo "$out" | grep -q "klammer-definition"; then fail "$name" "no internal dump" "$(echo "$out" | head -2)" else pass "$name" fi echo echo "-- the remedy the message names" accepted " 8. a .k declaration with :: instances" \ '@@k8.k s :n : a declaration @@ @@k8.ta :: [*s*] @@ @@k8.tb :: [*s*] @@ @k8 x @' rejected " 9. a .k declaration plus a parameterized definition" \ '@@k9.k s : a declaration @@ @@k9.ta s2 :other : [*s2*] @@ @k9 x @' 'both a declaration' echo echo "=============================" echo "Results: ${green}$PASS passed${reset}, ${red}$FAIL failed${reset}" [ $FAIL -eq 0 ]