Wren Linux

wren-linux / tools / test-wren-learn.sh

#!/bin/bash
# Checks bin/wren-learn in a temp home, on a pretend Wren Linux folder: every bash
# script listed smallest first, Space checking one off into the progress file,
# Enter opening it read-only, the references at the top. Changes nothing else.
# Run by test.sh, or:  bash tools/test-wren-learn.sh
# shellcheck disable=SC2016  # the inner shells expand their own variables
HERE=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
T=$(mktemp -d) || { echo "  FAIL  couldn't make a temp folder (is /tmp full?)"; exit 1; }
trap 'rm -rf "$T"' EXIT
fails=0
check() { # DESCRIPTION CONDITION-COMMAND...
    local what=$1
    shift
    if "$@" >/dev/null 2>&1; then printf '  ok    %s\n' "$what"; else printf '  FAIL  %s\n' "$what"; fails=$((fails + 1)); fi
}
W=$T/wren
mkdir -p "$W/bin" "$W/parts" "$W/data" "$W/.git" "$T/home" "$T/bin"
: >"$W/lib.sh"
printf '#!/bin/bash\n%s\n' a b c d e >"$W/parts/big.sh"
printf '#!/bin/sh\necho hi\n' >"$W/bin/small"
printf 'echo one\n' >"$W/data/tiny.sh"
printf '#!/usr/bin/python3\nprint(1)\n' >"$W/bin/notbash"
printf 'just words\n' >"$W/data/notes"
printf '#!/bin/bash\n' >"$W/.git/hook.sh"
L() { HOME=$T/home WREN_DIR=$W bash "$HERE/bin/wren-learn" "$@" 2>&1; }
P=$T/home/.local/share/wren/bash-learning.progress
out=$(L --list)
check "every bash script, the smallest first (lib.sh, .sh files, bash and sh scripts)" bash -c '
    [ "$(awk "{print \$(NF-2)}" <<<"$1" | paste -sd" ")" = "lib.sh data/tiny.sh bin/small parts/big.sh" ]' _ "$out"
check "...not other programs, plain files or git's folder" bash -c '! grep -qE "notbash|notes|hook" <<<"$1"' _ "$out"
check "...each with its lines, nothing checked yet" bash -c '[ "$(grep -c "^\[ \]" <<<"$1")" = 4 ] && grep -qE "^\[ \] +4  parts/big.sh  \(10 lines\)$" <<<"$1"' _ "$out"
L --toggle bin/small >/dev/null
check "checking one writes it to ~/.local/share/wren/bash-learning.progress" grep -qx 'bin/small' "$P"
check "...and the list shows it" grep -qx '\[x\]    3  bin/small  (2 lines)' <<<"$(L --list)"
L --toggle bin/small >/dev/null
check "...again: unchecked" test ! -s "$P"
check "a file that isn't one of its scripts is refused" bash -c '! HOME=$1 WREN_DIR=$2 bash "$3/bin/wren-learn" --toggle /etc/passwd && [ ! -s "$4" ]' _ "$T/home" "$W" "$HERE" "$P"

# The screen, in a pseudo-terminal: the references first; Space on a script checks it
# (a green check mark), Enter opens it read-only (a pretend view)
printf '#!/bin/sh\necho "view $*" >>"%s/opened"\n' "$T" >"$T/bin/view"
chmod +x "$T/bin/view"
cat >"$T/drive.py" <<'PY'
import os, pty, sys, time, select, struct, fcntl, termios
script, keys = sys.argv[1], sys.argv[2:]
pid, fd = pty.fork()
if pid == 0:
    fcntl.ioctl(0, termios.TIOCSWINSZ, struct.pack("HHHH", 24, 80, 0, 0))
    os.execvp("bash", ["bash", script])
out = b""
def pump(t):
    global out
    end = time.time() + t
    while time.time() < end:
        r, _, _ = select.select([fd], [], [], 0.05)
        if r:
            try: d = os.read(fd, 65536)
            except OSError: return
            if not d: return
            out += d
pump(1.5)
for k in keys:
    os.write(fd, k.encode().decode("unicode_escape").encode("latin-1") if "\\" in k else k.encode()); pump(0.6)
os.write(fd, b"q"); pump(0.8)
sys.stdout.write(out.decode(errors="replace"))
PY
scr() { HOME=$T/home WREN_DIR=$W LANG=C.UTF-8 PATH="$T/bin:$PATH" python3 -I "$T/drive.py" "$HERE/bin/wren-learn" "$@"; }
s=$(scr)
check "the screen: Greg's BashGuide and bash's own manual at the top, then the scripts" bash -c '
    grep -q "Online: Greg.s BashGuide" <<<"$1" && grep -q "Here: " <<<"$1" && grep -q "parts/big.sh" <<<"$1" && grep -q "0 of 4 read" <<<"$1"' _ "$s"
: >"$T/opened"
s=$(scr j j j ' ' '\r')
check "Space on a script checks it, with a green check mark" bash -c 'grep -qx "data/tiny.sh" "$1" && grep -q "\[$(printf "\033")\[32m✓" <<<"$2" && grep -q "1 of 4 read" <<<"$2"' _ "$P" "$s"
check "Enter opens it read-only (vim's view)" grep -qx "view -- $W/data/tiny.sh" "$T/opened"
s=$(LANG=C LC_ALL=C scr)
check "without UTF-8: a green * for the ones read" bash -c 'grep -q "\[$(printf "\033")\[32m\*" <<<"$1"' _ "$s"
check "numbered 1, 2, 3... down the list, not by their lines (scripts of the same length had the same number)" \
    bash -c '[ "$(awk "{print \$(NF-3)}" <<<"$1" | paste -sd" ")" = "1 2 3 4" ]' _ "$(L --list)"
check "a key redraws over the old screen in one write, without clearing it first (it flickered)" \
    bash -c '! grep -q "$(printf "\033")\[2J" <<<"$1" && grep -q "1 of 4 read" <<<"$1"' _ "$(scr j)"
printf 'data/tiny.sh\nparts/deleted-since.sh\n' >"$P"
check "a script read that has since gone isn't counted" grep -q "1 of 4 read" <<<"$(scr)"
printf '#!/bin/sh\necho "swaymsg $*" >>"%s/opened"\n' "$T" >"$T/bin/swaymsg"
printf '#!/bin/sh\nexit 0\n' >"$T/bin/firefox"
chmod +x "$T/bin/swaymsg" "$T/bin/firefox"
: >"$T/opened"
s=$(SWAYSOCK=$T/sock scr '\r')
check "Enter on Greg's BashGuide, in sway: opens it in Firefox, through sway (it had said to open it yourself)" \
    bash -c 'grep -qx "swaymsg -q exec -- firefox https://mywiki.wooledge.org/BashGuide" "$1" && ! grep -q "open that address" <<<"$2"' _ "$T/opened" "$s"
s=$(scr '\r')
check "...with no sway: the address, and that Enter goes back to the list" \
    bash -c 'grep -q "No browser to open it in here" <<<"$1" && grep -q "Press Enter to go back to the list" <<<"$1"' _ "$s"
printf '#!/bin/sh\necho "man $*" >>"%s/opened"\n' "$T" >"$T/bin/man"
printf '#!/bin/sh\necho "w3m $*" >>"%s/opened"\n' "$T" >"$T/bin/w3m"
printf '#!/bin/sh\nexit 0\n' >"$T/bin/foot"
chmod +x "$T/bin/man" "$T/bin/w3m" "$T/bin/foot"
: >"$T/opened"
s=$(SWAYSOCK=$T/sock scr j '\r')
check "Enter on bash's own manual, in sway: a terminal window of its own beside the list, not over it" bash -c '
    grep -qxE "swaymsg -q exec -- foot --log-level=error --app-id=wren-learn-manual (man bash|w3m /usr/share/doc/bash/bashref.html)" "$1" &&
    ! grep -q "^man " "$1"' _ "$T/opened"
: >"$T/opened"
s=$(scr j '\r')
check "...with no sway: in this terminal, as before" grep -qxE "man bash|w3m /usr/share/doc/bash/bashref.html" "$T/opened"
check "wrenctl learn opens it" grep -q 'exec "$HOME/.local/bin/wren-learn"' "$HERE/bin/wrenctl"
check "the Wren menu's part installs it" grep -qx 'install_bin wren-learn' "$HERE/parts/wren-menu.sh"

[ "$fails" -eq 0 ]