patchette

test-usage.sh

#!/bin/bash
## Runs the usage guide's examples.  Each `CASE/session` hunk in docs/userguide/USAGE.md
## is a terminal session: its prompt lines (`~/dir$ command`, or `/dir$ command`) are run in order, in a fresh sandbox,
## and the whole session as it ran -- prompts, commands, output -- must match the hunk.
## Run with TESTMARK_REGEN=1 to rewrite the sessions from what patchette does now; review with `git diff`.
set -euo pipefail
source "${TESTMARK_BASH:-$(dirname "${BASH_SOURCE[0]}")/../../../warplibs/testmark-bash}/lib/testmark.bash"

## replay_session runs a session's commands in this shell, in order, and prints the session as it ran.
## Each command is printed after a prompt naming the cwd (as `~`-relative), then what it printed,
## with the home dir shown as `~` there too; a nonzero exit adds an `[exit status: N]` line.
## The old session's other lines (its old output) are dropped: they're what gets regenerated.
## Commands get /dev/null on stdin, so nothing can wait on input.
##
## - @stdin the session, as written
## - @stdout the session, as it ran
replay_session() {
	local prompt_re='^[~/][^$]*\$ (.*)$' line cmd rc out
	local -a lines
	local capture
	capture=$(mktemp)
	mapfile -t lines
	for line in "${lines[@]}"; do
		[[ $line =~ $prompt_re ]] || continue
		cmd=${BASH_REMATCH[1]}
		printf '%s$ %s\n' "${PWD/#"$HOME"/"~"}" "$cmd"
		rc=0
		eval "$cmd" </dev/null >"$capture" 2>&1 || rc=$?
		out=$(<"$capture")
		[[ -z $out ]] || printf '%s\n' "${out//"$HOME"/"~"}"
		[[ $rc -eq 0 ]] || printf '[exit status: %s]\n' "$rc"
	done
	rm -f "$capture"
}

## exercise_session runs one session in a fresh sandbox home:
## `~/upstream/frob` is the upstream, and `~/src/frob` a clone of it, with `main` checked out,
## carrying the branches `topic/fancy`, `docs-polish`, and `odd-bytes` (see make_corpus).
## Git's identity and clock are pinned, so commits made in a session are reproducible.
exercise_session() {
	source "$TESTCASE_DIR/lib.sh"
	testcase_withtmpdir
	make_corpus corpus
	export HOME=$PWD/home
	mkdir -p "$HOME/upstream" "$HOME/src"
	mv corpus/upstream "$HOME/upstream/frob"
	mv corpus/dev "$HOME/src/frob"
	git -C "$HOME/src/frob" remote set-url origin "$HOME/upstream/frob"
	git -C "$HOME/src/frob" switch -q main
	export PATH="${PATCHETTE%/patchette}:$PATH"
	export GIT_AUTHOR_DATE='@1700086400 +0000' GIT_COMMITTER_DATE='@1700086400 +0000'
	cd "$HOME"
	testcase_hunk session |
		bash --norc --noprofile -c "$(declare -f replay_session); replay_session" |
		testcase_output session
}

testmarktest_provide replay_session
testmarktest_rule '*/session' exercise_session
testmarktest_run ../docs/userguide/USAGE.md

tests/test-usage.sh · 2.6 KiB · bd494f7d30