#!/usr/bin/env bash # Automatic tests for rdlink # Two kinds of tests are supported # * `tocompete` : competition between readlink and rdlink # * `toassert` : assert expected path and input path # test_rdlink.sh [OPTIONS] [PATH TO COMPETE] # [OPTIONS] # -a, --run-all : Run all tests (failed and successful) # -o, --only-result : Show only result (input <> expected) # # Internal tests will be executed if no arguments are found readonly test_dir="$(cd "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" readonly tool_rdlink="${test_dir}/../rdlink.sh" readonly tool_readlink="$(command -v readlink) -f" readonly config_path_width=45 readonly color_red='\033[1;31m' readonly color_yellow='\033[1;33m' readonly color_green='\033[1;32m' readonly color_less='\033[0m' flag_runall=0 flag_onlyresult=0 flag_verbose=0 toassert=() tocompete=() . "${test_dir}/totest.sh" # rl::testcmp # Compare results and print summary rl::testcmp() { local testnum="${1:-0}" local input="${2:-"-"}" local expect="${3:-"-"}" local actual="${4:-"-"}" local testresult=0 #failed local testresult_graphic="${color_red}✗${color_less}" # alt. symbol ≠ [[ "${expect}" == "${actual}" ]] && testresult=1 && testresult_graphic="${color_green}✔${color_less}" # alt. symbol ✓ # Show only reslult as quick overview if (( flag_onlyresult )); then # Change result graphic if test failed (( ! testresult )) && testresult_graphic="→" # "${color_green}→${color_less}" # Truncate input string on the left if longer than $config_path_width (( ${#input} > ${config_path_width} )) && input="<-${input:$(( ${#input} - ${config_path_width} + 2 ))}" # Print input and expected printf "%${config_path_width}s %b %s\n" "${input}" "${testresult_graphic}" "${expect}" # Print actual result if test failed if (( ! testresult )); then printf "%$((config_path_width))s %b %s\n" " " "${color_red}✗${color_less}" "${actual}" return 1 fi return 0 fi printf -- "%-3d Inp: %-${config_path_width}s ---" ${testnum} "${input}" printf " %b\n" "${testresult_graphic}" if (( ! testresult )); then # Test failed printf " Result: %s\n Exp: %s\n" "${actual}" "${expect}" if (( flag_verbose )); then [ -e "${input}" ] && printf "\n Subject:\n" && ls -al "${input}" # Print debug output of tool_a printf "\n Debug:\n" ( "${tool_rdlink}" -d "${input}" ) fi return 1 fi return 0 } rl::test() { local i=0 local path= local arraywalker= local firstelement= local testend=0 local arg= for arg in "$@"; do case "$1" in --) ## End of options shift && break ;; -a|--run-all) ## Run all even if tests fail flag_runall=1 shift ;; -o|--only-result) flag_onlyresult=1 shift ;; -v|--verbose) flag_verbose=1 shift ;; esac done # Only run `compete_args` if arguments are available if [[ "$@" ]]; then compete_args=( "Tests from command line" "$@" ) (( flag_runall )) && tocompete+=(compete_args) || tocompete=(compete_args) toassert=() fi # Compare against expected result printf "\n# Assertion tests (\"Expected path\" == rdlink)\n" for testarray in "${toassert[@]}"; do i=0 arraywalker="$testarray"[@] for path in "${!arraywalker}"; do if (( ! i )); then # Print title in array element 0 printf " ### %b ###\n" "${color_yellow}${path}${color_less}" (( flag_onlyresult )) && printf "%${config_path_width}s %s %s\n" "" "" "✗ [ACTUAL]" elif [ -z "$firstelement" ]; then # Save first element for string compare firstelement="${path}" else # Do the compare between two following elements if ! rl::testcmp "$((i-1))" "${firstelement}" \ "${path}" "$("$tool_rdlink" "${firstelement}")"; then # Run all tests if option -a is pressend (( ! $flag_runall )) && testend=1 && break fi firstelement= fi ((i++)) done (( testend )) && return 1 done # Compare output of rdlink and readlink -f printf "\n# Competition tests (readlink -f == rdlink)\n" for testarray in "${tocompete[@]}"; do i=0 arraywalker="$testarray"[@] for path in "${!arraywalker}"; do if (( ! i )); then # Print title in array element 0 printf " ### %b ###\n" "${color_yellow}${path}${color_less}" (( flag_onlyresult )) && printf "%${config_path_width}s %s %s\n" "" "" "✗ [ACTUAL]" else # Execute tests if ! rl::testcmp "${i}" "${path}" \ "$(${tool_readlink} "$path")" "$(${tool_rdlink} "$path")"; then # Run all tests if option -a is pressend (( ! $flag_runall )) && testend=1 && break fi fi ((i++)) done (( testend )) && return 1 done } time rl::test "$@"