#! bash
[[ -n $BASH_COMPLETION_SCRIPT ]] && source "$BASH_COMPLETION_SCRIPT"

# This builtin only works in real completions, so stub it for the tests
compopt() { true; }

begin-test-suite() {
    print-binary-versions
    echo
}

end-test-suite() {
    true
}

begin-test() {
    echo "TEST: $1"
}

end-test() {
    local status=$?
    if [[ $status -eq 0 ]]; then
        echo '  PASS'
        echo
    else
        if [[ -n $_TEST_BINARIES ]]; then
            echo
            print-binary-versions
        fi
        exit $status
    fi
}

test-completion() {
    _COMPLETION_TEST=($@⇥)
    print-array '  INPUT:' "${_COMPLETION_TEST[@]}"
    COMP_WORDS=($@)
    COMP_CWORD=$(($# - 1))
    COMP_LINE="$*"
    COMP_POINT=${#COMP_LINE}
    "$_TEST_FN" "$1" "${@: -1}" "${@: -2:1}"
}

expect() {
    print-array '  EXPECTED RESULT:' "$@"
    local word
    for word in "$@"; do
        if ! [[ " ${COMPREPLY[@]} " =~ " $word " ]]; then
            echo '    Expectation failed!'
            print-array '    Output:' "${COMPREPLY[@]}"
            if [[ -n $COMPREPLY ]]; then
                echo "    Missing:    $(printf "%q" "$word")"
            fi
            exit 1
        fi >&2
    done
}

reject() {
    print-array '  SHOULD NOT INCLUDE:' "$@"
    local word
    for word in "$@"; do
        if [[ " ${COMPREPLY[@]} " =~ " $word " ]]; then
            echo '    Expectation failed!'
            print-array '    Output:' "${COMPREPLY[@]}"
            echo "    Unexpected: $(printf "%q" "$word")"
            exit 1
        fi >&2
    done
}

print-array() {
    printf '%-22s' "$1"
    if [[ $# -eq 1 ]]; then
        echo ' (empty)'
        return
    fi
    while [[ $# -gt 1 ]]; do
        shift
        printf ' %q' "$1"
    done
    echo
}

print-binary-versions() {
    echo 'Versions:'
    local bin
    for bin in "${_TEST_BINARIES[@]}"; do
        "$bin" --version || echo "\`$bin --version\` failed with status $?" >&2
    done
}
