diff --git a/.env.example b/.env.example index 164a2c57..e69de29b 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +0,0 @@ -PARALLEL_RUN= - diff --git a/bashunit b/bashunit index ca02a7af..2269317e 100755 --- a/bashunit +++ b/bashunit @@ -5,6 +5,7 @@ readonly BASH_UNIT_ROOT_DIR="$(dirname "${BASH_SOURCE[0]}")" source "$BASH_UNIT_ROOT_DIR/src/default_env_config.sh" source "$BASH_UNIT_ROOT_DIR/src/env_configuration.sh" source "$BASH_UNIT_ROOT_DIR/src/check_os.sh" +source "$BASH_UNIT_ROOT_DIR/src/state.sh" source "$BASH_UNIT_ROOT_DIR/src/colors.sh" source "$BASH_UNIT_ROOT_DIR/src/console_results.sh" source "$BASH_UNIT_ROOT_DIR/src/helpers.sh" diff --git a/bin/pre-commit b/bin/pre-commit index 1b68b3a0..49cef02f 100755 --- a/bin/pre-commit +++ b/bin/pre-commit @@ -4,7 +4,7 @@ echo "Running pre-commit checks..." make pre_commit/run EXIT_CODE=$? -if [ ${EXIT_CODE} -ne 0 ]; then +if [[ ${EXIT_CODE} -ne 0 ]]; then echo "Pre Commit checks failed. Please fix the above issues before committing" exit ${EXIT_CODE} else diff --git a/src/assert.sh b/src/assert.sh index 3f6fea1e..676464ae 100755 --- a/src/assert.sh +++ b/src/assert.sh @@ -6,12 +6,12 @@ function assertEquals() { local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" if [[ "$expected" != "$actual" ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${expected}" "but got" "${actual}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "${expected}" "but got" "${actual}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertEmpty() { @@ -19,12 +19,12 @@ function assertEmpty() { local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" if [[ "$expected" != "" ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "to be empty" "but got" "${expected}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "to be empty" "but got" "${expected}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertNotEmpty() { @@ -32,12 +32,12 @@ function assertNotEmpty() { local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" if [[ "$expected" == "" ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "to not be empty" "but got" "${expected}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "to not be empty" "but got" "${expected}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertNotEquals() { @@ -46,12 +46,12 @@ function assertNotEquals() { local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" if [[ "$expected" == "$actual" ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${expected}" "but got" "${actual}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "${expected}" "but got" "${actual}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertContains() { @@ -60,12 +60,12 @@ function assertContains() { local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" if ! [[ $actual == *"$expected"* ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual}" "to contain" "${expected}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual}" "to contain" "${expected}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertNotContains() { @@ -74,12 +74,12 @@ function assertNotContains() { local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" if [[ $actual == *"$expected"* ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual}" "to not contain" "${expected}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual}" "to not contain" "${expected}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertMatches() { @@ -88,12 +88,12 @@ function assertMatches() { local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" if ! [[ $actual =~ $expected ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual}" "to match" "${expected}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual}" "to match" "${expected}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertNotMatches() { @@ -102,12 +102,12 @@ function assertNotMatches() { local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" if [[ $actual =~ $expected ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual}" "to not match" "${expected}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual}" "to not match" "${expected}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertExitCode() { @@ -115,13 +115,13 @@ function assertExitCode() { local expected_exit_code="$1" local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" - if [ $actual_exit_code -ne "$expected_exit_code" ]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual_exit_code}" "to be" "${expected_exit_code}" + if [[ $actual_exit_code -ne "$expected_exit_code" ]]; then + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual_exit_code}" "to be" "${expected_exit_code}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertSuccessfulCode() { @@ -129,13 +129,13 @@ function assertSuccessfulCode() { local expected_exit_code=0 local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" - if [[ $actual_exit_code != "$expected_exit_code" ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual_exit_code}" "to be exactly" "${expected_exit_code}" + if [[ $actual_exit_code -ne "$expected_exit_code" ]]; then + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual_exit_code}" "to be exactly" "${expected_exit_code}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertGeneralError() { @@ -143,13 +143,13 @@ function assertGeneralError() { local expected_exit_code=1 local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" - if [ $actual_exit_code -ne "$expected_exit_code" ]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual_exit_code}" "to be exactly" "${expected_exit_code}" + if [[ $actual_exit_code -ne "$expected_exit_code" ]]; then + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual_exit_code}" "to be exactly" "${expected_exit_code}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } @@ -158,13 +158,13 @@ function assertCommandNotFound() { local expected_exit_code=127 local label="${3:-$(Helper::normalizeTestFunctionName "${FUNCNAME[1]}")}" - if [ $actual_exit_code -ne "$expected_exit_code" ]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual_exit_code}" "to be exactly" "${expected_exit_code}" + if [[ $actual_exit_code -ne "$expected_exit_code" ]]; then + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual_exit_code}" "to be exactly" "${expected_exit_code}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertArrayContains() { @@ -174,12 +174,12 @@ function assertArrayContains() { local actual=("$@") if ! [[ "${actual[*]}" == *"$expected"* ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual[*]}" "to contain" "${expected}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual[*]}" "to contain" "${expected}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } function assertArrayNotContains() { @@ -189,10 +189,10 @@ function assertArrayNotContains() { local actual=("$@") if [[ "${actual[*]}" == *"$expected"* ]]; then - ((_ASSERTIONS_FAILED++)) - Console::printFailedTest "${label}" "${actual[*]}" "to not contain" "${expected}" + State::addAssertionsFailed + Console::printFailedTest "${label}" "${actual[*]}" "to not contain" "${expected}" return fi - ((_ASSERTIONS_PASSED++)) + State::addAssertionsPassed } diff --git a/src/check_os.sh b/src/check_os.sh index ed540939..b7025493 100644 --- a/src/check_os.sh +++ b/src/check_os.sh @@ -3,9 +3,9 @@ # shellcheck disable=SC2034 _OS="Unknown" -if [ "$(uname)" == "Linux" ]; then +if [[ "$(uname)" == "Linux" ]]; then _OS="Linux" -elif [ "$(uname)" == "Darwin" ]; then +elif [[ "$(uname)" == "Darwin" ]]; then _OS="OSX" elif [[ $(uname) == *"MINGW"* ]]; then _OS="Windows" diff --git a/src/console_results.sh b/src/console_results.sh index 4a4a8f25..ff3aed4f 100644 --- a/src/console_results.sh +++ b/src/console_results.sh @@ -1,10 +1,6 @@ #!/bin/bash _START_TIME=$(date +%s%N); -_TESTS_PASSED=0 -_TESTS_FAILED=0 -_ASSERTIONS_PASSED=0 -_ASSERTIONS_FAILED=0 function Console::renderResult() { local tests_passed=$1 @@ -46,7 +42,7 @@ function Console::renderResult() { } function Console::printExecutionTime() { - if [ "$_OS" != "OSX" ]; then + if [[ "$_OS" != "OSX" ]]; then _EXECUTION_TIME=$((($(date +%s%N) - "$_START_TIME") / 1000000)) printf "${_COLOR_BOLD}%s${_COLOR_DEFAULT}\n" "Time taken: ${_EXECUTION_TIME} ms" fi @@ -70,6 +66,3 @@ ${_COLOR_FAILED}✗ Failed${_COLOR_DEFAULT}: %s "${test_name}" "${expected}" "${failure_condition_message}" "${actual}" } - -# Set a trap to call renderResult when the script exits -trap 'Console::renderResult $_TESTS_PASSED $_TESTS_FAILED $_ASSERTIONS_PASSED $_ASSERTIONS_FAILED' EXIT diff --git a/src/default_env_config.sh b/src/default_env_config.sh index 7ecbc970..5893beab 100644 --- a/src/default_env_config.sh +++ b/src/default_env_config.sh @@ -1,2 +1,4 @@ #!/bin/bash -export _DEFAULT_PARALLEL_RUN=false + +# shellcheck disable=SC2034 +_DEFAULT_PARALLEL_RUN=false diff --git a/src/env_configuration.sh b/src/env_configuration.sh index e304c4cc..8dfc63d9 100644 --- a/src/env_configuration.sh +++ b/src/env_configuration.sh @@ -5,6 +5,6 @@ set -o allexport [[ -f ".env" ]] && source .env set set +o allexport -if [ -z "$PARALLEL_RUN" ]; then +if [[ -z "$PARALLEL_RUN" ]]; then PARALLEL_RUN=$_DEFAULT_PARALLEL_RUN fi diff --git a/src/runner.sh b/src/runner.sh index 51a0794b..baf031cd 100755 --- a/src/runner.sh +++ b/src/runner.sh @@ -11,14 +11,11 @@ function Runner::callTestFunctions() { # shellcheck disable=SC2207 functions_to_run=($(Helper::getFunctionsToRun "$prefix" "$filter" "$function_names")) - if [ "${#functions_to_run[@]}" -gt 0 ]; then + if [[ "${#functions_to_run[@]}" -gt 0 ]]; then echo "Running $script" for function_name in "${functions_to_run[@]}"; do - if [ "$PARALLEL_RUN" == true ] ; then - Runner::runTest "$function_name" & - else - Runner::runTest "$function_name" - fi + Runner::runTest "$function_name" + unset "$function_name" done fi @@ -26,19 +23,43 @@ function Runner::callTestFunctions() { function Runner::runTest() { local function_name="$1" - local current_assertions_failed="$_ASSERTIONS_FAILED" + local current_assertions_failed + current_assertions_failed="$(State::getAssertionsFailed)" Runner::runSetUp "$function_name" Runner::runTearDown - if [ "$current_assertions_failed" == "$_ASSERTIONS_FAILED" ]; then - ((_TESTS_PASSED++)) - local label="${3:-$(Helper::normalizeTestFunctionName "$function_name")}" - Console::printSuccessfulTest "${label}" - else - ((_TESTS_FAILED++)) + if [[ "$current_assertions_failed" != "$(State::getAssertionsFailed)" ]]; then + State::addTestsFailed + return fi + + local label="${3:-$(Helper::normalizeTestFunctionName "$function_name")}" + Console::printSuccessfulTest "${label}" + State::addTestsPassed +} + +function Runner::loadTestFiles() { + if [[ ${#_FILES[@]} -eq 0 ]]; then + echo "Error: At least one file path is required." + echo "Usage: $0 " + exit 1 + fi + + for test_file in "${_FILES[@]}"; do + if [[ ! -f $test_file ]]; then + continue + fi + + #shellcheck source=/dev/null + source "$test_file" + + Runner::runSetUpBeforeScript + Runner::callTestFunctions "$test_file" "$_FILTER" + Runner::runTearDownAfterScript + Runner::cleanSetUpAndTearDownAfterScript + done } function Runner::runSetUp() { @@ -74,7 +95,7 @@ function Runner::cleanSetUpAndTearDownAfterScript() { _FILES=() _FILTER="" -while [ $# -gt 0 ]; do +while [[ $# -gt 0 ]]; do argument="$1" case $argument in --filter) @@ -89,32 +110,10 @@ while [ $# -gt 0 ]; do esac done - - -function Runner::loadTestFiles() { - if [ ${#_FILES[@]} -eq 0 ]; then - echo "Error: At least one file path is required." - echo "Usage: $0 " - exit 1 - fi - - for test_file in "${_FILES[@]}"; do - if [[ ! -f $test_file ]]; - then - continue - fi - # shellcheck disable=SC1090 - source "$test_file" - Runner::runSetUpBeforeScript - Runner::callTestFunctions "$test_file" "$_FILTER" - if [ "$PARALLEL_RUN" = true ] ; then - wait - fi - Runner::runTearDownAfterScript - - Runner::cleanSetUpAndTearDownAfterScript - done -} - Runner::loadTestFiles +trap 'Console::renderResult '\ +'"$(State::getTestsPassed)" '\ +'"$(State::getTestsFailed)" '\ +'"$(State::getAssertionsPassed)" '\ +'"$(State::getAssertionsFailed)"' EXIT diff --git a/src/state.sh b/src/state.sh new file mode 100644 index 00000000..f45d0612 --- /dev/null +++ b/src/state.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +_TESTS_PASSED=0 +_TESTS_FAILED=0 +_ASSERTIONS_PASSED=0 +_ASSERTIONS_FAILED=0 + +function State::getTestsPassed() { + echo "$_TESTS_PASSED" +} + +function State::addTestsPassed() { + ((_TESTS_PASSED++)) +} + +function State::getTestsFailed() { + echo "$_TESTS_FAILED" +} + +function State::addTestsFailed() { + ((_TESTS_FAILED++)) +} + +function State::getAssertionsPassed() { + echo "$_ASSERTIONS_PASSED" +} + +function State::addAssertionsPassed() { + ((_ASSERTIONS_PASSED++)) +} + +function State::getAssertionsFailed() { + echo "$_ASSERTIONS_FAILED" +} + +function State::addAssertionsFailed() { + ((_ASSERTIONS_FAILED++)) +} diff --git a/tests/acceptance/bashunit_test.sh b/tests/acceptance/bashunit_test.sh index 29f84063..b149a3ad 100644 --- a/tests/acceptance/bashunit_test.sh +++ b/tests/acceptance/bashunit_test.sh @@ -40,7 +40,3 @@ function test_fail() { assertEquals \"1\" \"0\" ; }" > $test_file rm $test_file } - -function test_when_running_bashunit_without_error_then_exit_code_should_be_success() { - assertSuccessfulCode "$(./bashunit)" -}