Files
42_SIDE_minishell_test/unitests.sh
2021-12-14 23:14:53 +01:00

240 lines
5.4 KiB
Bash

#!/bin/bash
cd $(dirname $0)
MINISHELL="../minishell"
TEST_DIR="./tests/"
DEFAULT_DIR="./tests/defaults/"
# COLORS
RED="\e[0;31m"
GREEN="\e[0;32m"
YELLOW="\e[0;33m"
BLUE="\e[0;34m"
MAGENTA="\e[0;35m"
CYAN="\e[0;36m"
WHITE="\e[0;37m"
B_RED="\e[1;31m"
B_GREEN="\e[1;32m"
B_YELLOW="\e[1;33m"
B_BLUE="\e[1;34m"
B_MAGENTA="\e[1;35m"
B_CYAN="\e[1;36m"
B_WHITE="\e[1;37m"
ENDCO="\e[0m"
# copy the executable to current directory
cp $MINISHELL .
# globale variables
UNIT_TEST=0
SUCCESS_TEST=0
TOTAL_TEST=0
TOTAL_SUCCESS=0
LINE_NUMBER=0
FILES_BEFORE="$(ls .)"
mkdir -p ./logs
echo "" > ./logs/bash_log.txt
echo "" > ./logs/minishell_log.txt
BASH_LOG="./logs/bash_log.txt"
MINISHELL_LOG="./logs/minishell_log.txt"
# default list of files to be use
default_files="$( find $DEFAULT_DIR | tail -n+2 )"
# print usage
function print_usage
{
echo -en $GREEN"usage : "
echo -en $CYAN"bash unitest.sh [help] [files list ...]\n"
echo -en $GREEN"\n[help]\n"
echo -en $CYAN"print usage\n"
echo -en $GREEN"\n[files list ...] if empty, defaults files will be used :\n"
echo -en $CYAN"$default_files"
echo -en $ENDCO"\n"
echo ""
}
# to delete the files created during the script
function delete_files
{
FILES_AFTER="$(ls .)"
DIFF_FILES="$(comm -3 <(echo "$FILES_BEFORE") <(echo "$FILES_AFTER"))"
while read line_diff
do
rm -rf "$line_diff"
done < <(echo "$DIFF_FILES")
}
# check for arguments, like options or files list
# if no file in arguments, default file list is used
list_files="$default_files"
if [ $# -gt 0 ]
then
if [ "$1" == "help" ]
then
print_usage
delete_files
exit 0
else
list_files=""
for (( i = 1 ; i <= "$#" ; i++ ))
do
# the ! is for indirect parameter expansion
# $i expand in integers 1,2,3...
# $1,$2,$3... expand in arguments of process call
FILE="${!i%.sh}"
FILE="${FILE/%/.sh}"
if ! [ -e "$FILE" ]
then
FILE="${!i/#/$TEST_DIR}"
FILE="${FILE%.sh}"
FILE="${FILE/%/.sh}"
fi
if ! [ -e "$FILE" ]
then
FILE="${!i/#/$DEFAULT_DIR}"
FILE="${FILE%.sh}"
FILE="${FILE/%/.sh}"
fi
if [ -e "$FILE" ]
then
if [ -n "$list_files" ]
then
list_files+=$'\n'
fi
list_files+="$FILE"
else
print_usage
echo " <$FILE> is not a valid file or option, see usage above"
exit 0
fi
done
fi
fi
# if print option, print next command
function print_next_command
{
TEXT=$1
CMD=$2
COLOR=$3
INDENT="$(for (( i=1; i<=${#TEXT}; i++ )); do echo -n ' '; done)"
echo -en $COLOR"$TEXT"$YELLOW
echo -n "${CMD//$'\n'/$'\n'$INDENT}"
echo -e $ENDCO
}
# function that will launch the command in bash and minishell and compare them
function test_minishell
{
# execute commands in bash, and logs results
bash_execution=$( echo "$@" | bash 2>/dev/null )
minishell_execution=$( echo "$@" | ./minishell 2>/dev/null )
#compare output
if [ "$bash_execution" = "$minishell_execution" ]
then
(( SUCCESS_TEST++ ))
(( TOTAL_SUCCESS++ ))
else
ERROR_CMD="ERROR line $(( $LINE_NUMBER - 1 )), command : "
print_next_command "$ERROR_CMD" "$@" "$CYAN"
# print simple log
echo -e $B_WHITE"\n\n$@\n-----------"$ENDCO >>$BASH_LOG
echo "$bash_execution" >> $BASH_LOG
echo -e $B_WHITE"\n\n$@\n-----------"$ENDCO >>$MINISHELL_LOG
echo "$minishell_execution" >> $MINISHELL_LOG
fi
}
# function to print the results
# receive parameters : file name, numerator, denominator
function print_results
{
echo -en $B_WHITE"results for $1 : "$ENDCO
if [ $2 -eq 0 ]
then
echo -en $B_RED $2 $ENDCO
elif [ $2 -eq $3 ]
then
echo -en $B_GREEN $2 $ENDCO
else
echo -en $B_MAGENTA $2 $ENDCO
fi
echo -e $B_WHITE"/ $3"$ENDCO
}
# the main loop: go through the files and call the compare func on each commands
# parse tests files line by line, grouping lines non-separated by an empty line
# if line start with # it's ignore
for i in $list_files
do
filename=$i
echo -e "\n"$B_YELLOW"test file : $i"$ENDCO
command_test=""
LINE_NUMBER=0
LAST_LINE_NUMBER=$(wc -l < $filename)
UNIT_TEST=0
SUCCESS_TEST=0
# write name of file in log files
echo -en $B_YELLOW "\n\n\nfile: $filename\n" $ENDCO >>$BASH_LOG
echo -en $B_YELLOW "\n\n\nfile: $filename\n" $ENDCO >>$MINISHELL_LOG
# do the loop
while read line
do
(( LINE_NUMBER++ ))
if [ -n "$line" ]
then
# if line start with # skip it
if [ "${line:0:1}" != "#" ]
then
if [ "$command_test" == "" ]
then
command_test="$line"
else
command_test+=$'\n'
command_test+="$line"
fi
if [ $LINE_NUMBER -eq $LAST_LINE_NUMBER ]
then
(( UNIT_TEST++ ))
(( TOTAL_TEST++ ))
test_minishell "$command_test"
fi
fi
elif [ -z "$line" ] && [ -n "$command_test" ]
then
(( UNIT_TEST++ ))
(( TOTAL_TEST++ ))
test_minishell "$command_test"
command_test=""
fi
done < $filename
print_results $i $SUCCESS_TEST $UNIT_TEST
done
# print the total results
if [ -n "$list_files" ]
then
echo ""
print_results "all" $TOTAL_SUCCESS $TOTAL_TEST
fi
# ask to show the diff
# -rsn1 will stop read after first key pressed
if [ $TOTAL_SUCCESS -lt $TOTAL_TEST ]
then
read -rsn1 -p 'if you want to see the diff, press "y"' DIFF
if [[ "${DIFF,,}" == y ]]
then
diff -y --width=100 --color=always "$BASH_LOG" "$MINISHELL_LOG"
fi
fi
# delete files created during tests
delete_files