mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-11-15 21:43:09 +01:00
88d12b809a
B02typeset: ignore strerror text in test output, it differs by OS C02cond: discard stderr when looking for a path to the "mount" command
449 lines
11 KiB
Plaintext
449 lines
11 KiB
Plaintext
# Tests corresponding to the texinfo node `Conditional Expressions'
|
|
|
|
%prep
|
|
|
|
umask 077
|
|
|
|
mkdir cond.tmp
|
|
|
|
cd cond.tmp
|
|
|
|
typeset -gi isnfs
|
|
[[ "$(find . -prune -fstype nfs 2>/dev/null)" == "." ]] && isnfs=1
|
|
if (( isnfs )) &&
|
|
(cd -q ${ZTST_tmp} >/dev/null 2>&1 &&
|
|
[[ "$(find . -prune -fstype nfs 2>/dev/null)" != "." ]]); then
|
|
filetmpprefix=${ZTST_tmp}/condtest-$$-
|
|
isnfs=0
|
|
else
|
|
filetmpprefix=
|
|
fi
|
|
newnewnew=${filetmpprefix}newnewnew
|
|
unmodified=${filetmpprefix}unmodified
|
|
zlnfs=${filetmpprefix}zlnfs
|
|
|
|
touch $unmodified
|
|
|
|
touch zerolength
|
|
chgrp $EGID zerolength
|
|
|
|
touch $zlnfs
|
|
chgrp $EGID $zlnfs
|
|
|
|
print 'Garbuglio' >nonzerolength
|
|
|
|
mkdir modish
|
|
chgrp $EGID modish
|
|
|
|
chmod 7710 modish # g+xs,u+s,+t
|
|
chmod g+s modish # two lines combined work around chmod bugs
|
|
|
|
touch unmodish
|
|
chmod 000 unmodish
|
|
|
|
print 'MZ' > cmd.exe
|
|
chmod +x cmd.exe
|
|
%test
|
|
|
|
[[ -a zerolength && ! -a nonexistent ]]
|
|
0:-a cond
|
|
|
|
# Find a block special file system. This is a little tricky.
|
|
block=$(find /dev(|ices)/ -type b -print)
|
|
if [[ -n $block ]]; then
|
|
[[ -b $block[(f)1] && ! -b zerolength ]]
|
|
else
|
|
print -u$ZTST_fd 'Warning: Not testing [[ -b blockdevice ]] (no devices found)'
|
|
[[ ! -b zerolength ]]
|
|
fi
|
|
0D:-b cond
|
|
|
|
# Use hardcoded /dev/tty because globbing inside /dev fails on Cygwin
|
|
char=/dev/tty
|
|
[[ -c $char && ! -c $zerolength ]]
|
|
0:-c cond
|
|
|
|
[[ -d . && ! -d zerolength ]]
|
|
0:-d cond
|
|
|
|
[[ -e zerolength && ! -e nonexistent ]]
|
|
0:-e cond
|
|
|
|
if [[ -n $block ]]; then
|
|
[[ -f zerolength && ! -f cond && ! -f $char && ! -f $block[(f)1] && ! -f . ]]
|
|
else
|
|
print -u$ZTST_fd 'Warning: Not testing [[ -f blockdevice ]] (no devices found)'
|
|
[[ -f zerolength && ! -f cond && ! -f $char && ! -f . ]]
|
|
fi
|
|
0:-f cond
|
|
|
|
[[ -g modish && ! -g zerolength ]]
|
|
0:-g cond
|
|
|
|
ln -s zerolength link
|
|
[[ -h link && ! -h zerolength ]]
|
|
0:-h cond
|
|
|
|
[[ -k modish && ! -k zerolength ]]
|
|
0:-k cond
|
|
|
|
foo=foo
|
|
bar=
|
|
[[ -n $foo && ! -n $bar && ! -n '' ]]
|
|
0:-n cond
|
|
|
|
[[ -o rcs && ! -o norcs && -o noerrexit && ! -o errexit ]]
|
|
0:-o cond
|
|
|
|
if ! grep '#define HAVE_FIFOS' $ZTST_testdir/../config.h; then
|
|
print -u$ZTST_fd 'Warning: Not testing [[ -p pipe ]] (FIFOs not supported)'
|
|
[[ ! -p zerolength ]]
|
|
else
|
|
if whence mkfifo && mkfifo pipe || mknod pipe p; then
|
|
[[ -p pipe && ! -p zerolength ]]
|
|
else
|
|
print -u$ZTST_fd 'Warning: Not testing [[ -p pipe ]] (cannot create FIFO)'
|
|
[[ ! -p zerolength ]]
|
|
fi
|
|
fi
|
|
0dD:-p cond
|
|
|
|
if (( EUID == 0 )); then
|
|
print -u$ZTST_fd 'Warning: Not testing [[ ! -r file ]] (root reads anything)'
|
|
[[ -r zerolength && -r unmodish ]]
|
|
elif [[ $OSTYPE = cygwin ]]; then
|
|
print -u$ZTST_fd 'Warning: Not testing [[ ! -r file ]]
|
|
(all files created by user may be readable)'
|
|
[[ -r zerolength ]]
|
|
else
|
|
[[ -r zerolength && ! -r unmodish ]]
|
|
fi
|
|
0:-r cond
|
|
|
|
[[ -s nonzerolength && ! -s zerolength ]]
|
|
0:-s cond
|
|
|
|
# no simple way of guaranteeing test for -t
|
|
|
|
[[ -u modish && ! -u zerolength ]]
|
|
0:-u cond
|
|
|
|
[[ -x cmd.exe && ! -x zerolength ]]
|
|
0:-x cond
|
|
|
|
[[ -z $bar && -z '' && ! -z $foo ]]
|
|
0:-z cond
|
|
|
|
[[ -L link && ! -L zerolength ]]
|
|
0:-L cond
|
|
|
|
# hard to guarantee a file not owned by current uid
|
|
[[ -O zerolength ]]
|
|
0:-O cond
|
|
|
|
[[ -G zerolength ]]
|
|
0:-G cond
|
|
|
|
# can't be bothered with -S
|
|
|
|
if [[ ${mtab::="$({mount || /sbin/mount || /usr/sbin/mount} 2>/dev/null)"} = *[(]?*[)] ]]; then
|
|
print -u $ZTST_fd 'This test takes two seconds...'
|
|
else
|
|
unmodified_ls="$(ls -lu $unmodified)"
|
|
print -u $ZTST_fd 'This test takes up to 60 seconds...'
|
|
fi
|
|
sleep 2
|
|
touch $newnewnew
|
|
if [[ $OSTYPE == "cygwin" ]]; then
|
|
ZTST_skip="[[ -N file ]] not supported on Cygwin"
|
|
elif (( isnfs )); then
|
|
ZTST_skip="[[ -N file ]] not supported with NFS"
|
|
elif { (( ! $+unmodified_ls )) &&
|
|
cat $unmodified &&
|
|
{ df -k -- ${$(print -r -- "$mtab" |
|
|
awk '/noatime/ {print $1,$3}'):-""} | tr -s ' ' |
|
|
fgrep -- "$(df -k . | tail -1 | tr -s ' ')" } >&/dev/null } ||
|
|
{ (( $+unmodified_ls )) && SECONDS=0 &&
|
|
! until (( SECONDS >= 58 )); do
|
|
ZTST_hashmark; sleep 2; cat $unmodified
|
|
[[ $unmodified_ls != "$(ls -lu $unmodified)" ]] && break
|
|
done }; then
|
|
ZTST_skip="[[ -N file ]] not supported with noatime file system"
|
|
else
|
|
[[ -N $newnewnew && ! -N $unmodified ]]
|
|
fi
|
|
0:-N cond
|
|
F:This test can fail on NFS-mounted filesystems as the access and
|
|
F:modification times are not updated separately. The test will fail
|
|
F:on HFS+ (Apple Mac OS X default) filesystems because access times
|
|
F:are not recorded. Also, Linux ext3 filesystems may be mounted
|
|
F:with the noatime option which does not update access times.
|
|
F:Failures in these cases do not indicate a problem in the shell.
|
|
|
|
[[ $newnewnew -nt $zlnfs && ! ($unmodified -nt $zlnfs) ]]
|
|
0:-nt cond
|
|
|
|
[[ $zlnfs -ot $newnewnew && ! ($zlnfs -ot $unmodified) ]]
|
|
0:-ot cond
|
|
|
|
[[ link -ef zerolength && ! (link -ef nonzerolength) ]]
|
|
0:-ef cond
|
|
|
|
[[ foo = foo && foo != bar && foo == foo && foo != '' ]]
|
|
0:=, == and != conds
|
|
|
|
[[ bar < foo && foo > bar ]]
|
|
0:< and > conds
|
|
|
|
[[ $(( 3 + 4 )) -eq 0x07 && $(( 5 * 2 )) -ne 0x10 ]]
|
|
0:-eq and -ne conds
|
|
|
|
[[ 3 -lt 04 && 05 -gt 2 ]]
|
|
0:-lt and -gt conds
|
|
|
|
[[ 3 -le 3 && ! (4 -le 3) ]]
|
|
0:-le cond
|
|
|
|
[[ 3 -ge 3 && ! (3 -ge 4) ]]
|
|
0:-ge cond
|
|
|
|
[[ 1 -lt 2 || 2 -lt 2 && 3 -gt 4 ]]
|
|
0:|| and && in conds
|
|
|
|
if ! grep '#define PATH_DEV_FD' $ZTST_testdir/../config.h; then
|
|
print -u$ZTST_fd "Warning: not testing [[ -e /dev/fd/0 ]] (/dev/fd not supported)"
|
|
true
|
|
else
|
|
[[ -e /dev/fd/0 ]]
|
|
fi
|
|
0dD:/dev/fd support in conds handled by access
|
|
|
|
if ! grep '#define PATH_DEV_FD' $ZTST_testdir/../config.h; then
|
|
print -u$ZTST_fd "Warning: not testing [[ -O /dev/fd/0 ]] (/dev/fd not supported)"
|
|
true
|
|
else
|
|
[[ -O /dev/fd/0 ]]
|
|
fi
|
|
0dD:/dev/fd support in conds handled by stat
|
|
|
|
[[ ( -z foo && -z foo ) || -z foo ]]
|
|
1:complex conds with skipping
|
|
|
|
[ '' != bar -a '' = '' ]
|
|
0:strings with `[' builtin
|
|
|
|
[ `echo 0` -lt `echo 1` ]
|
|
0:substitution in `[' builtin
|
|
|
|
[ -n foo scrimble ]
|
|
2:argument checking for [ builtin
|
|
?(eval):[:1: too many arguments
|
|
|
|
test -n foo scramble
|
|
2:argument checking for test builtin
|
|
?(eval):test:1: too many arguments
|
|
|
|
[ -n foo scrimble scromble ]
|
|
2:argument checking for [ builtin
|
|
?(eval):[:1: too many arguments
|
|
|
|
test -n foo scramble scrumble
|
|
2:argument checking for test builtin
|
|
?(eval):test:1: too many arguments
|
|
|
|
[ -n foo -a -n bar scrimble ]
|
|
2:argument checking for [ builtin
|
|
?(eval):[:1: too many arguments
|
|
|
|
test -n foo -a -z "" scramble
|
|
2:argument checking for test builtin
|
|
?(eval):test:1: too many arguments
|
|
|
|
fn() {
|
|
# careful: first file must exist to trigger bug
|
|
[[ -e $unmodified ]] || print Where\'s my file\?
|
|
[[ $unmodified -nt NonExistentFile ]]
|
|
print status = $?
|
|
}
|
|
fn
|
|
0:-nt shouldn't abort on non-existent files
|
|
>status = 1
|
|
|
|
str='string' empty=''
|
|
[[ -v IFS && -v str && -v empty && ! -v str[3] && ! -v not_a_variable ]]
|
|
0:-v cond
|
|
|
|
arr=( 1 2 3 4 ) empty=()
|
|
[[ -v arr && -v arr[1,4] && -v arr[1] && -v arr[4] && -v arr[-4] &&
|
|
-v arr[(i)3] && ! -v arr[(i)x] &&
|
|
! -v arr[0] && ! -v arr[5] && ! -v arr[-5] && ! -v arr[2][1] &&
|
|
! -v arr[3]extra && -v empty && ! -v empty[1] ]]
|
|
0:-v cond with array
|
|
|
|
typeset -A assoc=( key val num 4 )
|
|
[[ -v assoc && -v assoc[key] && -v assoc[(i)*] && -v assoc[(I)*] &&
|
|
! -v assoc[x] && ! -v assoc[key][1] ]]
|
|
0:-v cond with association
|
|
|
|
() { [[ -v 0 && -v 1 && -v 2 && ! -v 3 ]] } arg ''
|
|
0:-v cond with positional parameters
|
|
|
|
# core dumps on failure
|
|
if zmodload zsh/regex 2>/dev/null; then
|
|
echo >regex_test.sh 'if [[ $# = 1 ]]; then
|
|
if [[ $1 =~ /?[^/]+:[0-9]+:$ ]]; then
|
|
:
|
|
fi
|
|
fi
|
|
exit 0'
|
|
$ZTST_testdir/../Src/zsh -f ./regex_test.sh
|
|
fi
|
|
0:regex tests shouldn't crash
|
|
|
|
if zmodload zsh/regex 2>/dev/null; then
|
|
( # subshell in case coredump test failed
|
|
string="this has stuff in it"
|
|
bad_regex=0
|
|
if [[ $string =~ "h([a-z]*) s([a-z]*) " ]]; then
|
|
if [[ "$MATCH $MBEGIN $MEND" != "has stuff 6 15" ]]; then
|
|
print -r "regex variables MATCH MBEGIN MEND:
|
|
'$MATCH $MBEGIN $MEND'
|
|
should be:
|
|
'has stuff 6 15'"
|
|
bad_regex=1
|
|
else
|
|
results=("as 7 8" "tuff 11 14")
|
|
for i in 1 2; do
|
|
if [[ "$match[$i] $mbegin[$i] $mend[$i]" != $results[i] ]]; then
|
|
print -r "regex variables match[$i] mbegin[$i] mend[$i]:
|
|
'$match[$i] $mbegin[$i] $mend[$i]'
|
|
should be
|
|
'$results[$i]'"
|
|
bad_regex=1
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
(( bad_regex )) || print OK
|
|
else
|
|
print -r "regex failed to match '$string'"
|
|
fi
|
|
)
|
|
else
|
|
# if it didn't load, tough, but not a test error
|
|
ZTST_skip="regexp library not found."
|
|
fi
|
|
0:MATCH, MBEGIN, MEND, match, mbegin, mend
|
|
>OK
|
|
|
|
if zmodload zsh/regex 2>/dev/null; then
|
|
( # subshell because regex module may dump core, see above
|
|
if [[ a =~ a && b == b ]]; then
|
|
print OK
|
|
else
|
|
print "regex =~ inverted following test"
|
|
fi
|
|
)
|
|
else
|
|
# not a test error
|
|
ZTST_skip="regexp library not found."
|
|
fi
|
|
0:regex infix operator should not invert following conditions
|
|
>OK
|
|
|
|
[[ -fail badly ]]
|
|
2:Error message for unknown prefix condition
|
|
?(eval):1: unknown condition: -fail
|
|
|
|
[[ really -fail badly ]]
|
|
2:Error message for unknown infix condition
|
|
?(eval):1: unknown condition: -fail
|
|
|
|
crashme() {
|
|
if [[ $1 =~ ^http:* ]]
|
|
then
|
|
url=${1#*=}
|
|
fi
|
|
}
|
|
which crashme
|
|
0:Regression test for examining code with regular expression match
|
|
>crashme () {
|
|
> if [[ $1 =~ ^http:* ]]
|
|
> then
|
|
> url=${1#*=}
|
|
> fi
|
|
>}
|
|
|
|
weirdies=(
|
|
'! -a !'
|
|
'! -o !'
|
|
'! -a'
|
|
'! -o'
|
|
'! -a ! -a !'
|
|
'! = !'
|
|
'! !'
|
|
'= -a o'
|
|
'! = -a o')
|
|
for w in $weirdies; do
|
|
eval test $w
|
|
print $?
|
|
done
|
|
0:test compatability weirdness: treat ! as a string sometimes
|
|
>0
|
|
>0
|
|
>1
|
|
>0
|
|
>0
|
|
>0
|
|
>1
|
|
>0
|
|
>1
|
|
|
|
foo=''
|
|
[[ $foo ]] || print foo is empty
|
|
foo=full
|
|
[[ $foo ]] && print foo is full
|
|
0:bash compatibility with single [[ ... ]] argument
|
|
>foo is empty
|
|
>foo is full
|
|
|
|
test -z \( || print Not zero 1
|
|
test -z \< || print Not zero 2
|
|
test -n \( && print Not zero 3
|
|
test -n \) && print Not zero 4
|
|
[ -n \> ] && print Not zero 5
|
|
[ -n \! ] && print Not zero 6
|
|
0:test with two arguments and a token
|
|
>Not zero 1
|
|
>Not zero 2
|
|
>Not zero 3
|
|
>Not zero 4
|
|
>Not zero 5
|
|
>Not zero 6
|
|
|
|
[ '(' = ')' ] || print OK 1
|
|
[ '((' = '))' ] || print OK 2
|
|
[ '(' = '(' ] && print OK 3
|
|
[ '(' non-empty-string ')' ] && echo OK 4
|
|
[ '(' '' ')' ] || echo OK 5
|
|
0:yet more old-fashioned test fix ups: prefer comparison to parentheses
|
|
>OK 1
|
|
>OK 2
|
|
>OK 3
|
|
>OK 4
|
|
>OK 5
|
|
|
|
fn() { [[ 'a' == 'b' || 'b' = 'c' || 'c' != 'd' ]] }
|
|
which -x2 fn
|
|
0: = and == appear as input
|
|
>fn () {
|
|
> [[ 'a' == 'b' || 'b' = 'c' || 'c' != 'd' ]]
|
|
>}
|
|
|
|
%clean
|
|
# This works around a bug in rm -f in some versions of Cygwin
|
|
chmod 644 unmodish
|
|
for tmpfile in $newnewnew $unmodified $zlnfs; do
|
|
[[ -f $tmpfile ]] && rm -f $tmpfile
|
|
done
|