diff options
Diffstat (limited to 'tests/builtins.tests')
-rw-r--r-- | tests/builtins.tests | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/tests/builtins.tests b/tests/builtins.tests new file mode 100644 index 0000000..00ebc0f --- /dev/null +++ b/tests/builtins.tests @@ -0,0 +1,284 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# tests for miscellaneous builtins not tested elsewhere +set +p +set +o posix + +ulimit -c 0 2>/dev/null + +# check that break breaks loops +for i in a b c; do echo $i; break; echo bad-$i; done +echo end-1 +for i in a b c; do echo $i; break 1; echo bad-$i; done +echo end-2 +for i in a b c; do + for j in x y z; do + echo $i:$j + break + echo bad-$i + done + echo end-$i +done +echo end-3 + +# check that break breaks nested loops +for i in a b c; do + for j in x y z; do + echo $i:$j + break 2 + echo bad-$i + done + echo end-$i +done +echo end + +# check that continue continues loops +for i in a b c; do echo $i; continue; echo bad-$i ; done +echo end-1 +for i in a b c; do echo $i; continue 1; echo bad-$i; done +echo end-2 +for i in a b c; do + for j in x y z; do + echo $i:$j + continue + echo bad-$i-$j + done + echo end-$i +done +echo end-3 + +# check that continue breaks out of nested loops +for i in a b c; do + for j in x y z; do + echo $i:$j + continue 2 + echo bad-$i-$j + done + echo end-$i +done +echo end + +# check that `eval' re-evaluates arguments, but `builtin' and `command' do not +AVAR='$BVAR' +BVAR=foo + +echo $AVAR +builtin echo $AVAR +command echo $AVAR +eval echo \$AVAR +eval echo $AVAR + +# test out eval with a temp environment +AVAR=bar eval echo \$AVAR +BVAR=xxx eval echo $AVAR + +unset -v AVAR BVAR + +# test umask +mask=$(umask) +umask 022 +umask +umask -S +umask -S u=rwx,g=rwx,o=rx >/dev/null # 002 +umask +umask -S +umask -p +umask -p -S +umask 0 +umask -S +umask ${mask} # restore original mask + +# builtin/command without arguments should do nothing. maybe someday they will +builtin +command + +# test enable +enable -ps + +enable -aps ; enable -nps + +enable -n test +case "$(type -t test)" in +builtin) echo oops -- enable -n test failed ;; +*) echo enable -n test worked ;; +esac + +enable test +case "$(type -t test)" in +builtin) echo enable test worked ;; +*) echo oops -- enable test failed ;; +esac + +# test options to exec +(exec -a specialname ${THIS_SH} -c 'echo $0' ) +(exec -l -a specialname ${THIS_SH} -c 'echo $0' ) +# test `clean' environment. if /bin/sh is bash, and the script version of +# printenv is run, there will be variables in the environment that bash +# sets on startup. Also test code that prefixes argv[0] with a dash. +(export FOO=BAR ; exec -c -l printenv ) | grep FOO +(FOO=BAR exec -c printenv ) | grep FOO + +(export FOO=BAR ; exec printenv ) | grep FOO +(FOO=BAR exec printenv ) | grep FOO + +# ok, forget everything about hashed commands +hash -r +hash + +# this had better succeed, since command -p guarantees we will find the +# standard utilities +command -p hash rm + +# check out source/. + +# sourcing a zero-length-file had better not be an error +rm -f /tmp/zero-length-file +cp /dev/null /tmp/zero-length-file +. /tmp/zero-length-file +echo $? +rm /tmp/zero-length-file + +AVAR=AVAR + +. ./source1.sub +AVAR=foo . ./source1.sub + +. ./source2.sub +echo $? + +set -- a b c +. ./source3.sub + +# make sure source with arguments does not change the shell's positional +# parameters, but that the sourced file sees the arguments as its +# positional parameters +echo "$@" +. ./source3.sub x y z +echo "$@" + +# but if the sourced script sets the positional parameters explicitly, they +# should be reflected in the calling shell's positional parameters. this +# also tests one of the shopt options that controls source using $PATH to +# find the script +echo "$@" +shopt -u sourcepath +. source4.sub +echo "$@" + +# this is complicated when the sourced scripts gets its own positional +# parameters from arguments to `.' +set -- a b c +echo "$@" +. source4.sub x y z +echo "$@" + +# test out cd and $CDPATH +${THIS_SH} ./builtins1.sub + +# test behavior of `.' when given a non-existent file argument +${THIS_SH} ./source5.sub + +# test bugs in sourcing non-regular files, fixed post-bash-3.2 +${THIS_SH} ./source6.sub + +# test bugs with source called from multiline aliases and other contexts +${THIS_SH} ./source7.sub + +# in posix mode, assignment statements preceding special builtins are +# reflected in the shell environment. `.' and `eval' need special-case +# code. +set -o posix +echo $AVAR +AVAR=foo . ./source1.sub +echo $AVAR + +AVAR=AVAR +echo $AVAR +AVAR=foo eval echo \$AVAR +echo $AVAR + +AVAR=AVAR +echo $AVAR +AVAR=foo : +echo $AVAR +set +o posix + +# but assignment statements preceding `export' are always reflected in +# the environment +foo="" export foo +declare -p foo +unset foo + +# assignment statements preceding `declare' should be displayed correctly, +# but not persist after the command +FOO='$$' declare -p FOO +declare -p FOO +unset FOO + +# except for `declare -x', which should be equivalent to `export' +FOO='$$' declare -x FOO +declare -p FOO +unset FOO + +# test out kill -l. bash versions prior to 2.01 did `kill -l num' wrong +sigone=$(kill -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p') + +case "$(kill -l 1)" in +${sigone/SIG/}) echo ok;; +*) echo oops -- kill -l failure;; +esac + +# kill -l and trap -l should display exactly the same output +sigonea=$(trap -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p') + +if [ "$sigone" != "$sigonea" ]; then + echo oops -- kill -l and trap -l differ +fi + +# POSIX.2 says that exit statuses > 128 are mapped to signal names by +# subtracting 128 so you can find out what signal killed a process +case "$(kill -l $(( 128 + 1)) )" in +${sigone/SIG/}) echo ok;; +*) echo oops -- kill -l 129 failure;; +esac + +# out-of-range signal numbers should report the argument in the error +# message, not 128 less than the argument +kill -l 4096 + +# kill -l NAME should return the signal number +kill -l ${sigone/SIG/} + +# test behavior of shopt xpg_echo +${THIS_SH} ./builtins2.sub + +# test behavior of declare -g +${THIS_SH} ./builtins3.sub + +# test behavior of using declare to create variables without assigning values +${THIS_SH} ./builtins4.sub + +# test behavior of set and unset array variables +${THIS_SH} ./builtins5.sub + +# test behavior of unset builtin with -f and -v options +${THIS_SH} ./builtins6.sub + +# test behavior of command builtin after changing it to a pseudo-keyword +${THIS_SH} ./builtins7.sub + +# this must be last -- it is a fatal error +exit status + +echo after bad exit |