#!/bin/bash # # filename_test.sh — Regression tests for filenames containing spaces. # # Filenames may contain spaces. The rules (see CLAUDE.md "Output directory # policy" and the filename-list functions in mac/file.cpp): # - argv boundaries are authoritative: a shell-quoted "my file.kt" is one # filename (Argv stores the original argv vector; nothing re-splits it). # - A filename LIST is separated by a standalone "/" token (whitespace on # both sides) — never a legal input filename, since "/" alone is the # root directory. # - Rescue: without a separator, whitespace-split names that do not exist # are greedily rejoined with their neighbors into names that do; the # regrouping is announced on stderr. # - A leading "~/" expands to $HOME (shells do not expand a quoted tilde). # # Engine tier: uses -k none; no SKS. # # Usage: ./filename_test.sh # 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' # Scratch input files DIR=$(mktemp -d) trap 'rm -rf "$DIR"' EXIT mkdir "$DIR/my dir" printf 'ALPHA\n' > "$DIR/my file.kt" printf 'BETA\n' > "$DIR/b.kt" printf 'GAMMA\n' > "$DIR/my dir/c.kt" cd "$DIR" || exit 1 # check TEST_NAME EXPECTED_STDOUT EXPECTED_STDERR_SUBSTRING KTEXT_ARGS... # EXPECTED_STDERR_SUBSTRING may be "" (no stderr requirement). check() { local test_name="$1" expected="$2" err_needle="$3" shift 3 local output status errfile=$DIR/.stderr output=$("$KTEXT" "$@" 2>"$errfile") status=$? output=$(printf '%s' "$output" | sed -e 's/[ \t]*$//' | grep -v '^$') if [ $status -ne 0 ]; then echo "${red}FAIL${reset} $test_name — ktext exited $status" echo " stderr: $(head -3 "$errfile")" FAIL=$((FAIL + 1)) return fi if [ "$output" != "$expected" ]; then echo "${red}FAIL${reset} $test_name" echo " expected: [$expected]" echo " got: [$output]" FAIL=$((FAIL + 1)) return fi if [ -n "$err_needle" ] && ! grep -qF "$err_needle" "$errfile"; then echo "${red}FAIL${reset} $test_name — expected stderr to contain [$err_needle]" echo " stderr: $(head -3 "$errfile")" FAIL=$((FAIL + 1)) return fi echo "${green}PASS${reset} $test_name" PASS=$((PASS + 1)) } # check_error TEST_NAME EXPECTED_SUBSTRING KTEXT_ARGS... # Expects a nonzero exit whose combined output contains EXPECTED_SUBSTRING. check_error() { local test_name="$1" needle="$2" shift 2 local output status output=$("$KTEXT" "$@" 2>&1) status=$? if [ $status -eq 0 ]; then echo "${red}FAIL${reset} $test_name — expected an error, got exit 0" FAIL=$((FAIL + 1)) return fi if echo "$output" | grep -qF "$needle"; then echo "${green}PASS${reset} $test_name" PASS=$((PASS + 1)) else echo "${red}FAIL${reset} $test_name — expected output to contain [$needle]" echo " output: $(echo "$output" | head -3)" FAIL=$((FAIL + 1)) fi } echo "${bold}Filename-with-spaces tests${reset}" echo "=======================" check "1. quoted filename with a space is one file" \ "ALPHA" "" \ "my file.kt" -d -k none check "2. unquoted spaces rescued into an existing file (announced)" \ "ALPHA" "interpreting \"my file.kt\" as one filename" \ my file.kt -d -k none check "3. standalone / separates a filename list" \ "ALPHA BETA" "" \ my file.kt / b.kt -d -k none check "4. space in a directory component" \ "GAMMA" "" \ "my dir/c.kt" -d -k none check "5. quoted name that exists is never split (b.kt also exists)" \ "ALPHA" "" \ "my file.kt" -d -k none HOME="$DIR" check "6. quoted ~/ expands to \$HOME inside ktext" \ "BETA" "" \ "~/b.kt" -d -k none check "7. @read argument keeps its internal space" \ "ALPHA" "" \ -s '@read my file.kt @' -d -k none check_error "8. unrescuable name is reported as written" \ "no such.kt" \ "no such.kt" -d -k none echo echo "=======================" echo "Results: ${green}$PASS passed${reset}, ${red}$FAIL failed${reset}" [ $FAIL -eq 0 ]