Assembled from klammertext-dev f344a37d772c. The commands, the library,
the Standard Klammer Set, the reflection klammerset and the Python
binding build and run natively on Windows (MSYS2 UCRT64 gcc, python.org
Python), and both test tiers pass there. doc/install/windows_source_install.md
is the fifth install guide: a source install parallel to the Linux and
macOS ones, verified by following it on a pristine Windows 11.
Behaviour on every system: paths Klammertext prints use forward slashes;
output is LF; the command line is UTF-8 on Windows; @eval :shell is a
POSIX shell command everywhere -- on Windows it runs the sh Klammertext
ships, BusyBox for Windows (win/busybox/, GPLv2, with its licence and the
source pointer). KLAMMERTEXT_FONTS and KLAMMERTEXT_KLAMMERSETS are lists in
the system's PATH convention (';' on Windows). On Linux and macOS nothing
observable changes.
156 lines
6.2 KiB
Bash
Executable File
156 lines
6.2 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# verbosity_test.sh — what "-v" says, and what it must not say.
|
|
#
|
|
# The output policy (CLAUDE.md, "Command output policy") fixes what each
|
|
# verbosity level is FOR, and a policy with no test drifts back — which is how
|
|
# the suites this session repaired got where they were. The rule:
|
|
#
|
|
# -v 0 silent. Nothing but the result.
|
|
# -v 1 every decision whose outcome the user COULD NOT HAVE READ OFF THEIR
|
|
# OWN INPUT: a klammerset symbol resolved to a file, a default applied,
|
|
# "-o" expanded into a directory and a basename, a filename regrouped,
|
|
# a klammer overridden by a definition in another klammer set.
|
|
# -v 2+ the trace: what the command DID, for someone reading the code.
|
|
#
|
|
# The boundary is the part worth testing. Andy's first formulation was "-v 1
|
|
# describes a change of state", and taken literally that swallows -v 2 — every
|
|
# definition is a change of state. So the test for -v 1 is not "did something
|
|
# happen" but "could the user have predicted the outcome from what they wrote".
|
|
# Registering a klammer the user wrote, in the file they wrote, is NOT -v 1
|
|
# material; resolving a symbol through a three-stage search path with shadowing
|
|
# is.
|
|
#
|
|
# Engine tier: no klammerset beyond what a case loads deliberately. The SKS
|
|
# half of this policy — font resolution and ":files" resolution — is in
|
|
# sks/tst/verbosity_test.sh, because those are @document's decisions.
|
|
#
|
|
# Usage: ./verbosity_test.sh (needs KLAMMERTEXT_HOME set; commands 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'
|
|
|
|
OUTF=$(mktemp "${TMPDIR:-/tmp}"/verb_out.XXXXXX)
|
|
ERRF=$(mktemp "${TMPDIR:-/tmp}"/verb_err.XXXXXX)
|
|
TMPD=$(mktemp -d "${TMPDIR:-/tmp}"/verb_dir.XXXXXX)
|
|
trap 'rm -f "$OUTF" "$ERRF"; rm -rf "$TMPD"' EXIT
|
|
|
|
plain() { sed 's/\x1b\[[0-9;]*m//g'; }
|
|
|
|
pass() { echo "${green}PASS${reset} $1"; PASS=$((PASS + 1)); }
|
|
fail() { echo "${red}FAIL${reset} $1"; [ -n "$2" ] && echo " $2"; FAIL=$((FAIL + 1)); }
|
|
|
|
# run CMD ARGS... — fills OUTF/ERRF, sets STATUS.
|
|
STATUS=0
|
|
run() { "$@" >"$OUTF" 2>"$ERRF"; STATUS=$?; }
|
|
|
|
# reports NAME PATTERN — ERRF matches PATTERN (the log is on stderr, always).
|
|
reports() {
|
|
if plain < "$ERRF" | grep -Eq -- "$2"; then pass "$1"
|
|
else fail "$1" "no [$2] in: $(plain < "$ERRF" | head -3 | tr '\n' ' ')"; fi
|
|
}
|
|
absent() {
|
|
if plain < "$ERRF" | grep -Eq -- "$2"; then fail "$1" "unexpected [$2]"
|
|
else pass "$1"; fi
|
|
}
|
|
|
|
echo "${bold}Verbosity tests${reset}"
|
|
echo "==============="
|
|
echo
|
|
|
|
echo "-- -v 0 is silent --"
|
|
run "$KTEXT" --klammersets none -s 'hello' -d
|
|
if [ $STATUS -eq 0 ] && [ "$(cat "$OUTF")" = "hello" ] && [ ! -s "$ERRF" ]; then
|
|
pass " 1. a successful run says nothing but its result"
|
|
else
|
|
fail " 1. exit $STATUS, stdout [$(cat "$OUTF")], stderr [$(head -1 "$ERRF")]"
|
|
fi
|
|
|
|
echo
|
|
echo "-- -v 1 answers \"what did the command think I asked for?\" --"
|
|
run "$KTEXT" --klammersets none -s 'hello' -d -v 1
|
|
reports " 2. the resolved argument list is shown" '\-s +: hello'
|
|
reports " 3. ... including a default the user did not write" '\-v +: 1'
|
|
# The document is on stdout and nothing shares it, whatever -v says.
|
|
if [ "$(cat "$OUTF")" = "hello" ]; then
|
|
pass " 4. and the result is still the only thing on stdout"
|
|
else
|
|
fail " 4. stdout carried [$(head -c 60 "$OUTF")]"
|
|
fi
|
|
|
|
echo
|
|
echo "-- -v 1 reports DERIVED values --"
|
|
# The output path: the user gave a target and an input name; the directory, the
|
|
# basename and the final filename were all constructed.
|
|
printf 'hello\n' > "$TMPD/doc.kt"
|
|
run "$KTEXT" "$TMPD/doc.kt" -t txt --klammersets none -v 1
|
|
reports " 5. the output directory it constructed" 'Output directory: '
|
|
reports " 6. the output basename it constructed" 'Output basename: doc'
|
|
reports " 7. the output filename it constructed" 'Output filename: .*doc\.txt'
|
|
|
|
# A klammerset symbol resolves through a three-stage search path with
|
|
# shadowing, so the FILE it landed on is the derived value. Both branches are
|
|
# checked: the default (no --klammersets at all) reported nothing until
|
|
# 2026-08-15, which was the commonest case of all.
|
|
run "$KTEXT" -s 'x' -d -v 1
|
|
reports " 8. the DEFAULT klammerset names the file it loaded" 'Klammerset \(default\): .*sks/sks\.k'
|
|
mkdir -p "$TMPD/kset"
|
|
printf '@@@klammerset kset | A set @@@\n' > "$TMPD/kset/kset.k"
|
|
run env KLAMMERTEXT_KLAMMERSETS="$TMPD" "$KTEXT" -s 'x' -d --klammersets kset -v 1
|
|
reports " 9. a symbol names the file it resolved to" 'Klammerset "kset": .*kset/kset\.k'
|
|
run "$KTEXT" -s 'x' -d --klammersets none -v 1
|
|
reports "10. and \"none\" says that none was loaded" 'Klammersets: none'
|
|
|
|
# An override: the definition being replaced usually lives somewhere the user
|
|
# cannot see, which is what earns it a place here rather than a warning.
|
|
run "$KTEXT" --klammersets none -t fx -d -v 1 \
|
|
-s '@@@target fx | F @@@ @@w.k : W @@ @@w.fx :: A @@ @@w.fx ::: B @@ @w@'
|
|
reports "11. a klammer overridden by a later definition" 'overridden'
|
|
|
|
echo
|
|
echo "-- the boundary: -v 2 is the trace, -v 1 is not --"
|
|
run "$KTEXT" --klammersets none -s 'hello' -d -v 1
|
|
v1=$(wc -l < "$ERRF")
|
|
run "$KTEXT" --klammersets none -s 'hello' -d -v 2
|
|
v2=$(wc -l < "$ERRF")
|
|
if [ "$v2" -gt "$v1" ]; then
|
|
pass "12. -v 2 says more than -v 1 ($v1 lines -> $v2)"
|
|
else
|
|
fail "12. -v 2 added nothing ($v1 -> $v2)"
|
|
fi
|
|
# The trace names the code; the -v 1 report never should. A source location in
|
|
# a level-1 line means a msg() or a stray log level, not a decision.
|
|
run "$KTEXT" --klammersets none -s 'hello' -d -v 1
|
|
absent "13. -v 1 does not name source files" '\[[a-z_]+\.cpp:[0-9]+\]'
|
|
run "$KTEXT" --klammersets none -s 'hello' -d -v 2
|
|
reports "14. ... while -v 2 does" '\[[a-z_]+\.(cpp|h):[0-9]+\]'
|
|
|
|
echo
|
|
echo "-- the other two commands honour -v as well --"
|
|
run kdesc --katoms -v 1
|
|
if [ $STATUS -eq 0 ] && [ -s "$OUTF" ]; then
|
|
pass "15. kdesc -v 1 still produces its result on stdout"
|
|
else
|
|
fail "15. exit $STATUS, stdout $(wc -c < "$OUTF") bytes"
|
|
fi
|
|
run kdiag -v 1 '@i-x'
|
|
if [ $STATUS -eq 0 ] && [ -s "$OUTF" ]; then
|
|
pass "16. kdiag -v 1 still produces its result on stdout"
|
|
else
|
|
fail "16. exit $STATUS, stdout $(wc -c < "$OUTF") bytes"
|
|
fi
|
|
|
|
echo
|
|
echo "==============="
|
|
echo "Results: ${PASS} passed, ${FAIL} failed"
|
|
[ "$FAIL" -eq 0 ] || exit 1
|
|
exit 0
|