From 4108c598c5c82b4d58c721078757d91ac2fd07d4 Mon Sep 17 00:00:00 2001 From: Emmanuel Valverde Ramos Date: Thu, 17 Oct 2024 16:14:40 +0200 Subject: [PATCH 1/4] chore: add test that covers the source of a file and check that the spies work --- src/test_doubles.sh | 29 ++++++++++++++++++ tests/unit/fixtures/fake_function_to_spy.sh | 3 ++ tests/unit/test_doubles_test.sh | 33 +++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 tests/unit/fixtures/fake_function_to_spy.sh diff --git a/src/test_doubles.sh b/src/test_doubles.sh index c450fa16..597c3a17 100644 --- a/src/test_doubles.sh +++ b/src/test_doubles.sh @@ -96,3 +96,32 @@ function assert_have_been_called_times() { state::add_assertions_passed } + + +# Spy function that wraps around a target function and logs calls +function spy_on() { + local target_function="$1" + + # Ensure the target function exists + if ! declare -f "$target_function" > /dev/null; then + echo "Function '$target_function' does not exist." + return 1 + fi + + # Create spy variables to track calls and arguments + eval "__${target_function}_call_count=0" + eval "__${target_function}_args=()" + + # Create a wrapper function to spy on calls + eval " + ${target_function}() { + # Increment the call count + __${target_function}_call_count=\$((__${target_function}_call_count + 1)) + + # Save the arguments + __${target_function}_args+=(\"\$*\") + + # Call the original function + $(declare -f "$target_function" | tail -n +2) + }" +} diff --git a/tests/unit/fixtures/fake_function_to_spy.sh b/tests/unit/fixtures/fake_function_to_spy.sh new file mode 100644 index 00000000..22d78cbe --- /dev/null +++ b/tests/unit/fixtures/fake_function_to_spy.sh @@ -0,0 +1,3 @@ +function function_to_be_spied_on(){ + echo "this function should be spy and not execute" +} diff --git a/tests/unit/test_doubles_test.sh b/tests/unit/test_doubles_test.sh index 9c9e489a..d9dcb0fb 100644 --- a/tests/unit/test_doubles_test.sh +++ b/tests/unit/test_doubles_test.sh @@ -65,3 +65,36 @@ function test_unsuccessful_spy_called_times() { "$(console_results::print_failed_test "Unsuccessful spy called times" "ps" "to has been called" "1 times")"\ "$(assert_have_been_called_times 1 ps)" } + +function test_successful_spy_with_source_function() { + source ./fixtures/fake_function_to_spy.sh + spy function_to_be_spied_on + + function_to_be_spied_on + + assert_have_been_called function_to_be_spied_on +} + +function test_unsuccessful_spy_with_source_function_have_been_called() { + source ./fixtures/fake_function_to_spy.sh + spy function_to_be_spied_on + + function_to_be_spied_on + function_to_be_spied_on + + assert_same\ + "$(console_results::print_failed_test "Unsuccessful spy with source function have been called" "function_to_be_spied_on" "to has been called" "1 times")"\ + "$(assert_have_been_called_times 1 function_to_be_spied_on)" +} + + +function test_successful_spy_called_times_with_source() { + source ./fixtures/fake_function_to_spy.sh + spy function_to_be_spied_on + + function_to_be_spied_on + function_to_be_spied_on + + assert_have_been_called_times 2 function_to_be_spied_on +} + From 43c49fcea69eaa2357d1ef0fd6c6418c470edb7c Mon Sep 17 00:00:00 2001 From: Emmanuel Valverde Ramos Date: Thu, 17 Oct 2024 18:15:20 +0200 Subject: [PATCH 2/4] chore: remove unused code and pass shellcheck --- install.sh | 2 +- src/test_doubles.sh | 28 --------------------- tests/unit/console_results_test.sh | 1 - tests/unit/fixtures/fake_function_to_spy.sh | 2 ++ tests/unit/test_doubles_test.sh | 3 +++ 5 files changed, 6 insertions(+), 30 deletions(-) diff --git a/install.sh b/install.sh index f158d959..ee328ecb 100755 --- a/install.sh +++ b/install.sh @@ -24,7 +24,7 @@ function build_and_install_beta() { exit 1 fi - git clone --depth 1 --no-tags $BASHUNIT_GIT_REPO temp_bashunit 2>/dev/null + git clone --depth 1 --no-tags "$BASHUNIT_GIT_REPO" temp_bashunit 2>/dev/null cd temp_bashunit ./build.sh >/dev/null local latest_commit=$(git rev-parse --short=7 HEAD) diff --git a/src/test_doubles.sh b/src/test_doubles.sh index 597c3a17..a149e527 100644 --- a/src/test_doubles.sh +++ b/src/test_doubles.sh @@ -97,31 +97,3 @@ function assert_have_been_called_times() { state::add_assertions_passed } - -# Spy function that wraps around a target function and logs calls -function spy_on() { - local target_function="$1" - - # Ensure the target function exists - if ! declare -f "$target_function" > /dev/null; then - echo "Function '$target_function' does not exist." - return 1 - fi - - # Create spy variables to track calls and arguments - eval "__${target_function}_call_count=0" - eval "__${target_function}_args=()" - - # Create a wrapper function to spy on calls - eval " - ${target_function}() { - # Increment the call count - __${target_function}_call_count=\$((__${target_function}_call_count + 1)) - - # Save the arguments - __${target_function}_args+=(\"\$*\") - - # Call the original function - $(declare -f "$target_function" | tail -n +2) - }" -} diff --git a/tests/unit/console_results_test.sh b/tests/unit/console_results_test.sh index d1f99fe2..1cb6e5a5 100644 --- a/tests/unit/console_results_test.sh +++ b/tests/unit/console_results_test.sh @@ -297,7 +297,6 @@ function test_render_execution_time_on_osx_without_perl() { mock dependencies::has_perl mock_false _START_TIME=1727771758.0664479733 - EPOCHREALTIME=1727780556.4266040325 local render_result render_result=$( diff --git a/tests/unit/fixtures/fake_function_to_spy.sh b/tests/unit/fixtures/fake_function_to_spy.sh index 22d78cbe..1c630364 100644 --- a/tests/unit/fixtures/fake_function_to_spy.sh +++ b/tests/unit/fixtures/fake_function_to_spy.sh @@ -1,3 +1,5 @@ +#!/bin/bash + function function_to_be_spied_on(){ echo "this function should be spy and not execute" } diff --git a/tests/unit/test_doubles_test.sh b/tests/unit/test_doubles_test.sh index d9dcb0fb..43068910 100644 --- a/tests/unit/test_doubles_test.sh +++ b/tests/unit/test_doubles_test.sh @@ -67,6 +67,7 @@ function test_unsuccessful_spy_called_times() { } function test_successful_spy_with_source_function() { + # shellcheck source=/dev/null source ./fixtures/fake_function_to_spy.sh spy function_to_be_spied_on @@ -76,6 +77,7 @@ function test_successful_spy_with_source_function() { } function test_unsuccessful_spy_with_source_function_have_been_called() { + # shellcheck source=/dev/null source ./fixtures/fake_function_to_spy.sh spy function_to_be_spied_on @@ -89,6 +91,7 @@ function test_unsuccessful_spy_with_source_function_have_been_called() { function test_successful_spy_called_times_with_source() { + # shellcheck source=/dev/null source ./fixtures/fake_function_to_spy.sh spy function_to_be_spied_on From 1555ded4da5f517da1957208f09cf7a5e46b193b Mon Sep 17 00:00:00 2001 From: Emmanuel Valverde Ramos Date: Thu, 17 Oct 2024 18:21:10 +0200 Subject: [PATCH 3/4] style: fix editorconfig lenght --- tests/unit/test_doubles_test.sh | 6 +- tmp/temp.sh | 262 ++++++++++++++++++++++++++++++++ 2 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 tmp/temp.sh diff --git a/tests/unit/test_doubles_test.sh b/tests/unit/test_doubles_test.sh index 43068910..6e6748d3 100644 --- a/tests/unit/test_doubles_test.sh +++ b/tests/unit/test_doubles_test.sh @@ -85,7 +85,11 @@ function test_unsuccessful_spy_with_source_function_have_been_called() { function_to_be_spied_on assert_same\ - "$(console_results::print_failed_test "Unsuccessful spy with source function have been called" "function_to_be_spied_on" "to has been called" "1 times")"\ + "$(console_results::print_failed_test \ + "Unsuccessful spy with source function have been called"\ + "function_to_be_spied_on" \ + "to has been called" \ + "1 times")"\ "$(assert_have_been_called_times 1 function_to_be_spied_on)" } diff --git a/tmp/temp.sh b/tmp/temp.sh new file mode 100644 index 00000000..4f40f4e6 --- /dev/null +++ b/tmp/temp.sh @@ -0,0 +1,262 @@ +#!/bin/bash +# check_os.sh + +# shellcheck disable=SC2034 +_OS="Unknown" +_DISTRO="Unknown" + +function check_os::init() { + if check_os::is_linux; then + _OS="Linux" + if check_os::is_ubuntu; then + _DISTRO="Ubuntu" + elif check_os::is_alpine; then + _DISTRO="Alpine" + else + _DISTRO="Other" + fi + elif check_os::is_macos; then + _OS="OSX" + elif check_os::is_windows; then + _OS="Windows" + else + _OS="Unknown" + _DISTRO="Unknown" + fi +} + +function check_os::is_ubuntu() { + command -v apt > /dev/null +} + +function check_os::is_alpine() { + command -v apk > /dev/null +} + +function check_os::is_linux() { + [[ "$(uname)" == "Linux" ]] +} + +function check_os::is_macos() { + [[ "$(uname)" == "Darwin" ]] +} + +function check_os::is_windows() { + [[ "$(uname)" == *"MINGW"* ]] +} + +function check_os::is_busybox() { + + case "$_DISTRO" in + + "Alpine") + return 0 + ;; + *) + return 1 + ;; + esac +} + +check_os::init + +export _OS +export _DISTRO +export -f check_os::is_alpine +export -f check_os::is_busybox +export -f check_os::is_ubuntu + +# str.sh + +function str::rpad() { + local left_text="$1" + local right_word="$2" + local width_padding="${3:-$TERMINAL_WIDTH}" + # Subtract 1 more to account for the extra space + local padding=$((width_padding - ${#right_word} - 1)) + + # Remove ANSI escape sequences (non-visible characters) for length calculation + # shellcheck disable=SC2155 + local clean_left_text=$(echo -e "$left_text" | sed 's/\x1b\[[0-9;]*m//g') + + local is_truncated=false + # If the visible left text exceeds the padding, truncate it and add "..." + if [[ ${#clean_left_text} -gt $padding ]]; then + local truncation_length=$((padding - 3)) # Subtract 3 for "..." + clean_left_text="${clean_left_text:0:$truncation_length}" + is_truncated=true + fi + + # Rebuild the text with ANSI codes intact, preserving the truncation + local result_left_text="" + local i=0 + local j=0 + while [[ $i -lt ${#clean_left_text} && $j -lt ${#left_text} ]]; do + local char="${clean_left_text:$i:1}" + local original_char="${left_text:$j:1}" + + # If the current character is part of an ANSI sequence, skip it and copy it + if [[ "$original_char" == $'\x1b' ]]; then + while [[ "${left_text:$j:1}" != "m" && $j -lt ${#left_text} ]]; do + result_left_text+="${left_text:$j:1}" + ((j++)) + done + result_left_text+="${left_text:$j:1}" # Append the final 'm' + ((j++)) + elif [[ "$char" == "$original_char" ]]; then + # Match the actual character + result_left_text+="$char" + ((i++)) + ((j++)) + else + ((j++)) + fi + done + + local remaining_space + if $is_truncated ; then + result_left_text+="..." + # 1: due to a blank space + # 3: due to the appended ... + remaining_space=$((width_padding - ${#clean_left_text} - ${#right_word} - 1 - 3)) + else + # Copy any remaining characters after the truncation point + result_left_text+="${left_text:$j}" + remaining_space=$((width_padding - ${#clean_left_text} - ${#right_word} - 1)) + fi + + # Ensure the right word is placed exactly at the far right of the screen + # filling the remaining space with padding + if [[ $remaining_space -lt 0 ]]; then + remaining_space=0 + fi + + printf "%s%${remaining_space}s %s\n" "$result_left_text" "" "$right_word" +} + +# globals.sh +set -euo pipefail + +# This file provides a set of global functions to developers. + +function current_dir() { + dirname "${BASH_SOURCE[1]}" +} + +function current_filename() { + basename "${BASH_SOURCE[1]}" +} + +function caller_filename() { + dirname "${BASH_SOURCE[2]}" +} + +function caller_line() { + echo "${BASH_LINENO[1]}" +} + +function current_timestamp() { + date +"%Y-%m-%d %H:%M:%S" +} + +function is_command_available() { + command -v "$1" >/dev/null 2>&1 +} + +function random_str() { + local length=${1:-6} + local chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' + local str='' + for (( i=0; i> "$BASHUNIT_DEV_LOG" +} + +# dependencies.sh +set -euo pipefail + +function dependencies::has_perl() { + command -v perl >/dev/null 2>&1 +} + +function dependencies::has_powershell() { + command -v powershell > /dev/null 2>&1 +} + +function dependencies::has_adjtimex() { + command -v adjtimex >/dev/null 2>&1 +} + +function dependencies::has_bc() { + command -v bc >/dev/null 2>&1 +} + +function dependencies::has_awk() { + command -v awk >/dev/null 2>&1 +} + +function dependencies::has_git() { + command -v git >/dev/null 2>&1 +} + +function dependencies::has_curl() { + command -v curl >/dev/null 2>&1 +} + +function dependencies::has_wget() { + command -v wget >/dev/null 2>&1 +} + +# io.sh + +function io::download_to() { + local url="$1" + local output="$2" + if dependencies::has_curl; then + curl -L -J -o "$output" "$url" 2>/dev/null + elif dependencies::has_wget; then + wget -q -O "$output" "$url" 2>/dev/null + else + return 1 + fi +} + +# math.sh From 98c9dfa6bb0ff7c90166df24ff3d2195127a1542 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Thu, 17 Oct 2024 18:45:22 +0200 Subject: [PATCH 4/4] fix: remove tmp file --- tmp/temp.sh | 262 ---------------------------------------------------- 1 file changed, 262 deletions(-) delete mode 100644 tmp/temp.sh diff --git a/tmp/temp.sh b/tmp/temp.sh deleted file mode 100644 index 4f40f4e6..00000000 --- a/tmp/temp.sh +++ /dev/null @@ -1,262 +0,0 @@ -#!/bin/bash -# check_os.sh - -# shellcheck disable=SC2034 -_OS="Unknown" -_DISTRO="Unknown" - -function check_os::init() { - if check_os::is_linux; then - _OS="Linux" - if check_os::is_ubuntu; then - _DISTRO="Ubuntu" - elif check_os::is_alpine; then - _DISTRO="Alpine" - else - _DISTRO="Other" - fi - elif check_os::is_macos; then - _OS="OSX" - elif check_os::is_windows; then - _OS="Windows" - else - _OS="Unknown" - _DISTRO="Unknown" - fi -} - -function check_os::is_ubuntu() { - command -v apt > /dev/null -} - -function check_os::is_alpine() { - command -v apk > /dev/null -} - -function check_os::is_linux() { - [[ "$(uname)" == "Linux" ]] -} - -function check_os::is_macos() { - [[ "$(uname)" == "Darwin" ]] -} - -function check_os::is_windows() { - [[ "$(uname)" == *"MINGW"* ]] -} - -function check_os::is_busybox() { - - case "$_DISTRO" in - - "Alpine") - return 0 - ;; - *) - return 1 - ;; - esac -} - -check_os::init - -export _OS -export _DISTRO -export -f check_os::is_alpine -export -f check_os::is_busybox -export -f check_os::is_ubuntu - -# str.sh - -function str::rpad() { - local left_text="$1" - local right_word="$2" - local width_padding="${3:-$TERMINAL_WIDTH}" - # Subtract 1 more to account for the extra space - local padding=$((width_padding - ${#right_word} - 1)) - - # Remove ANSI escape sequences (non-visible characters) for length calculation - # shellcheck disable=SC2155 - local clean_left_text=$(echo -e "$left_text" | sed 's/\x1b\[[0-9;]*m//g') - - local is_truncated=false - # If the visible left text exceeds the padding, truncate it and add "..." - if [[ ${#clean_left_text} -gt $padding ]]; then - local truncation_length=$((padding - 3)) # Subtract 3 for "..." - clean_left_text="${clean_left_text:0:$truncation_length}" - is_truncated=true - fi - - # Rebuild the text with ANSI codes intact, preserving the truncation - local result_left_text="" - local i=0 - local j=0 - while [[ $i -lt ${#clean_left_text} && $j -lt ${#left_text} ]]; do - local char="${clean_left_text:$i:1}" - local original_char="${left_text:$j:1}" - - # If the current character is part of an ANSI sequence, skip it and copy it - if [[ "$original_char" == $'\x1b' ]]; then - while [[ "${left_text:$j:1}" != "m" && $j -lt ${#left_text} ]]; do - result_left_text+="${left_text:$j:1}" - ((j++)) - done - result_left_text+="${left_text:$j:1}" # Append the final 'm' - ((j++)) - elif [[ "$char" == "$original_char" ]]; then - # Match the actual character - result_left_text+="$char" - ((i++)) - ((j++)) - else - ((j++)) - fi - done - - local remaining_space - if $is_truncated ; then - result_left_text+="..." - # 1: due to a blank space - # 3: due to the appended ... - remaining_space=$((width_padding - ${#clean_left_text} - ${#right_word} - 1 - 3)) - else - # Copy any remaining characters after the truncation point - result_left_text+="${left_text:$j}" - remaining_space=$((width_padding - ${#clean_left_text} - ${#right_word} - 1)) - fi - - # Ensure the right word is placed exactly at the far right of the screen - # filling the remaining space with padding - if [[ $remaining_space -lt 0 ]]; then - remaining_space=0 - fi - - printf "%s%${remaining_space}s %s\n" "$result_left_text" "" "$right_word" -} - -# globals.sh -set -euo pipefail - -# This file provides a set of global functions to developers. - -function current_dir() { - dirname "${BASH_SOURCE[1]}" -} - -function current_filename() { - basename "${BASH_SOURCE[1]}" -} - -function caller_filename() { - dirname "${BASH_SOURCE[2]}" -} - -function caller_line() { - echo "${BASH_LINENO[1]}" -} - -function current_timestamp() { - date +"%Y-%m-%d %H:%M:%S" -} - -function is_command_available() { - command -v "$1" >/dev/null 2>&1 -} - -function random_str() { - local length=${1:-6} - local chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' - local str='' - for (( i=0; i> "$BASHUNIT_DEV_LOG" -} - -# dependencies.sh -set -euo pipefail - -function dependencies::has_perl() { - command -v perl >/dev/null 2>&1 -} - -function dependencies::has_powershell() { - command -v powershell > /dev/null 2>&1 -} - -function dependencies::has_adjtimex() { - command -v adjtimex >/dev/null 2>&1 -} - -function dependencies::has_bc() { - command -v bc >/dev/null 2>&1 -} - -function dependencies::has_awk() { - command -v awk >/dev/null 2>&1 -} - -function dependencies::has_git() { - command -v git >/dev/null 2>&1 -} - -function dependencies::has_curl() { - command -v curl >/dev/null 2>&1 -} - -function dependencies::has_wget() { - command -v wget >/dev/null 2>&1 -} - -# io.sh - -function io::download_to() { - local url="$1" - local output="$2" - if dependencies::has_curl; then - curl -L -J -o "$output" "$url" 2>/dev/null - elif dependencies::has_wget; then - wget -q -O "$output" "$url" 2>/dev/null - else - return 1 - fi -} - -# math.sh