From f074d050d840b4f41788b53b8b5fcc4aa9075a6d Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 5 Jul 2001 15:04:03 +0000 Subject: 15261: remaining easy option tests --- Test/E01options.ztst | 350 ++++++++++++++++++++++++++++++++++++++++++++++++++- Test/ztst.zsh | 104 +++++++++++---- 2 files changed, 431 insertions(+), 23 deletions(-) (limited to 'Test') diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 8ffba78b7..08bcb21da 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -52,21 +52,42 @@ # MENU_COMPLETE # MONITOR # NOTIFY +# OVERSTRIKE +# PRINT_EIGHT_BIT +# PROMPT_CR +# PUSHD_SILENT +# REC_EXACT +# RM_STAR_SILENT +# RM_STAR_WAIT +# SHARE_HISTORY +# SINGLE_LINE_ZLE +# SUN_KEYBOARD_HACK +# ZLE # The following require SHINSTDIN and are not (yet) tested: # AUTO_CD +# SHINSTDIN # # Other difficult things I haven't done: # GLOBAL_RCS (uses fixed files outside build area) # HASH_CMDS ) # HASH_DIRS ) fairly seriously internal, hard to test at all # HASH_LIST_ALL ) +# PRINT_EXIT_STATUS haven't worked out what this does yet, although +# Bart suggested a fix. +# PRIVILEGED (similar to GLOBAL_RCS) +# RCS ( " " " " ) +# SH_OPTION_LETTERS even I found this too dull to set up a test for +# SINGLE_COMMAND kills shell +# VERBOSE hard because done on input (c.f. SHINSTDIN). %prep mkdir options.tmp && cd options.tmp mkdir tmpcd touch tmpfile1 tmpfile2 mydir=$PWD + mydirt=`print -P %~` catpath=$(which cat) + lspath==ls %test @@ -100,8 +121,8 @@ setopt autopushd cd tmpcd dircount - cd .. unsetopt autopushd + popd >/dev/null 0:AUTO_PUSHD option >1 >2 @@ -614,3 +635,330 @@ 0:NULL_GLOB option >tmpcd tmpfile1 tmpfile2 >frooble* tmpcd tmpfile1 tmpfile2 + + touch ngs1.txt ngs2.txt ngs10.txt ngs20.txt ngs100.txt ngs200.txt + setopt numericglobsort + print -l ngs* + unsetopt numericglobsort + print -l ngs* +0:NUMERIC_GLOB_SORT option +>ngs1.txt +>ngs2.txt +>ngs10.txt +>ngs20.txt +>ngs100.txt +>ngs200.txt +>ngs1.txt +>ngs10.txt +>ngs100.txt +>ngs2.txt +>ngs20.txt +>ngs200.txt + + typeset -i 10 oznum + setopt octalzeroes + (( oznum = 012 + 013 )) + print $oznum + unsetopt octalzeroes + (( oznum = 012 + 013 )) + print $oznum + unset oznum +0:OCTAL_ZEROES options +>21 +>25 + + typeset -a oldpath + oldpath=($path) + mkdir pdt_topdir pathtestdir pdt_topdir/pathtestdir + print "#!/bin/sh\necho File in upper dir" >pathtestdir/findme + print "#!/bin/sh\necho File in lower dir" >pdt_topdir/pathtestdir/findme + chmod u+x pathtestdir/findme pdt_topdir/pathtestdir/findme + pathtestdir/findme + rm -f pathtestdir/findme + setopt pathdirs + path=($PWD $PWD/pdt_topdir) + pathtestdir/findme + print unsetting option... + unsetopt pathdirs + pathtestdir/findme + path=($oldpath) + unset $oldpath + rm -rf pdt_topdir pathtestdir +0:PATH_DIRS option +>File in upper dir +>File in lower dir +>unsetting option... +?ZTST_execchunk:2: no such file or directory: pathtestdir/findme + + setopt posixbuiltins + command print foo + unsetopt posixbuiltins + print unsetting... + command print foo +1:POSIX_BUILTINS option +>foo +>unsetting... +?ZTST_execchunk:2: command not found: print + +# This option seems to be problematic. I don't quite know how it works. +## func() { +## setopt localoptions printexitvalue +## false +## } +## func +## 1:PRINT_EXIT_VALUE option +## ?ZTST_execchunk:2: exit 1 + + setopt promptbang + print -P ! + setopt nopromptbang + print -P ! +0:PROMPT_BANG option +>0 +>! + + unsetopt promptpercent + print -P '%/' + setopt promptpercent + print -P '%/' +0q:PROMPT_PERCENT option +>%/ +>$mydir + + setopt promptsubst + print -P '`echo waaah`' + unsetopt promptsubst + print -P '`echo waaah`' +0:PROMPT_SUBST option +>waaah +>`echo waaah` + + dirs + pushd $mydir/tmpcd + dirs + pushd $mydir/tmpcd + dirs + setopt pushdignoredups + pushd $mydir/tmpcd + dirs + unsetopt pushdignoredups + popd >/dev/null + popd >/dev/null +0q:PUSHD_IGNOREDUPS option +>$mydirt +>$mydirt/tmpcd $mydirt +>$mydirt/tmpcd $mydirt/tmpcd $mydirt +>$mydirt/tmpcd $mydirt/tmpcd $mydirt + + mkdir newcd + cd $mydir + pushd $mydir/tmpcd + pushd $mydir/newcd + dirs + pushd -0 + dirs + setopt pushdminus pushdsilent + pushd -0 + dirs + unsetopt pushdminus + popd >/dev/null + popd >/dev/null + cd $mydir +0q:PUSHD_MINUS option +>$mydirt/newcd $mydirt/tmpcd $mydirt +>$mydirt +>$mydirt $mydirt/newcd $mydirt/tmpcd +>$mydirt +>$mydirt $mydirt/newcd $mydirt/tmpcd + +# Do you have any idea how dull this is? + + pushd $mydir/tmpcd + pushd + dirs + setopt pushdtohome + pushd + dirs + unsetopt pushdtohome + popd + pushd + popd + dirs +0q:PUSHD_TO_HOME option +>$mydirt $mydirt/tmpcd +>~ $mydirt $mydirt/tmpcd +>$mydirt + + array=(one two three four) + setopt rcexpandparam + print aa${array}bb + unsetopt rcexpandparam + print aa${array}bb +0:RC_EXPAND_PARAM option +>aaonebb aatwobb aathreebb aafourbb +>aaone two three fourbb + + setopt rcquotes + # careful, this is done when parsing a complete block + eval "print 'one''quoted''expression'" + unsetopt rcquotes + eval "print 'another''quoted''expression'" +0:RC_QUOTES option +>one'quoted'expression +>anotherquotedexpression + + # too lazy to test jobs -Z and ARGV0. + (setopt restricted; cd /) + (setopt restricted; PATH=/bin:/usr/bin) + (setopt restricted; /bin/ls) + (setopt restricted; hash ls=/bin/ls) + (setopt restricted; print ha >outputfile) + (setopt restricted; exec ls) + (setopt restricted; unsetopt restricted) + : +0:RESTRICTED option +?ZTST_execchunk:cd:2: restricted +?ZTST_execchunk:2: PATH: restricted +?ZTST_execchunk:2: /bin/ls: restricted +?ZTST_execchunk:hash:2: restricted: /bin/ls +?ZTST_execchunk:2: writing redirection not allowed in restricted mode +?ZTST_execchunk:exec:2: ls: restricted +?ZTST_execchunk:unsetopt:2: can't change option: restricted + + fn() { + print =ls ={ls,} + local foo='=ls' + print ${~foo} + } + setopt shfileexpansion + fn + unsetopt shfileexpansion + fn +0q:SH_FILE_EXPANSION option +>$lspath =ls = +>=ls +>$lspath $lspath = +>$lspath + + testpat() { + if [[ $1 = ${~2} ]]; then print $1 $2 yes; else print $1 $2 no; fi + } + print option on + setopt shglob + repeat 2; do + for str in 'a(b|c)' ab; do + testpat $str 'a(b|c)' + done + for str in 'a<1-10>' a9; do + testpat $str 'a<1-10>' + done + [[ ! -o shglob ]] && break + print option off + unsetopt shglob + done +0:SH_GLOB option +>option on +>a(b|c) a(b|c) yes +>ab a(b|c) no +>a<1-10> a<1-10> yes +>a9 a<1-10> no +>option off +>a(b|c) a(b|c) no +>ab a(b|c) yes +>a<1-10> a<1-10> no +>a9 a<1-10> yes + + print this is bar >bar + fn() { + local NULLCMD=cat READNULLCMD=cat + echo hello | >foo + cat foo + option set +>option unset +>hello +>this is bar + + fn() { + eval 'for f in foo bar; print $f' + eval 'for f (word1 word2) print $f' + eval 'repeat 3 print nonsense' + } + unsetopt shortloops + print option unset + fn + setopt shortloops + print option set + fn +0:SHORT_LOOPS option +>option unset +>option set +>foo +>bar +>word1 +>word2 +>nonsense +>nonsense +>nonsense +?fn:-1: parse error near `print' +?fn:-1: parse error near `print' +?fn:-1: parse error near `print' +# Eugh, that line numbering behaviour with eval is probably a bug. + + fn() { print -l $*; } + setopt shwordsplit + print option set + repeat 2; do + foo='two words' + fn $foo + fn "${=foo}" + [[ ! -o shwordsplit ]] && break + unsetopt shwordsplit + print option unset + done +0:SH_WORD_SPLIT option +>option set +>two +>words +>two +>words +>option unset +>two words +>two +>words + + fn() { unset foo; print $foo; } + setopt nounset + print option unset unset by setting nounset + eval fn + print option unset reset + setopt unset + fn +0:UNSET option +>option unset unset by setting nounset +>option unset reset +> +?fn: foo: parameter not set + +# This really just tests if XTRACE is egregiously broken. +# To test it properly would need a full set of its own. + fn() { print message; } + setopt xtrace + fn + unsetopt xtrace + fn +0:XTRACE option +>message +>message +?+ZTST_execchunk:2> fn +?+fn:0> print message +?+ZTST_execchunk:2> unsetopt xtrace diff --git a/Test/ztst.zsh b/Test/ztst.zsh index fe996832c..0b748dac9 100755 --- a/Test/ztst.zsh +++ b/Test/ztst.zsh @@ -22,6 +22,12 @@ # 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 $LANG ]] && LANG=C + # 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 ) @@ -47,12 +53,21 @@ ZTST_mainopts=(${(kv)options}) ZTST_testdir=$PWD ZTST_testname=$1 -# The source directory is not necessarily the current directory -ZTST_srcdir=${0%/*} +integer ZTST_testfailed + +# 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/../(Completion|Functions)/*~*/CVS(/) ) +fpath=( $ZTST_srcdir/../Functions/*~*/CVS(/) + $ZTST_srcdir/../Completion + $ZTST_srcdir/../Completion/*/*~*/CVS(/) ) : ${TMPPREFIX:=/tmp/zsh} # Temporary files for redirection inside tests. @@ -66,7 +81,8 @@ ZTST_terr=${TMPPREFIX}.ztst.terr.$$ ZTST_cleanup() { cd $ZTST_testdir - rm -rf $ZTST_testdir/dummy.tmp $ZTST_testdir/*.tmp ${TMPPREFIX}.ztst*$$ + rm -rf $ZTST_testdir/dummy.tmp $ZTST_testdir/*.tmp(N) \ + ${TMPPREFIX}.ztst*$$(N) } # This cleanup always gets performed, even if we abort. Later, @@ -85,20 +101,27 @@ ZTST_testfailed() { print -r "Was testing: $ZTST_message" fi print -r "$ZTST_testname: test failed." - ZTST_cleanup - exit 1 + ZTST_testfailed=1 + return 1 } # Print messages if $ZTST_verbose is non-empty ZTST_verbose() { local lev=$1 shift - [[ -n $ZTST_verbose && $ZTST_verbose -ge $lev ]] && print -- $* >&8 + [[ -n $ZTST_verbose && $ZTST_verbose -ge $lev ]] && print -r -- $* >&8 +} +ZTST_hashmark() { + [[ ZTST_verbose -le 0 && -t 8 ]] && print -nu8 ${(pl:SECONDS::\#::\#\r:)} + (( SECONDS > COLUMNS+1 && (SECONDS -= COLUMNS) )) } -[[ ! -r $ZTST_testname ]] && ZTST_testfailed "can't read test file." +if [[ ! -r $ZTST_testname ]]; then + ZTST_testfailed "can't read test file." + exit 1 +fi -[[ -n $ZTST_verbose && $ZTST_verbose -ge 0 ]] && exec 8>&1 +exec 8>&1 exec 9<$ZTST_testname # The current line read from the test file. @@ -118,15 +141,18 @@ ZTST_getline() { # 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 [[ $ZTST_curline != '%'[[:alnum:]]##* ]]; then + 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 @@ -176,6 +202,7 @@ case $char in '?') fn=$ZTST_err ;; *) ZTST_testfailed "bad redir operator: $char" + return 1 ;; esac if [[ $ZTST_flags = *q* ]]; then @@ -183,6 +210,8 @@ if [[ $ZTST_flags = *q* ]]; then else print -r -- "$ZTST_redir" >>$fn fi + +return 0 } # Execute an indented chunk. Redirections will already have @@ -191,9 +220,10 @@ ZTST_execchunk() { options=($ZTST_testopts) 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" - ZTST_testopts=(${(kv)options}) - options=($ZTST_mainopts) return $ZTST_status } @@ -208,6 +238,19 @@ $ZTST_code" done } +# diff wrapper +ZTST_diff() { + local diff_out diff_ret + + diff_out=$(diff "$@") + diff_ret="$?" + if [[ "$diff_ret" != "0" ]]; then + echo "$diff_out" + fi + + return "$diff_ret" +} + ZTST_test() { local last match mbegin mend found @@ -246,29 +289,33 @@ $ZTST_curline" else ZTST_testfailed "expecting test status at: $ZTST_curline" + return 1 fi ZTST_getline found=1 ;; - '<'*) ZTST_getredir + '<'*) ZTST_getredir || return 1 found=1 ;; - '>'*) ZTST_getredir + '>'*) ZTST_getredir || return 1 found=1 ;; - '?'*) ZTST_getredir + '?'*) ZTST_getredir || return 1 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 @@ -278,6 +325,7 @@ $ZTST_curline" $ZTST_code${$(<$ZTST_terr):+ Error output: $(<$ZTST_terr)}" + return 1 fi ZTST_verbose 2 "ZTST_test: test produced standard output: @@ -286,15 +334,17 @@ ZTST_test: and standard error: $(<$ZTST_terr)" # Now check output and error. - if [[ $ZTST_flags != *d* ]] && ! diff -c $ZTST_out $ZTST_tout; then + if [[ $ZTST_flags != *d* ]] && ! ZTST_diff -c $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 != *D* ]] && ! diff -c $ZTST_err $ZTST_terr; then + if [[ $ZTST_flags != *D* ]] && ! ZTST_diff -c $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." @@ -312,12 +362,16 @@ $ZTST_code" 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. -while ZTST_getsect; do +ZTST_skipok= +while 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 @@ -325,22 +379,28 @@ while ZTST_getsect; do 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_prepclean 1 - ZTST_sects[clean]=1 + ZTST_skipok= ;; *) ZTST_testfailed "bad section name: $ZTST_cursect" ;; esac done -print "$ZTST_testname: all tests successful." +(( $ZTST_testfailed )) || print "$ZTST_testname: all tests successful." ZTST_cleanup -exit 0 +exit $(( ZTST_testfailed )) -- cgit 1.4.1