Files
klammertext/tst/signature_test.sh
Andy Kopra 59c1599bc9 Target coverage: a klammer states the targets it serves
kdesc gains --coverage, which reports for every klammer the set of targets it
can render to, and — the point of it — which klammers' coverage cannot be
derived and must therefore be declared.  Three rules: coverage is DERIVED
where the definitions determine it (a general body of klammer calls covers
the intersection of what those klammers cover, by a greatest fixpoint after
loading), DECLARED where the engine cannot interpret what decides it (an
@eval body, whose targets are undecidable), and UNKNOWN where nothing is
written — which never means "deliberately unavailable".

Two new spellings in a definition's name.  A comma-separated target list,
"@@table.html,tex :: ...", gives one body several targets; it is surface
syntax, expanded at registration, and each member goes through the
redefinition rules on its own.  And "@@date.* :: ..." writes the general
target out, asserting that the klammer works for EVERY target including ones
not yet defined — a stronger claim than a list of the targets defined today,
and the one target declaration that could be mechanically falsified.

The Standard Klammer Set was swept accordingly: it now has no general
definitions at all, every klammer names the targets it serves, six use ".*",
and tex and pdf are at zero undecided.

kdesc's flags are reorganised on two rules: a flag reached for often gets a
single letter (-k klammers, -t targets, -c characters, -i input), a more
specialised topic a multi-letter name (--argtypes, --katoms, --rewrite,
--optionsets, --coverage, --klammerset, --font); and -v says how much to show
about PROCESSING, never what the RESULT contains — so the katom regex column
is "--katoms full" and the coverage detail "--coverage all".  NOTE: "-k" now
lists klammers (optionally filtered by a name/description search); the katom
table moved to "--katoms".

Fixes carried along: an option written with no value crashed the command with
SIGSEGV instead of reporting the mistake; two required positional arguments
never parsed; kdesc and kdiag printed an error and exited 0; and definition
diagnostics counted registrations rather than what was written, so one line
could be reported as two definitions and then printed twice.

Four new test suites: target_list, coverage, command_option, kdesc.

(from dev 46f54080bd9a)
2026-08-12 17:20:23 +02:00

144 lines
4.5 KiB
Bash
Executable File

#!/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 ".k" declaration'
echo
echo "============================="
echo "Results: ${green}$PASS passed${reset}, ${red}$FAIL failed${reset}"
[ $FAIL -eq 0 ]