summaryrefslogtreecommitdiffstats
path: root/tests/builtins.tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/builtins.tests')
-rw-r--r--tests/builtins.tests284
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