bd
is a bash script to conveniently jump multiple directory levels up from the current working directory instead of a tedious and possibly inaccurate cd ../../../..
Say, for example, that you are in the directory /home/user/project/src/org/main
and you want to jump to project
. Instead of counting the necessary levels to jump and typing cd ../../..
, you can do bd -s pro
(where -s
is to match the start of the directory name, in this example "pro" for "project").
I came across this script in another question, and looking at the github repository I decided to jazz it up a little. But before going ahead and refactoring it, I wanted to make sure I'm not breaking anything, so I needed some sort of unit tests as a sane baseline first.
This is the main function in the bd
script under testing,
and this is not for code review,
I'm including it here only for your reference in case it helps in some way:
# NOT for code review: the reference implementation under test
newpwd() {
OLDPWD=$1
if [ "$2" = "-s" ]
then
NEWPWD=`echo $OLDPWD | sed 's|\(.*/'$3'[^/]*/\).*|\1|'`
index=`echo $NEWPWD | awk '{ print index($0,"/'$3'"); }'`
elif [ "$2" = "-si" ]
then
NEWPWD=`echo $OLDPWD | sed 's|\(.*/'$3'[^/]*/\).*|\1|I'`
index=`echo $NEWPWD | awk '{ print index(tolower($0),tolower("/'$3'")); }'`
else
NEWPWD=`echo $OLDPWD | sed 's|\(.*/'$2'/\).*|\1|'`
index=`echo $NEWPWD | awk '{ print index($1,"/'$2'/"); }'`
fi
}
What I'd like reviewed is my implementation of "unit tests" to verify the behavior of the newpwd
function inside the bd
script:
#!/bin/bash
# loading the "newpwd" function from the bd script, a necessary ugliness for now
. bd nonexistent > /dev/null
success=0
failure=0
total=0
assertEquals() {
((total++))
expected=$1
actual=$2
if [[ $expected = $actual ]]; then
((success++))
else
((failure++))
echo "Assertion failed: $expected != $actual" >&2
caller 0
echo
fi
}
sample=/home/user/project/src/org/main/site/utils/file/reader/whatever
# test run with no args
newpwd $sample
assertEquals $sample $NEWPWD
assertEquals 0 $index
# test run with exact match
newpwd $sample src
assertEquals /home/user/project/src/ $NEWPWD
assertEquals 19 $index
# test run with prefix but no -s so not found
newpwd $sample sr
assertEquals $sample $NEWPWD
assertEquals 0 $index
# test run with prefix found
newpwd $sample -s sr
assertEquals /home/user/project/src/ $NEWPWD
assertEquals 19 $index
# test run with prefix not found because case sensitive
newpwd $sample -s Sr
assertEquals $sample $NEWPWD
assertEquals 0 $index
# test run with prefix found thanks to -si
newpwd $sample -si Sr
assertEquals /home/user/project/src/ $NEWPWD
assertEquals 19 $index
sample='/home/user/my project/src'
# test run with space in dirname
newpwd "$sample" -s my
assertEquals '/home/user/my project/' "$NEWPWD"
assertEquals 11 $index
red='\e[0;31m'
green='\e[0;32m'
nocolor='\e[0m'
echo
[[ $failure = 0 ]] && printf $green || printf $red
echo "Tests run: $total ($success success, $failure failed)"
printf $nocolor
echo
My questions:
- Is this easy to read? If not, how to improve it?
- Is this a good way to test stuff in Bash? Is there a better way? I'd rather not add external dependencies to the project though, I'm looking for something ultra-light, or a technique
- Are there any corner cases I missed?
- Any other improvement ideas?