#!/usr/bin/env bash # CONSTANTS # functions function assert { ((test_count++)) cmd="./test/stub/scenario.bash $1" if $cmd >/dev/null 2>/dev/null 3>_miaou; then if [[ -s _miaou ]]; then echo -n . return fi fi echo -n F failures+=("$cmd") return 1 } # assert performing '$1:script' successfully + output must contain '$2:content' # in case of extra args (4th position or more) must be provided after -- (3rd position) # 1: script # 2: content # 3: -- # 4..: extra args function assert_grep { ((test_count++)) local script="$1" content="$2" extra_args=() [[ $# -gt 3 ]] && shift 3 && extra_args=("$@") cmd="./test/stub/scenario.bash $script" if $cmd "${extra_args[@]}" >_stdout 2>/dev/null 3>/dev/null; then if grep -q "$content" _stdout; then echo -n . return fi fi echo -n F #TODO: quote extra_args for i in "${extra_args[@]}"; do safe_args+=$(printf '%q ' "$i"); done failures+=("$cmd $safe_args") return 1 } function fail_type { ((test_count++)) local success regex hint_message success=false hint_message="${3:-}" cmd="./test/stub/scenario.bash $1" # mapfile -t stderr <<<"$(miaou-bash ./test/stub/scenario.bash "$1" 2>&1 >/dev/null 3>/dev/null)" $cmd >/dev/null 2>_stderr 3>_miaou mapfile -t stderr <_stderr last_error="${stderr[-1]}" regex="^(.*): line ([0-9]+): miaou_error: $2 ([0-9]+)" [[ "${last_error}" =~ $regex ]] && success=true if [[ $success == true && -n "${hint_message}" ]]; then grep -q "${hint_message}" _miaou || success=false fi if [[ $success == true ]]; then echo -n . return fi echo -n F failures+=("$cmd") return 1 } function fail_stderr_count { ((test_count++)) local regex count="$2" cmd="./test/stub/scenario.bash $1" # mapfile -t stderr <<<"$(miaou-bash ./test/stub/scenario.bash "$1" 2>&1 >/dev/null 3>/dev/null)" if ! $cmd >/dev/null 2>_stderr 3>/dev/null; then mapfile -t stderr <_stderr if [[ "${#stderr[@]}" == "$count" ]]; then echo -n . return fi fi echo -n F failures+=("$cmd 2>_stderr") return 1 } function fail_miaou_count { ((test_count++)) local regex count="$2" cmd="./test/stub/scenario.bash $1" # mapfile -t stderr <<<"$(miaou-bash ./test/stub/scenario.bash "$1" 2>&1 >/dev/null 3>/dev/null)" if ! $cmd >/dev/null 2>/dev/null 3>_miaou; then mapfile -t miaou <_miaou if [[ "${#miaou[@]}" == "$count" ]]; then echo -n . return fi fi echo -n F failures+=("$cmd 3>_miaou") return 1 } # main set -uo pipefail test_count=0 failures=() TIMEFORMAT=$'\nelapsed: %Rs' time { assert success assert exit_0 assert_grep success_with_args 'count args: 2' -- 'A B' C fail_type subshell_term SUBSHELL_ERROR fail_type unbound_variable UNBOUND_VARIABLE fail_type unbound_associative UNBOUND_VARIABLE fail_type false FALSE fail_type last_false COMMAND_ERROR fail_type command_error COMMAND_ERROR fail_type subshell_term SUBSHELL_ERROR fail_type exit EXIT fail_type command_not_found COMMAND_NOT_FOUND fail_type source_not_found SOURCE_NOT_FOUND fail_type file_not_found FILE_NOT_FOUND fail_type child_error CHILD_ERROR 'prefer source than child process' fail_stderr_count unbound_variable 1 fail_stderr_count child_error 4 fail_miaou_count command_error_multiline 6 } failed=${#failures[@]} success=$((test_count - failed)) if [[ $failed -gt 0 ]]; then ratio=$((100 * success / test_count)) echo "${ratio}% passed, ${test_count} tests, ${failed} failed!" echo failures: for failure in "${failures[@]}"; do echo -e "\t- $failure" done exit 1 else echo "100% passed, ${test_count} tests" fi