summaryrefslogtreecommitdiff
path: root/dotfiles/system/.zsh/modules/Test/ztst.zsh
diff options
context:
space:
mode:
Diffstat (limited to 'dotfiles/system/.zsh/modules/Test/ztst.zsh')
-rwxr-xr-xdotfiles/system/.zsh/modules/Test/ztst.zsh547
1 files changed, 0 insertions, 547 deletions
diff --git a/dotfiles/system/.zsh/modules/Test/ztst.zsh b/dotfiles/system/.zsh/modules/Test/ztst.zsh
deleted file mode 100755
index f172ae1..0000000
--- a/dotfiles/system/.zsh/modules/Test/ztst.zsh
+++ /dev/null
@@ -1,547 +0,0 @@
-#!/bin/zsh -f
-# The line above is just for convenience. Normally tests will be run using
-# a specified version of zsh. With dynamic loading, any required libraries
-# must already have been installed in that case.
-#
-# Takes one argument: the name of the test file. Currently only one such
-# file will be processed each time ztst.zsh is run. This is slower, but
-# much safer in terms of preserving the correct status.
-# To avoid namespace pollution, all functions and parameters used
-# only by the script begin with ZTST_.
-#
-# Options (without arguments) may precede the test file argument; these
-# are interpreted as shell options to set. -x is probably the most useful.
-
-# Produce verbose messages if non-zero.
-# If 1, produce reports of tests executed; if 2, also report on progress.
-# Defined in such a way that any value from the environment is used.
-: ${ZTST_verbose:=0}
-
-# We require all options to be reset, not just emulation options.
-# Unfortunately, due to the crud which may be in /etc/zshenv this might
-# still not be good enough. Maybe we should trick it somehow.
-emulate -R zsh
-
-# Ensure the locale does not screw up sorting. Don't supply a locale
-# unless there's one set, to minimise problems.
-[[ -n $LC_ALL ]] && LC_ALL=C
-[[ -n $LC_COLLATE ]] && LC_COLLATE=C
-[[ -n $LC_NUMERIC ]] && LC_NUMERIC=C
-[[ -n $LC_MESSAGES ]] && LC_MESSAGES=C
-[[ -n $LANG ]] && LANG=C
-
-# Don't propagate variables that are set by default in the shell.
-typeset +x WORDCHARS
-
-# Set the module load path to correspond to this build of zsh.
-# This Modules directory should have been created by "make check".
-[[ -d Modules/zsh ]] && module_path=( $PWD/Modules )
-# Allow this to be passed down.
-export MODULE_PATH
-
-# We need to be able to save and restore the options used in the test.
-# We use the $options variable of the parameter module for this.
-zmodload zsh/parameter
-
-# Note that both the following are regular arrays, since we only use them
-# in whole array assignments to/from $options.
-# Options set in test code (i.e. by default all standard options)
-ZTST_testopts=(${(kv)options})
-
-setopt extendedglob nonomatch
-while [[ $1 = [-+]* ]]; do
- set $1
- shift
-done
-# Options set in main script
-ZTST_mainopts=(${(kv)options})
-
-# We run in the current directory, so remember it.
-ZTST_testdir=$PWD
-ZTST_testname=$1
-
-integer ZTST_testfailed
-
-# This is POSIX nonsense. Because of the vague feeling someone, somewhere
-# may one day need to examine the arguments of "tail" using a standard
-# option parser, every Unix user in the world is expected to switch
-# to using "tail -n NUM" instead of "tail -NUM". Older versions of
-# tail don't support this.
-tail() {
- emulate -L zsh
-
- if [[ -z $TAIL_SUPPORTS_MINUS_N ]]; then
- local test
- test=$(echo "foo\nbar" | command tail -n 1 2>/dev/null)
- if [[ $test = bar ]]; then
- TAIL_SUPPORTS_MINUS_N=1
- else
- TAIL_SUPPORTS_MINUS_N=0
- fi
- fi
-
- integer argi=${argv[(i)-<->]}
-
- if [[ $argi -le $# && $TAIL_SUPPORTS_MINUS_N = 1 ]]; then
- argv[$argi]=(-n ${argv[$argi][2,-1]})
- fi
-
- command tail "$argv[@]"
-}
-
-# The source directory is not necessarily the current directory,
-# but if $0 doesn't contain a `/' assume it is.
-if [[ $0 = */* ]]; then
- ZTST_srcdir=${0%/*}
-else
- ZTST_srcdir=$PWD
-fi
-[[ $ZTST_srcdir = /* ]] || ZTST_srcdir="$ZTST_testdir/$ZTST_srcdir"
-
-# Set the function autoload paths to correspond to this build of zsh.
-fpath=( $ZTST_srcdir/../Functions/*~*/CVS(/)
- $ZTST_srcdir/../Completion
- $ZTST_srcdir/../Completion/*/*~*/CVS(/) )
-
-: ${TMPPREFIX:=/tmp/zsh}
-ZTST_tmp=${TMPPREFIX}.ztst.$$
-if ! rm -f $ZTST_tmp || ! mkdir -p $ZTST_tmp || ! chmod go-w $ZTST_tmp; then
- print "Can't create $ZTST_tmp for exclusive use." >&2
- exit 1
-fi
-# Temporary files for redirection inside tests.
-ZTST_in=${ZTST_tmp}/ztst.in
-# hold the expected output
-ZTST_out=${ZTST_tmp}/ztst.out
-ZTST_err=${ZTST_tmp}/ztst.err
-# hold the actual output from the test
-ZTST_tout=${ZTST_tmp}/ztst.tout
-ZTST_terr=${ZTST_tmp}/ztst.terr
-
-ZTST_cleanup() {
- cd $ZTST_testdir
- rm -rf $ZTST_testdir/dummy.tmp $ZTST_testdir/*.tmp(N) ${ZTST_tmp}
-}
-
-# This cleanup always gets performed, even if we abort. Later,
-# we should try and arrange that any test-specific cleanup
-# always gets called as well.
-##trap 'print cleaning up...
-##ZTST_cleanup' INT QUIT TERM
-# Make sure it's clean now.
-rm -rf dummy.tmp *.tmp
-
-# Report failure. Note that all output regarding the tests goes to stdout.
-# That saves an unpleasant mixture of stdout and stderr to sort out.
-ZTST_testfailed() {
- print -r "Test $ZTST_testname failed: $1"
- if [[ -n $ZTST_message ]]; then
- print -r "Was testing: $ZTST_message"
- fi
- print -r "$ZTST_testname: test failed."
- if [[ -n $ZTST_failmsg ]]; then
- print -r "The following may (or may not) help identifying the cause:
-$ZTST_failmsg"
- fi
- ZTST_testfailed=1
- return 1
-}
-
-# Print messages if $ZTST_verbose is non-empty
-ZTST_verbose() {
- local lev=$1
- shift
- if [[ -n $ZTST_verbose && $ZTST_verbose -ge $lev ]]; then
- print -r -u $ZTST_fd -- $*
- fi
-}
-ZTST_hashmark() {
- if [[ ZTST_verbose -le 0 && -t $ZTST_fd ]]; then
- print -n -u$ZTST_fd -- ${(pl:SECONDS::\#::\#\r:)}
- fi
- (( SECONDS > COLUMNS+1 && (SECONDS -= COLUMNS) ))
-}
-
-if [[ ! -r $ZTST_testname ]]; then
- ZTST_testfailed "can't read test file."
- exit 1
-fi
-
-exec {ZTST_fd}>&1
-exec {ZTST_input}<$ZTST_testname
-
-# The current line read from the test file.
-ZTST_curline=''
-# The current section being run
-ZTST_cursect=''
-
-# Get a new input line. Don't mangle spaces; set IFS locally to empty.
-# We shall skip comments at this level.
-ZTST_getline() {
- local IFS=
- while true; do
- read -u $ZTST_input -r ZTST_curline || return 1
- [[ $ZTST_curline == \#* ]] || return 0
- done
-}
-
-# Get the name of the section. It may already have been read into
-# $curline, or we may have to skip some initial comments to find it.
-# If argument present, it's OK to skip the reset of the current section,
-# so no error if we find garbage.
-ZTST_getsect() {
- local match mbegin mend
-
- while [[ $ZTST_curline != '%'(#b)([[:alnum:]]##)* ]]; do
- ZTST_getline || return 1
- [[ $ZTST_curline = [[:blank:]]# ]] && continue
- if [[ $# -eq 0 && $ZTST_curline != '%'[[:alnum:]]##* ]]; then
- ZTST_testfailed "bad line found before or after section:
-$ZTST_curline"
- exit 1
- fi
- done
- # have the next line ready waiting
- ZTST_getline
- ZTST_cursect=${match[1]}
- ZTST_verbose 2 "ZTST_getsect: read section name: $ZTST_cursect"
- return 0
-}
-
-# Read in an indented code chunk for execution
-ZTST_getchunk() {
- # Code chunks are always separated by blank lines or the
- # end of a section, so if we already have a piece of code,
- # we keep it. Currently that shouldn't actually happen.
- ZTST_code=''
- # First find the chunk.
- while [[ $ZTST_curline = [[:blank:]]# ]]; do
- ZTST_getline || break
- done
- while [[ $ZTST_curline = [[:blank:]]##[^[:blank:]]* ]]; do
- ZTST_code="${ZTST_code:+${ZTST_code}
-}${ZTST_curline}"
- ZTST_getline || break
- done
- ZTST_verbose 2 "ZTST_getchunk: read code chunk:
-$ZTST_code"
- [[ -n $ZTST_code ]]
-}
-
-# Read in a piece for redirection.
-ZTST_getredir() {
- local char=${ZTST_curline[1]} fn
- ZTST_redir=${ZTST_curline[2,-1]}
- while ZTST_getline; do
- [[ $ZTST_curline[1] = $char ]] || break
- ZTST_redir="${ZTST_redir}
-${ZTST_curline[2,-1]}"
- done
- ZTST_verbose 2 "ZTST_getredir: read redir for '$char':
-$ZTST_redir"
-
- case $char in
- ('<') fn=$ZTST_in
- ;;
- ('>') fn=$ZTST_out
- ;;
- ('?') fn=$ZTST_err
- ;;
- (*) ZTST_testfailed "bad redir operator: $char"
- return 1
- ;;
- esac
- if [[ $ZTST_flags = *q* && $char = '<' ]]; then
- # delay substituting output until variables are set
- print -r -- "${(e)ZTST_redir}" >>$fn
- else
- print -r -- "$ZTST_redir" >>$fn
- fi
-
- return 0
-}
-
-# Execute an indented chunk. Redirections will already have
-# been set up, but we need to handle the options.
-ZTST_execchunk() {
- setopt localloops # don't let continue & break propagate out
- options=($ZTST_testopts)
- () {
- unsetopt localloops
- eval "$ZTST_code"
- }
- ZTST_status=$?
- # careful... ksh_arrays may be in effect.
- ZTST_testopts=(${(kv)options[*]})
- options=(${ZTST_mainopts[*]})
- ZTST_verbose 2 "ZTST_execchunk: status $ZTST_status"
- return $ZTST_status
-}
-
-# Functions for preparation and cleaning.
-# When cleaning up (non-zero string argument), we ignore status.
-ZTST_prepclean() {
- # Execute indented code chunks.
- while ZTST_getchunk; do
- ZTST_execchunk >/dev/null || [[ -n $1 ]] || {
- [[ -n "$ZTST_unimplemented" ]] ||
- ZTST_testfailed "non-zero status from preparation code:
-$ZTST_code" && return 0
- }
- done
-}
-
-# diff wrapper
-ZTST_diff() {
- emulate -L zsh
- setopt extendedglob
-
- local diff_out
- integer diff_pat diff_ret
-
- case $1 in
- (p)
- diff_pat=1
- ;;
-
- (d)
- ;;
-
- (*)
- print "Bad ZTST_diff code: d for diff, p for pattern match"
- ;;
- esac
- shift
-
- if (( diff_pat )); then
- local -a diff_lines1 diff_lines2
- integer failed i
-
- diff_lines1=("${(f)$(<$argv[-2])}")
- diff_lines2=("${(f)$(<$argv[-1])}")
- if (( ${#diff_lines1} != ${#diff_lines2} )); then
- failed=1
- else
- for (( i = 1; i <= ${#diff_lines1}; i++ )); do
- if [[ ${diff_lines2[i]} != ${~diff_lines1[i]} ]]; then
- failed=1
- break
- fi
- done
- fi
- if (( failed )); then
- print -rl "Pattern match failed:" \<${^diff_lines1} \>${^diff_lines2}
- diff_ret=1
- fi
- else
- diff_out=$(diff "$@")
- diff_ret="$?"
- if [[ "$diff_ret" != "0" ]]; then
- print -r -- "$diff_out"
- fi
- fi
-
- return "$diff_ret"
-}
-
-ZTST_test() {
- local last match mbegin mend found substlines
- local diff_out diff_err
- local ZTST_skip
-
- while true; do
- rm -f $ZTST_in $ZTST_out $ZTST_err
- touch $ZTST_in $ZTST_out $ZTST_err
- ZTST_message=''
- ZTST_failmsg=''
- found=0
- diff_out=d
- diff_err=d
-
- ZTST_verbose 2 "ZTST_test: looking for new test"
-
- while true; do
- ZTST_verbose 2 "ZTST_test: examining line:
-$ZTST_curline"
- case $ZTST_curline in
- (%*) if [[ $found = 0 ]]; then
- break 2
- else
- last=1
- break
- fi
- ;;
- ([[:space:]]#)
- if [[ $found = 0 ]]; then
- ZTST_getline || break 2
- continue
- else
- break
- fi
- ;;
- ([[:space:]]##[^[:space:]]*) ZTST_getchunk
- if [[ $ZTST_curline == (#b)([-0-9]##)([[:alpha:]]#)(:*)# ]]; then
- ZTST_xstatus=$match[1]
- ZTST_flags=$match[2]
- ZTST_message=${match[3]:+${match[3][2,-1]}}
- else
- ZTST_testfailed "expecting test status at:
-$ZTST_curline"
- return 1
- fi
- ZTST_getline
- found=1
- ;;
- ('<'*) ZTST_getredir || return 1
- found=1
- ;;
- ('*>'*)
- ZTST_curline=${ZTST_curline[2,-1]}
- diff_out=p
- ;&
- ('>'*)
- ZTST_getredir || return 1
- found=1
- ;;
- ('*?'*)
- ZTST_curline=${ZTST_curline[2,-1]}
- diff_err=p
- ;&
- ('?'*)
- ZTST_getredir || return 1
- found=1
- ;;
- ('F:'*) ZTST_failmsg="${ZTST_failmsg:+${ZTST_failmsg}
-} ${ZTST_curline[3,-1]}"
- ZTST_getline
- found=1
- ;;
- (*) ZTST_testfailed "bad line in test block:
-$ZTST_curline"
- return 1
- ;;
- esac
- done
-
- # If we found some code to execute...
- if [[ -n $ZTST_code ]]; then
- ZTST_hashmark
- ZTST_verbose 1 "Running test: $ZTST_message"
- ZTST_verbose 2 "ZTST_test: expecting status: $ZTST_xstatus"
- ZTST_verbose 2 "Input: $ZTST_in, output: $ZTST_out, error: $ZTST_terr"
-
- ZTST_execchunk <$ZTST_in >$ZTST_tout 2>$ZTST_terr
-
- if [[ -n $ZTST_skip ]]; then
- ZTST_verbose 0 "Test case skipped: $ZTST_skip"
- ZTST_skip=
- if [[ -n $last ]]; then
- break
- else
- continue
- fi
- fi
-
- # First check we got the right status, if specified.
- if [[ $ZTST_xstatus != - && $ZTST_xstatus != $ZTST_status ]]; then
- ZTST_testfailed "bad status $ZTST_status, expected $ZTST_xstatus from:
-$ZTST_code${$(<$ZTST_terr):+
-Error output:
-$(<$ZTST_terr)}"
- return 1
- fi
-
- ZTST_verbose 2 "ZTST_test: test produced standard output:
-$(<$ZTST_tout)
-ZTST_test: and standard error:
-$(<$ZTST_terr)"
-
- # Now check output and error.
- if [[ $ZTST_flags = *q* && -s $ZTST_out ]]; then
- substlines="$(<$ZTST_out)"
- rm -rf $ZTST_out
- print -r -- "${(e)substlines}" >$ZTST_out
- fi
- if [[ $ZTST_flags != *d* ]] && ! ZTST_diff $diff_out -u $ZTST_out $ZTST_tout; then
- ZTST_testfailed "output differs from expected as shown above for:
-$ZTST_code${$(<$ZTST_terr):+
-Error output:
-$(<$ZTST_terr)}"
- return 1
- fi
- if [[ $ZTST_flags = *q* && -s $ZTST_err ]]; then
- substlines="$(<$ZTST_err)"
- rm -rf $ZTST_err
- print -r -- "${(e)substlines}" >$ZTST_err
- fi
- if [[ $ZTST_flags != *D* ]] && ! ZTST_diff $diff_err -u $ZTST_err $ZTST_terr; then
- ZTST_testfailed "error output differs from expected as shown above for:
-$ZTST_code"
- return 1
- fi
- fi
- ZTST_verbose 1 "Test successful."
- [[ -n $last ]] && break
- done
-
- ZTST_verbose 2 "ZTST_test: all tests successful"
-
- # reset message to keep ZTST_testfailed output correct
- ZTST_message=''
-}
-
-
-# Remember which sections we've done.
-typeset -A ZTST_sects
-ZTST_sects=(prep 0 test 0 clean 0)
-
-print "$ZTST_testname: starting."
-
-# Now go through all the different sections until the end.
-# prep section may set ZTST_unimplemented, in this case the actual
-# tests will be skipped
-ZTST_skipok=
-ZTST_unimplemented=
-while [[ -z "$ZTST_unimplemented" ]] && ZTST_getsect $ZTST_skipok; do
- case $ZTST_cursect in
- (prep) if (( ${ZTST_sects[prep]} + ${ZTST_sects[test]} + \
- ${ZTST_sects[clean]} )); then
- ZTST_testfailed "\`prep' section must come first"
- exit 1
- fi
- ZTST_prepclean
- ZTST_sects[prep]=1
- ;;
- (test)
- if (( ${ZTST_sects[test]} + ${ZTST_sects[clean]} )); then
- ZTST_testfailed "bad placement of \`test' section"
- exit 1
- fi
- # careful here: we can't execute ZTST_test before || or &&
- # because that affects the behaviour of traps in the tests.
- ZTST_test
- (( $? )) && ZTST_skipok=1
- ZTST_sects[test]=1
- ;;
- (clean)
- if (( ${ZTST_sects[test]} == 0 || ${ZTST_sects[clean]} )); then
- ZTST_testfailed "bad use of \`clean' section"
- else
- ZTST_prepclean 1
- ZTST_sects[clean]=1
- fi
- ZTST_skipok=
- ;;
- *) ZTST_testfailed "bad section name: $ZTST_cursect"
- ;;
- esac
-done
-
-if [[ -n "$ZTST_unimplemented" ]]; then
- print "$ZTST_testname: skipped ($ZTST_unimplemented)"
- ZTST_testfailed=2
-elif (( ! $ZTST_testfailed )); then
- print "$ZTST_testname: all tests successful."
-fi
-ZTST_cleanup
-exit $(( ZTST_testfailed ))