diff --git a/assert-extras.sh b/assert-extras.sh new file mode 100644 index 0000000..9a7fcb2 --- /dev/null +++ b/assert-extras.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +# assert-extras.sh 1.1 - supplementary bash unit testing functions +# Note: This script should be sourced together with assert.sh, +# it is dependent on the functionality provided by that script. + +assert_success() { + assert_raises "$@" 0 +} + +# assert_failure [stdin] +assert_failure() { + (( tests_ran++ )) || : + [[ -z "$DISCOVERONLY" ]] || return + status=0 + (eval "$1" <<< ${2:-}) > /dev/null 2>&1 || status=$? + if [[ "$status" != "0" ]]; then + [[ -z "$DEBUG" ]] || echo -n . + return + fi + _assert_fail "program terminated with a zero return code;" \ + "expecting non-zero return code" "$1" "$2" +} + +# assert_contains +assert_contains() { + _assert_with_grep '-F' "$@" +} + +# assert_matches +assert_matches() { + _assert_with_grep '-E' "$@" +} + +# assert_startswith +assert_startswith() { + assert_success "[[ '$($1)' == '$2'* ]]" +} + +# assert_endswith +assert_endswith() { + assert_success "[[ '$($1)' == *'$2' ]]" +} + +# _assert_with_grep +_assert_with_grep() { + local grep_modifier="$1" + local output="$($2)" + shift 2 + + while [ $# != 0 ]; do + assert_raises "echo '$output' | $GREP $grep_modifier '$1'" 0 || return 1 + shift + done +} + +# Returns the resolved command, preferring any gnu-versions of the cmd (prefixed with 'g') on +# non-Linux systems such as Mac OS, and falling back to the standard version if not. +_cmd() { + local cmd="$1" + + local gnu_cmd="g$cmd" + local gnu_cmd_found=$(which "$gnu_cmd" 2> /dev/null) + if [ "$gnu_cmd_found" ]; then + echo "$gnu_cmd_found" + else + if [ "$(uname)" == 'Darwin' ]; then + echo "Warning: Cannot find gnu version of command '$cmd' ($gnu_cmd) on path." \ + "Falling back to standard command" >&2 + fi + echo "cmd" + fi +} + +GREP=$(_cmd grep) +SED=$(_cmd sed) \ No newline at end of file diff --git a/test-extras.sh b/test-extras.sh new file mode 100755 index 0000000..a45eaa9 --- /dev/null +++ b/test-extras.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash + +source assert.sh +source assert-extras.sh + +assert "echo foo" "foo" +assert_raises "true" 0 +assert_raises "exit 127" 127 + +assert_end sanity + +### +### assert_success tests +### + +# Tests expecting success +assert_success "true" +assert_success "echo foo" + +# Tests expecting failure +assert_raises 'assert_success "false"' 1 +assert_raises 'assert_success "exit 1"' 1 + +assert_end assert_success + +### +### assert_failure tests +### + +# Tests expecting success +assert_failure "false" +assert_failure "exit 1" +assert_failure "exit -1" +assert_failure "exit 42" +assert_failure "exit -42" + +# Tests expecting failure +assert_raises 'assert_failure "true"' 1 +assert_raises 'assert_failure "echo foo"' 1 + +assert_end assert_failure + +### +### assert_contains tests +### + +# Tests expecting success +assert_contains "echo foo" "foo" +assert_contains "echo foobar" "foo" +assert_contains "echo foo bar" "foo" +assert_contains "echo foo bar" "bar" +assert_contains "echo foo bar" "foo bar" + +# Tests expecting failure +assert_failure 'assert_contains "echo foo" "foot"' +assert_failure 'assert_contains "echo foo" "f.."' + +# Multi-word argument tests +assert_contains "echo foo bar" "foo bar" +assert_failure 'assert_contains "echo foo; echo bar" "foo bar"' + +# Multi-argument tests +assert_contains "echo foo bar baz" "foo" "baz" +assert_failure 'assert_contains "echo foo bar baz" "bar" "foo baz"' + +assert_end assert_contains + +### +### assert_matches tests +### + +# Tests expecting success +assert_matches "echo foo" "f.." +assert_matches "echo foobar" "f." +assert_matches "echo foo bar" "^foo bar$" +assert_matches "echo foo bar" "[az ]+" + +# Tests expecting failure +assert_failure 'assert_matches "echo foot" "foo$"' + +# Multi-word argument tests +assert_matches "echo foo bar" "foo .*" +assert_failure 'assert_matches "echo foo; echo bar" "foo .*"' + +# Multi-argument tests +assert_matches "echo foo bar baz" "^f.." "baz$" +assert_failure 'assert_matches "echo foo bar baz" "bar" "foo baz"' + +assert_end assert_matches + +### +### assert_startswith tests +### + +# Tests expecting success +assert_startswith "echo foo" "f" +assert_startswith "echo foo" "foo" +assert_startswith "echo foo; echo bar" "foo" + +# Tests expecting failure +assert_failure 'assert_startswith "echo foo" "oo"' +assert_failure 'assert_startswith "echo foo; echo bar" "foo bar"' +assert_failure 'assert_startswith "echo foo" "."' + +assert_end assert_startswith + +### +### assert_endswith tests +### + +# Tests expecting success +assert_endswith "echo foo" "oo" +assert_endswith "echo foo" "foo" +assert_endswith "echo foo; echo bar" "bar" + +# Tests expecting failure +assert_failure 'assert_endswith "echo foo" "f"' +assert_failure 'assert_endswith "echo foo; echo bar" "foo bar"' +assert_failure 'assert_endswith "echo foo" "."' + +assert_end assert_endswith \ No newline at end of file