From 4e7a63a8e669349bd03d9cf17207c251d1b05ec8 Mon Sep 17 00:00:00 2001 From: Wilhelm Schuermann Date: Mon, 20 Jul 2015 13:49:42 +0200 Subject: [PATCH] Tests: Include bash_tap.sh for quick Bash tests --- test/bash_tap.sh | 108 ++++++++++++++++++++++++++++++++++++++++++++ test/bash_tap_tw.sh | 63 ++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 test/bash_tap.sh create mode 100644 test/bash_tap_tw.sh diff --git a/test/bash_tap.sh b/test/bash_tap.sh new file mode 100644 index 000000000..43c2b4c5c --- /dev/null +++ b/test/bash_tap.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash +# For more information, see https://github.com/wbsch/bash_tap +# Subject to the MIT License. See LICENSE file or http://opensource.org/licenses/MIT +# Copyright (c) 2015 Wilhelm Schürmann + +function bashtap_on_error { + # A command in the parent script failed, interpret this as a test failure. + # $bashtap_line contains the last executed line, or an error. + echo -n "$bashtap_output" + echo "not ok 1 - ${bashtap_line}" + bashtap_clean_tmpdir +} + +function bashtap_run_testcase { + # Run each line in the parent script up to the first "exit". + bashtap_output="" + while IFS= read -r bashtap_line && [ "${bashtap_line:0:4}" != "exit" ]; do + # Skip shebang. + if [ "${bashtap_line:0:2}" == "#!" ]; then + continue + fi + + # Avoid recursively sourcing this script, and any helper scripts. + if [[ "$bashtap_line" =~ ^(\.|source).*(/|[[:blank:]])bash_tap[^/]*$ ]]; then + continue + fi + + # Include comments as-is. + if [ "${bashtap_line:0:1}" == "#" ]; then + bashtap_output+="$bashtap_line" + bashtap_output+=$'\n' + continue + fi + + # Run file line by line. + if [ ! -z "$bashtap_line" ] && [ "${bashtap_line:0:2}" != "#!" ]; then + bashtap_output+="# $ $bashtap_line" + bashtap_output+=$'\n' + local cmd_output + local cmd_ret + cmd_output=$(eval "$bashtap_line" 2>&1 | sed 's/^/# >>> /') + cmd_ret=$? + if [ ! -z "$cmd_output" ]; then + bashtap_output+="$cmd_output" + bashtap_output+=$'\n' + fi + if [ "$cmd_ret" -ne 0 ]; then + exit $cmd_ret + fi + fi + done <"$bashtap_org_script" +} + +function bashtap_clean_tmpdir { + if [ ! -z "$bashtap_tmpdir" ] && [ -d "$bashtap_tmpdir" ]; then + cd "$bashtap_org_pwd" + rm -rf "$bashtap_tmpdir" + fi +} + +function bashtap_get_absolute_path { + # NOTE: No actual thought put into this. Might break. Horribly. + # Using this instead of readlink/realpath for OSX compatibility. + echo $(cd "$(dirname "$1")" && pwd)/$(basename "$1") +} + + +bashtap_org_pwd=$(pwd) +bashtap_org_script=$(bashtap_get_absolute_path "$0") + +if [ "${0:(-2)}" == ".t" ] || [ "$1" == "-t" ]; then + # Make sure any failing commands are caught. + set -e + set -o pipefail + + # TAP header. Hardcoded number of tests, 1. + echo "1..1" + + # Output TAP failure on early exit. + trap bashtap_on_error EXIT + + # The different calls to mktemp are necessary for OSX compatibility. + bashtap_tmpdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'bash_tap') + if [ ! -z "$bashtap_tmpdir" ]; then + cd "$bashtap_tmpdir" + else + bashtap_line="Unable to create temporary directory." + exit 1 + fi + + # Scripts sourced before bash_tap.sh may declare this function. + if declare -f bashtap_setup >/dev/null; then + bashtap_setup + fi + + # Run test file interpreting failing commands as a test failure. + bashtap_run_testcase && echo "ok 1" + + # Since we're in a sourced file and just ran the parent script, + # exit without running it a second time. + trap - EXIT + bashtap_clean_tmpdir + exit +else + if declare -f bashtap_setup >/dev/null; then + bashtap_setup + fi +fi diff --git a/test/bash_tap_tw.sh b/test/bash_tap_tw.sh new file mode 100644 index 000000000..8b290769d --- /dev/null +++ b/test/bash_tap_tw.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# This file only contains helper functions for making Taskwarrior testing +# easier. The magic happens in bash_tap.sh sourced at the end of this file. +# +# "task" is a bash function calling "/path/to/compiled/task rc:taskrc" +# Only local paths are searched, see bash_tap_tw.sh:find_task_binary(). +# +# "taskrc" is a file set up in bash_tap_tw.sh:setup_taskrc(), and can be +# appended to or changed as needed. +# +# Subject to the MIT License. See LICENSE file or http://opensource.org/licenses/MIT +# Copyright (c) 2015 Wilhelm Schürmann + +function setup_taskrc { + # Configuration + for i in pending.data completed.data undo.data backlog.data taskrc; do + if [ -f "$i" ]; then + rm "$i" 2>&1 >/dev/null + fi + done + + echo 'data.location=.' > taskrc + echo 'confirmation=off' >> taskrc + echo 'dateformat=m/d/Y' >> taskrc + echo 'color.debug=rgb025' >> taskrc + echo 'color.header=rgb025' >> taskrc + echo 'color.footer=rgb025' >> taskrc + echo 'color.error=bold white on red' >> taskrc +} + +function find_task_binary { + # $bashtap_org_pwd is set in bash_tap.sh. It is the directory the parent script is + # run from. Check for the task binary relative to that directory. + # Do not use the system "task" if no local one is found, error out instead. + for t in "${bashtap_org_pwd}/task" "${bashtap_org_pwd}/src/task" "${bashtap_org_pwd}/../task" "${bashtap_org_pwd}/../src/task" "${bashtap_org_pwd}/../build/src/task"; do + if [ -f "$t" ] && [ -x "$t" ]; then + t_abs=$(bashtap_get_absolute_path "$t") + eval "function task { ${t_abs} rc:taskrc \$@; }" + return 0 + fi + done + + echo "# ERROR: Could not find task binary!" + + # Needed for normal, i.e. "non-test" mode. + eval "function task { exit; }" + + # Set $line so we can have useful TAP output. + line="bash_tap.sh:find_task_binary()" + + return 1 +} + +function bashtap_setup { + # This function is called by bash_tap.sh before running tests, or before + # running the parent script normally. + find_task_binary + setup_taskrc +} + + +# Include the base script that does the actual work. +source bash_tap.sh