#!/usr/bin/env bash set -uo pipefail declare -i FAILED=0 declare -i SUCCEDED=0 declare -i TODO=0 declare -i RAN=0 NAME="" EXTRAENV="" MINISHELL=$PWD/minishell 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 rm -rf /tmp/dir.minishell mkdir -p /tmp/dir.minishell pushd /tmp/dir.minishell > /dev/null env $EXTRAENV $MINISHELL &> /tmp/got.minishell < /tmp/input.minishell popd > /dev/null EXTRAENV="" 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 expecting <>] │ │ ├─ marker = [ ] │ │ ├─ flags = 0 │ │ ╰─ t_token_type = OUT_APPEND_REDIR_TOKEN │ ├─ t_worddesc │ │ ├─ word = [>] │ │ ├─ marker = [ ] │ │ ├─ flags = 0 │ │ ╰─ t_token_type = OUT_TRUNC_REDIR_TOKEN │ ├─ t_worddesc │ │ ├─ word = [<<] │ │ ├─ marker = [ ] │ │ ├─ flags = 0 │ │ ╰─ t_token_type = HERE_DOC_REDIR_TOKEN │ ╰─ t_worddesc │ ├─ word = [<] │ ├─ marker = [ ] │ ├─ flags = 0 │ ╰─ t_token_type = IN_REDIR_TOKEN ╰─ redirections = (empty redir list) EOF when_run <" ">>" "<" "<<" EOF expecting <"] │ │ ├─ marker = [ " ] │ │ ├─ flags = 34 │ │ ╰─ t_token_type = WORD_TOKEN │ ├─ t_worddesc │ │ ├─ word = [">>"] │ │ ├─ marker = [ "" ] │ │ ├─ flags = 34 │ │ ╰─ t_token_type = WORD_TOKEN │ ├─ t_worddesc │ │ ├─ word = ["<"] │ │ ├─ marker = [ " ] │ │ ├─ flags = 34 │ │ ╰─ t_token_type = WORD_TOKEN │ ╰─ t_worddesc │ ├─ word = ["<<"] │ ├─ marker = [ "" ] │ ├─ flags = 34 │ ╰─ t_token_type = WORD_TOKEN ╰─ redirections = (empty redir list) EOF when_run <' '>>' '<' '<<' EOF expecting <'] │ │ ├─ marker = [ ' ] │ │ ├─ flags = 2 │ │ ╰─ t_token_type = WORD_TOKEN │ ├─ t_worddesc │ │ ├─ word = ['>>'] │ │ ├─ marker = [ '' ] │ │ ├─ flags = 2 │ │ ╰─ t_token_type = WORD_TOKEN │ ├─ t_worddesc │ │ ├─ word = ['<'] │ │ ├─ marker = [ ' ] │ │ ├─ flags = 2 │ │ ╰─ t_token_type = WORD_TOKEN │ ╰─ t_worddesc │ ├─ word = ['<<'] │ ├─ marker = [ '' ] │ ├─ flags = 2 │ ╰─ t_token_type = WORD_TOKEN ╰─ redirections = (empty redir list) EOF finalize