blob: 42fbf72445b38a15212899c1860e26164e9a1a0d [file] [log] [blame]
#
# A suite of tests for bash word expansions
#
# This tests parameter and variable expansion, with an empahsis on
# proper quoting behavior.
#
# Chet Ramey
#
# If you comment out the body of this function, you can do a diff against
# `expansion-tests.right' to see if the shell is behaving correctly
#
expect()
{
echo expect "$@"
}
# Test the substitution quoting characters (CTLESC and CTLNUL) in different
# combinations
expect "<^A>"
recho `echo ''`
expect "<^A>"
recho `echo ""`
expect "<^B>"
recho `echo ''`
expect "<^B>"
recho `echo ""`
expect "<^A>"
recho `echo `
expect "<^B>"
recho `echo `
# Test null strings without variable expansion
expect "<abcdefgh>"
recho abcd""efgh
expect "<abcdefgh>"
recho abcd''efgh
expect "<abcdefgh>"
recho ""abcdefgh
expect "<abcdefgh>"
recho ''abcdefgh
expect "<abcd>"
recho abcd""
expect "<abcd>"
recho abcd''
# Test the quirky behavior of $@ in ""
expect nothing
recho "$@"
expect "< >"
recho " $@"
expect "<-->"
recho "-${@}-"
# Test null strings with variable expansion that fails
expect '<>'
recho $xxx""
expect '<>'
recho ""$xxx
expect '<>'
recho $xxx''
expect '<>'
recho ''$xxx
expect '<>'
recho $xxx""$yyy
expect '<>'
recho $xxx''$yyy
# Test null strings with variable expansion that succeeds
xxx=abc
yyy=def
expect '<abc>'
recho $xxx""
expect '<abc>'
recho ""$xxx
expect '<abc>'
recho $xxx''
expect '<abc>'
recho ''$xxx
expect '<abcdef>'
recho $xxx""$yyy
expect '<abcdef>'
recho $xxx''$yyy
unset xxx yyy
# Test the unquoted special quoting characters
expect "<^A>"
recho 
expect "<^B>"
recho 
expect "<^A>"
recho ""
expect "<^B>"
recho ""
expect "<^A>"
recho ''
expect "<^B>"
recho ''
# Test expansion of a variable that is unset
expect nothing
recho $xxx
expect '<>'
recho "$xxx"
expect nothing
recho "$xxx${@}"
# Test empty string expansion
expect '<>'
recho ""
expect '<>'
recho ''
# Test command substitution with (disabled) history substitution
expect '<Hello World!>'
# set +H
recho "`echo \"Hello world!\"`"
# Test some shell special characters
expect '<`>'
recho "\`"
expect '<">'
recho "\""
expect '<\^A>'
recho "\"
expect '<\$>'
recho "\\$"
expect '<\\>'
recho "\\\\"
# This should give argv[1] = a argv[2] = b
expect '<a> <b>'
FOO=`echo 'a b' | tr ' ' '\012'`
recho $FOO
# This should give argv[1] = ^A argv[2] = ^B
expect '<^A> <^B>'
FOO=`echo ' ' | tr ' ' '\012'`
recho $FOO
# Test quoted and unquoted globbing characters
expect '<**>'
recho "*"*
expect '<\.\./*/>'
recho "\.\./*/"
# Test patterns that come up when the shell quotes funny character
# combinations
expect '<^A^B^A^B>'
recho ''
expect '<^A^A>'
recho ''
expect '<^A^B>'
recho ''
expect '<^A^A^B>'
recho ''
# More tests of "$@"
set abc def ghi jkl
expect '< abc> <def> <ghi> <jkl >'
recho " $@ "
expect '< abc> <def> <ghi> <jkl >'
recho "${1+ $@ }"
set abc def ghi jkl
expect '<--abc> <def> <ghi> <jkl-->'
recho "--$@--"
set "a b" cd ef gh
expect '<a b> <cd> <ef> <gh>'
recho ${1+"$@"}
expect '<a b> <cd> <ef> <gh>'
recho ${foo:-"$@"}
expect '<a b> <cd> <ef> <gh>'
recho "${@}"
expect '< >'
recho " "
expect '< - >'
recho " - "
# Test combinations of different types of quoting in a fully-quoted string
# (so the WHOLLY_QUOTED tests fail and it doesn't get set)
expect '</^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>'
recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/"
# Test the various Posix parameter expansions
expect '<foo bar>'
recho "${x:-$(echo "foo bar")}"
expect '<foo> <bar>'
recho ${x:-$(echo "foo bar")}
unset X
expect '<abc>'
recho ${X:=abc}
expect '<abc>'
recho $X
set a b c
expect '<posix>'
recho ${3:+posix}
POSIX=/usr/posix
expect '<10>'
recho ${#POSIX}
# remove shortest trailing match
x=file.c
expect '<file.o>'
recho ${x%.c}.o
# remove longest trailing match
x=posix/src/std
expect '<posix>'
recho ${x%%/*}
# remove shortest leading pattern
x=$HOME/src/cmd
expect '</src/cmd>'
recho ${x#$HOME}
# remove longest leading pattern
x=/one/two/three
expect '<three>'
recho ${x##*/}
# pattern removal of patterns that don't match
z=abcdef
expect '<abcdef>'
recho ${z#xyz}
expect '<abcdef>'
recho ${z##xyz}
expect '<abcdef>'
recho ${z%xyz}
expect '<abcdef>'
recho ${z%%xyz}
# Command substitution and the quirky differences between `` and $()
expect '<\$x>'
recho '\$x'
expect '<$x>'
recho `echo '\$x'`
expect '<\$x>'
recho $(echo '\$x')
# The difference between $* "$*" and "$@"
set "abc" "def ghi" "jkl"
expect '<abc> <def> <ghi> <jkl>'
recho $*
expect '<abc def ghi jkl>'
recho "$*"
OIFS="$IFS"
IFS=":$IFS"
# The special behavior of "$*", using the first character of $IFS as separator
expect '<abc:def ghi:jkl>'
recho "$*"
IFS="$OIFS"
expect '<abc> <def ghi> <jkl>'
recho "$@"
expect '<xxabc> <def ghi> <jklyy>'
recho "xx$@yy"
expect '<abc> <def ghi> <jklabc> <def ghi> <jkl>'
recho "$@$@"
foo=abc
bar=def
expect '<abcdef>'
recho "$foo""$bar"
unset foo
set $foo bar '' xyz "$foo" abc
expect '<bar> <> <xyz> <> <abc>'
recho "$@"
# More tests of quoting and deferred evaluation
foo=10 x=foo
y='$'$x
expect '<$foo>'
recho $y
eval y='$'$x
expect '<10>'
recho $y
# case statements
NL='
'
x='ab
cd'
expect '<newline expected>'
case "$x" in
*$NL*) recho "newline expected" ;;
esac
expect '<got it>'
case \? in
*"?"*) recho "got it" ;;
esac
expect '<got it>'
case \? in
*\?*) recho "got it" ;;
esac
set one two three four five
expect '<one> <three> <five>'
recho $1 $3 ${5} $8 ${9}
# length tests on positional parameters and some special parameters
expect '<5> <5>'
recho $# ${#}
expect '<3>'
recho ${#1}
expect '<1>'
recho ${##}
expect '<1>'
recho ${#?}
expect '<5>'
recho ${#@}
expect '<5>'
recho ${#*}
expect '<5>'
recho "${#@}"
expect '<5>'
recho "${#*}"
expect '<42>'
recho $((28 + 14))
expect '<26>'
recho $[ 13 * 2 ]
expect '<\>'
recho `echo \\\\`
expect '<~>'
recho '~'
expect nothing
recho $!
expect nothing
recho ${!}
# test word splitting of assignment statements not preceding a command
a="a b c d e"
declare b=$a
expect '<a> <b> <c> <d> <e>'
recho $b
a="a?b?c"
echo ${a//\\?/ }
echo ${a//\?/ }
${THIS_SH} ./exp1.sub
${THIS_SH} ./exp2.sub