mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
318 lines
9.9 KiB
Bash
Executable file
318 lines
9.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
set -uo pipefail
|
|
|
|
declare -i FAILED=0
|
|
declare -i SUCCEDED=0
|
|
declare -i TODTODO=0
|
|
declare -i RAN=0
|
|
NAME=""
|
|
|
|
report_header()
|
|
{
|
|
echo "++++++++++++++++++++++++++++++++++++++++++++++++++++"
|
|
echo $NAME
|
|
echo "++++++++++++++++++++++++++++++++++++++++++++++++++++"
|
|
echo "++++ test input:"
|
|
}
|
|
|
|
failed_report()
|
|
{
|
|
NAME="failed: $NAME"
|
|
report_header
|
|
cat /tmp/input.minishell
|
|
echo "++++ Got output:"
|
|
cat /tmp/got.minishell
|
|
echo "++++ But expected:"
|
|
cat /tmp/expected.minishell
|
|
echo "++++ Diff:"
|
|
echo "(red is got, green is expected)"
|
|
diff --color=always /tmp/got.minishell /tmp/expected.minishell
|
|
echo "++++ Run this to debug:"
|
|
cat < /tmp/input.minishell > /tmp/input.failed.$FAILED.minishell
|
|
echo "cat /tmp/input.failed.$FAILED.minishell | ./minishell"
|
|
}
|
|
|
|
todo_report()
|
|
{
|
|
NAME="todo: $NAME"
|
|
report_header
|
|
cat /tmp/input.minishell
|
|
echo "++++ Got output:"
|
|
cat /tmp/got.minishell
|
|
echo "++++ But test was marked as todo."
|
|
echo "++++ Run this to debug:"
|
|
cat < /tmp/input.minishell > /tmp/input.todo.$TODO.minishell
|
|
echo "cat /tmp/input.todo.$TODO.minishell | ./minishell"
|
|
}
|
|
|
|
failed()
|
|
{
|
|
echo -n "F"
|
|
FAILED+=1
|
|
failed_report >> report.txt
|
|
}
|
|
|
|
succeded()
|
|
{
|
|
echo -n "."
|
|
SUCCEDED+=1
|
|
}
|
|
|
|
assert()
|
|
{
|
|
diff -q /tmp/got.minishell /tmp/expected.minishell > /dev/null && succeded || failed
|
|
}
|
|
|
|
when_run()
|
|
{
|
|
cat > /tmp/input.minishell
|
|
./minishell &> /tmp/got.minishell < /tmp/input.minishell
|
|
RAN+=1
|
|
NAME=$1
|
|
}
|
|
|
|
expecting()
|
|
{
|
|
cat > /tmp/expected.minishell
|
|
assert
|
|
}
|
|
|
|
todo()
|
|
{
|
|
echo -n "t"
|
|
TODO+=1
|
|
todo_report >> report.txt
|
|
}
|
|
|
|
setup()
|
|
{
|
|
rm -f report.txt
|
|
}
|
|
|
|
finalize()
|
|
{
|
|
echo
|
|
echo "$RAN tests ran. $SUCCEDED succeded, $FAILED failed, $TODO todo."
|
|
if [ $SUCCEDED -eq $RAN ];
|
|
then
|
|
echo "All integration tests passed!"
|
|
else
|
|
echo "cat report.txt"
|
|
echo "to see details of failed/todo tests"
|
|
fi
|
|
exit $FAILED
|
|
}
|
|
|
|
setup
|
|
|
|
when_run <<EOF "empty inputs returns nothing"
|
|
|
|
EOF
|
|
expecting <<EOF
|
|
EOF
|
|
|
|
when_run <<EOF "simple command is parsed"
|
|
echo hello
|
|
EOF
|
|
expecting <<EOF
|
|
╰─ t_cmdgroup
|
|
├─ t_cmdlist
|
|
│ ├─ num_cmds = 1
|
|
│ ╰─ cmd[0]
|
|
│ ├─ t_cmdlist_item
|
|
│ │ ╰─ t_pipeline
|
|
│ │ ├─ num_cmd = 1
|
|
│ │ ╰─ cmd[0]
|
|
│ │ ╰─ t_simple_cmd
|
|
│ │ ├─ words = [echo][hello]
|
|
│ │ ╰─ (no redirections)
|
|
│ ╰─ t_operator = END
|
|
╰─ (no redirections)
|
|
EOF
|
|
|
|
when_run <<EOF "single redirection is parsed"
|
|
echo hello>outfile
|
|
EOF
|
|
expecting <<EOF
|
|
╰─ t_cmdgroup
|
|
├─ t_cmdlist
|
|
│ ├─ num_cmds = 1
|
|
│ ╰─ cmd[0]
|
|
│ ├─ t_cmdlist_item
|
|
│ │ ╰─ t_pipeline
|
|
│ │ ├─ num_cmd = 1
|
|
│ │ ╰─ cmd[0]
|
|
│ │ ╰─ t_simple_cmd
|
|
│ │ ├─ words = [echo][hello]
|
|
│ │ ╰─ t_redir_list
|
|
│ │ ╰─ redirection[0]
|
|
│ │ ╰─ t_redirection
|
|
│ │ ├─ t_redir_type = REDIR_OUTPUT
|
|
│ │ ╰─ marker = [outfile]
|
|
│ ╰─ t_operator = END
|
|
╰─ (no redirections)
|
|
EOF
|
|
|
|
when_run <<EOF "redirections are parsed"
|
|
echo hello < in hi > out
|
|
EOF
|
|
expecting <<EOF
|
|
╰─ t_cmdgroup
|
|
├─ t_cmdlist
|
|
│ ├─ num_cmds = 1
|
|
│ ╰─ cmd[0]
|
|
│ ├─ t_cmdlist_item
|
|
│ │ ╰─ t_pipeline
|
|
│ │ ├─ num_cmd = 1
|
|
│ │ ╰─ cmd[0]
|
|
│ │ ╰─ t_simple_cmd
|
|
│ │ ├─ words = [echo][hello][hi]
|
|
│ │ ╰─ t_redir_list
|
|
│ │ ├─ redirection[0]
|
|
│ │ │ ╰─ t_redirection
|
|
│ │ │ ├─ t_redir_type = REDIR_INPUT
|
|
│ │ │ ╰─ marker = [in]
|
|
│ │ ╰─ redirection[1]
|
|
│ │ ╰─ t_redirection
|
|
│ │ ├─ t_redir_type = REDIR_OUTPUT
|
|
│ │ ╰─ marker = [out]
|
|
│ ╰─ t_operator = END
|
|
╰─ (no redirections)
|
|
EOF
|
|
|
|
when_run <<EOF "multiple redirections are parsed"
|
|
echo << HERE_DOC hello>outfile there < infile < infile2 >> append
|
|
EOF
|
|
expecting <<EOF
|
|
╰─ t_cmdgroup
|
|
├─ t_cmdlist
|
|
│ ├─ num_cmds = 1
|
|
│ ╰─ cmd[0]
|
|
│ ├─ t_cmdlist_item
|
|
│ │ ╰─ t_pipeline
|
|
│ │ ├─ num_cmd = 1
|
|
│ │ ╰─ cmd[0]
|
|
│ │ ╰─ t_simple_cmd
|
|
│ │ ├─ words = [echo][hello][there]
|
|
│ │ ╰─ t_redir_list
|
|
│ │ ├─ redirection[0]
|
|
│ │ │ ╰─ t_redirection
|
|
│ │ │ ├─ t_redir_type = REDIR_HERE_DOC
|
|
│ │ │ ╰─ marker = [HERE_DOC]
|
|
│ │ ├─ redirection[1]
|
|
│ │ │ ╰─ t_redirection
|
|
│ │ │ ├─ t_redir_type = REDIR_OUTPUT
|
|
│ │ │ ╰─ marker = [outfile]
|
|
│ │ ├─ redirection[2]
|
|
│ │ │ ╰─ t_redirection
|
|
│ │ │ ├─ t_redir_type = REDIR_INPUT
|
|
│ │ │ ╰─ marker = [infile]
|
|
│ │ ├─ redirection[3]
|
|
│ │ │ ╰─ t_redirection
|
|
│ │ │ ├─ t_redir_type = REDIR_INPUT
|
|
│ │ │ ╰─ marker = [infile2]
|
|
│ │ ╰─ redirection[4]
|
|
│ │ ╰─ t_redirection
|
|
│ │ ├─ t_redir_type = REDIR_APPEND
|
|
│ │ ╰─ marker = [append]
|
|
│ ╰─ t_operator = END
|
|
╰─ (no redirections)
|
|
EOF
|
|
|
|
when_run <<EOF "a single command in parentheses is has the parenthesis implicitly removed"
|
|
(echo hi)
|
|
EOF
|
|
# this is how it is handled in bash:
|
|
# doing a `ps uf` on bash running `sleep 10`
|
|
# \_ bash --norc
|
|
# \_ sleep 10
|
|
# and `(sleep 10)`
|
|
# \_ bash --norc
|
|
# \_ sleep 10
|
|
# this is exactly the same process graph
|
|
expecting <<EOF
|
|
╰─ t_cmdgroup
|
|
├─ t_cmdlist
|
|
│ ├─ num_cmds = 1
|
|
│ ╰─ cmd[0]
|
|
│ ├─ t_cmdlist_item
|
|
│ │ ╰─ t_pipeline
|
|
│ │ ├─ num_cmd = 1
|
|
│ │ ╰─ cmd[0]
|
|
│ │ ╰─ t_simple_cmd
|
|
│ │ ├─ words = [echo][hi]
|
|
│ │ ╰─ (no redirections)
|
|
│ ╰─ t_operator = END
|
|
╰─ (no redirections)
|
|
EOF
|
|
|
|
when_run <<EOF "a single cmdlist in parenthesis has the parenthesis implicitly removed"
|
|
(echo hi >> append | echo < infile bye && echo hello > outfile)
|
|
EOF
|
|
expecting <<EOF
|
|
╰─ t_cmdgroup
|
|
├─ t_cmdlist
|
|
│ ├─ num_cmds = 2
|
|
│ ├─ cmd[0]
|
|
│ │ ├─ t_cmdlist_item
|
|
│ │ │ ╰─ t_pipeline
|
|
│ │ │ ├─ num_cmd = 2
|
|
│ │ │ ├─ cmd[0]
|
|
│ │ │ │ ╰─ t_simple_cmd
|
|
│ │ │ │ ├─ words = [echo][hi]
|
|
│ │ │ │ ╰─ t_redir_list
|
|
│ │ │ │ ╰─ redirection[0]
|
|
│ │ │ │ ╰─ t_redirection
|
|
│ │ │ │ ├─ t_redir_type = REDIR_APPEND
|
|
│ │ │ │ ╰─ marker = [append]
|
|
│ │ │ ╰─ cmd[1]
|
|
│ │ │ ╰─ t_simple_cmd
|
|
│ │ │ ├─ words = [echo][bye]
|
|
│ │ │ ╰─ t_redir_list
|
|
│ │ │ ╰─ redirection[0]
|
|
│ │ │ ╰─ t_redirection
|
|
│ │ │ ├─ t_redir_type = REDIR_INPUT
|
|
│ │ │ ╰─ marker = [infile]
|
|
│ │ ╰─ t_operator = AND
|
|
│ ╰─ cmd[1]
|
|
│ ├─ t_cmdlist_item
|
|
│ │ ╰─ t_pipeline
|
|
│ │ ├─ num_cmd = 1
|
|
│ │ ╰─ cmd[0]
|
|
│ │ ╰─ t_simple_cmd
|
|
│ │ ├─ words = [echo][hello]
|
|
│ │ ╰─ t_redir_list
|
|
│ │ ╰─ redirection[0]
|
|
│ │ ╰─ t_redirection
|
|
│ │ ├─ t_redir_type = REDIR_OUTPUT
|
|
│ │ ╰─ marker = [outfile]
|
|
│ ╰─ t_operator = END
|
|
╰─ (no redirections)
|
|
EOF
|
|
|
|
when_run <<EOF "quotes are removed"
|
|
echo "this contains quotes"
|
|
EOF
|
|
expecting <<EOF
|
|
╰─ t_cmdgroup
|
|
├─ t_cmdlist
|
|
│ ├─ num_cmds = 1
|
|
│ ╰─ cmd[0]
|
|
│ ├─ t_cmdlist_item
|
|
│ │ ╰─ t_pipeline
|
|
│ │ ├─ num_cmd = 1
|
|
│ │ ╰─ cmd[0]
|
|
│ │ ╰─ t_simple_cmd
|
|
│ │ ├─ words = [echo][this contains quotes]
|
|
│ │ ╰─ (no redirections)
|
|
│ ╰─ t_operator = END
|
|
╰─ (no redirections)
|
|
EOF
|
|
|
|
when_run <<EOF "quoted parentheses are not operators"
|
|
echo unclosed '('
|
|
EOF
|
|
todo
|
|
|
|
finalize
|