#!/bin/bash # # editor_test.sh — Regression tests for the Klammertext editor support # (the Emacs mode's indentation/alignment units and their Sublime Text ports). # # Why this lives in tst/: the editor code implements the LANGUAGE's structural # layer — @-run length, bar-run dimension, ^-escapes, # removal, literal # spans, nesting depth — independently of both the SKS and the Klammermachine. # tst/ is the SKS-independent tier, and these suites check that the # independent implementations of Klammertext's structure agree with the # canonical formatting conventions AND with each other. The klammer names # that appear in the fixtures (@ol, @table, @document, @code) are seeded # configuration of the editor tools, not SKS dependencies; nothing here runs # ktext or loads a klammer set. # # What is checked, for every fixture pair .kt / _expected.kt in # tst/editor/: # * the Sublime Python core's output equals the expected file # * idempotence: the tool applied to the expected file leaves it unchanged # * when Emacs is installed: the Emacs unit's output equals the expected # file, and equals the Python output byte for byte (the sync check across # the SYNC-noted policy lists) — skipped gracefully otherwise # # The editor code is located automatically: doc/emacs + doc/sublime in the # development tree, doc/edit/emacs + doc/edit/sublime in the distribution. # # Usage: ./editor_test.sh Requires python3; Emacs is optional. # Exit code: 0 if all tests pass, 1 otherwise. PASS=0 FAIL=0 red=$'\033[31m' green=$'\033[32m' bold=$'\033[1m' reset=$'\033[0m' HERE="$(cd "$(dirname "$0")" && pwd)" ROOT="$(cd "$HERE/.." && pwd)" if [ -d "$ROOT/doc/emacs" ]; then EMACS_DIR="$ROOT/doc/emacs" SUBLIME_DIR="$ROOT/doc/sublime" elif [ -d "$ROOT/doc/edit/emacs" ]; then EMACS_DIR="$ROOT/doc/edit/emacs" SUBLIME_DIR="$ROOT/doc/edit/sublime" else echo "editor_test.sh: cannot locate the editor support (doc/emacs or doc/edit/emacs)" >&2 exit 1 fi FIX="$HERE/editor" OUT="$(mktemp -d)" trap 'rm -rf "$OUT"' EXIT INDENT_FIXTURES="indent_list indent_document indent_table indent_untouched indent_defs indent_escapes indent_named_close" ALIGN_FIXTURES="align_mixed align_empty_cells align_boundary align_colspan align_escapes align_too_wide" # Build the (MODE INFILE OUTFILE) triples: each fixture is run from its input # and from its expected file (the idempotence check). py_args=() el_args=() add_fixture() { # add_fixture MODE NAME local mode="$1" name="$2" py_args+=("$mode" "$FIX/$name.kt" "$OUT/$name.py.out") py_args+=("$mode" "$FIX/${name}_expected.kt" "$OUT/$name.py.idem") el_args+=("$mode" "$FIX/$name.kt" "$OUT/$name.el.out") el_args+=("$mode" "$FIX/${name}_expected.kt" "$OUT/$name.el.idem") } for f in $INDENT_FIXTURES; do add_fixture indent "$f"; done for f in $ALIGN_FIXTURES; do add_fixture align "$f"; done # --- run the Sublime Python cores (required) ------------------------------- if ! command -v python3 >/dev/null 2>&1; then echo "editor_test.sh: python3 not found" >&2 exit 1 fi if ! PYTHONDONTWRITEBYTECODE=1 python3 "$FIX/editor_driver.py" "$SUBLIME_DIR" "${py_args[@]}"; then echo "editor_test.sh: the Python driver failed" >&2 exit 1 fi # --- run the Emacs units (optional) ---------------------------------------- HAVE_EMACS=0 if command -v emacs >/dev/null 2>&1; then if emacs --batch -L "$EMACS_DIR" \ -l klammertext-mode -l klammertext-indent -l klammertext-align \ -l "$FIX/editor_driver.el" "${el_args[@]}" 2>"$OUT/emacs.log"; then HAVE_EMACS=1 else echo "${red}FAIL${reset} the Emacs driver failed:" >&2 cat "$OUT/emacs.log" >&2 FAIL=$((FAIL + 1)) fi else echo "(Emacs not installed — the Emacs half is skipped; the Python cores still run)" fi # --- compare --------------------------------------------------------------- check() { # check NAME FILE_A FILE_B if diff -q "$2" "$3" >/dev/null 2>&1; then echo "${green}PASS${reset} $1" PASS=$((PASS + 1)) else echo "${red}FAIL${reset} $1" diff "$2" "$3" | head -10 FAIL=$((FAIL + 1)) fi } for f in $INDENT_FIXTURES $ALIGN_FIXTURES; do check "$f (python)" "$OUT/$f.py.out" "$FIX/${f}_expected.kt" check "$f (python idempotent)" "$OUT/$f.py.idem" "$FIX/${f}_expected.kt" if [ "$HAVE_EMACS" = 1 ]; then check "$f (emacs)" "$OUT/$f.el.out" "$FIX/${f}_expected.kt" check "$f (emacs idempotent)" "$OUT/$f.el.idem" "$FIX/${f}_expected.kt" check "$f (emacs == python)" "$OUT/$f.el.out" "$OUT/$f.py.out" fi done echo echo "${bold}editor_test: $PASS passed, $FAIL failed${reset}" [ "$FAIL" -eq 0 ]