Select Git revision
README-dnszone.md
-
Rafael Guterres Jeffman authored
ansible-freeipa roles do not work with Ansible 2.8 anymore, so the minimum supported version is changed to 2.15, the oldest supported Ansible version as of today. This patch includes the change to the version number in the collection and all plugin README files. The collection README was also update to remove text that related only to previous Ansible versions.
Rafael Guterres Jeffman authoredansible-freeipa roles do not work with Ansible 2.8 anymore, so the minimum supported version is changed to 2.15, the oldest supported Ansible version as of today. This patch includes the change to the version number in the collection and all plugin README files. The collection README was also update to remove text that related only to previous Ansible versions.
shebang-unit 29.58 KiB
#!/usr/bin/env bash
# Copyright (C) 2015, Arpinum
#
# shebang-unit is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# shebang-unit is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# shebang-unit. If not, see http://www.gnu.org/licenses/lgpl.html.
# shebang-unit all in one source file
configuration__load() {
# yes/no representation used with shebang-unit parameters to activate
# stuff like colors
SBU_YES="yes"
SBU_NO="no"
# Colors for outputs
SBU_GREEN_COLOR_CODE="\\033[1;32m"
SBU_RED_COLOR_CODE="\\033[1;31m"
SBU_YELLOW_COLOR_CODE="\\033[1;33m"
SBU_DEFAULT_COLOR_CODE="\\e[0m"
# Functions coding coventions
SBU_GLOBAL_SETUP_FUNCTION_NAME="global_setup"
SBU_GLOBAL_TEARDOWN_FUNCTION_NAME="global_teardown"
SBU_SETUP_FUNCTION_NAME="setup"
SBU_TEARDOWN_FUNCTION_NAME="teardown"
SBU_FUNCTION_DECLARATION_REGEX="^[ ]*\(function\)\{0,1\}[ ]*\([A-Za-z0-9_-]\{1,\}\)[ ]*\(([ ]*)\)\{0,1\}[ ]*{"
SBU_PRIVATE_FUNCTION_NAME_REGEX="^_.*"
# Default configuration that can be modified with shebang-unit parameters
# For more information see shebang-unit usages
SBU_TEST_FILE_PATTERN="*_test.sh"
SBU_TEST_FUNCTION_PATTERN="*"
SBU_USE_COLORS="${SBU_YES}"
SBU_RANDOM_RUN="${SBU_NO}"
SBU_REPORTERS="simple"
SBU_JUNIT_REPORTER_OUTPUT_FILE="./junit_report.xml"
# Internal constants
SBU_SUCCESS_STATUS_CODE=0
SBU_FAILURE_STATUS_CODE=1
SBU_VALUE_SEPARATOR=","
SBU_TEMP_DIR="/tmp/.shebang-unit"
SBU_LAST_ASSERTION_MSG_KEY="last_assertion_message"
SBU_NO_RUN="${SBU_NO}"
SBU_STANDARD_FD=42
SBU_ERROR_FD=43
}
assertion__equal() {
if [[ "$1" != "$2" ]]; then
_assertion__failed "Actual: <$2>, expected: <$1>."
fi
}
assertion__different() {
if [[ "$1" == "$2" ]]; then
_assertion__failed "Both values are: <$1>."
fi
}
assertion__string_contains() {
if ! system__string_contains "$1" "$2"; then
_assertion__failed "String: <$1> does not contain: <$2>."
fi
}
assertion__string_does_not_contain() {
if system__string_contains "$1" "$2"; then
_assertion__failed "String: <$1> contains: <$2>."
fi
}
assertion__string_empty() {
if [[ -n "$1" ]]; then
_assertion__failed "String: <$1> is not empty."
fi
}
assertion__string_not_empty() {
if [[ -z "$1" ]]; then
_assertion__failed "The string is empty."
fi
}
assertion__array_contains() {
local element=$1
shift 1
if ! array__contains "${element}" "$@"; then
local array_as_string="$(system__pretty_print_array "$@")"
_assertion__failed \
"Array: <${array_as_string}> does not contain: <${element}>."
fi
}
assertion__array_does_not_contain() {
local element=$1
shift 1
if array__contains "${element}" "$@"; then
local array_as_string="$(system__pretty_print_array "$@")"
_assertion__failed \
"Array: <${array_as_string}> contains: <${element}>."
fi
}
assertion__status_code_is_success() {
if (( $1 != ${SBU_SUCCESS_STATUS_CODE} )); then
_assertion__failed \
"Status code is failure instead of success." "$2"
fi
}
assertion__status_code_is_failure() {
if (( $1 == ${SBU_SUCCESS_STATUS_CODE} )); then
_assertion__failed \
"Status code is success instead of failure." "$2"
fi
}
assertion__successful() {
"$@"
if (( $? != ${SBU_SUCCESS_STATUS_CODE} )); then
_assertion__failed "Command is failing instead of successful."
fi
}
assertion__failing() {
"$@"
if (( $? == ${SBU_SUCCESS_STATUS_CODE} )); then
_assertion__failed "Command is successful instead of failing."
fi
}
_assertion__failed() {
local message_to_use="$(_assertion__get_assertion_message_to_use "$1" "$2")"
system__print_line "Assertion failed. ${message_to_use}"
exit ${SBU_FAILURE_STATUS_CODE}
}
_assertion__get_assertion_message_to_use() {
local message=$1
local custom_messsage=$2
if [[ -n "${custom_messsage}" ]]; then
system__print "${message} ${custom_messsage}"
else
system__print "${message}"
fi
}
mock__make_function_do_nothing() {
mock__make_function_call "$1" ":"
}
mock__make_function_prints() {
local function=$1
local text=$2
eval "${function}() { printf "${text}"; }"
}
mock__make_function_call() {
local function_to_mock=$1
local function_to_call=$2
shift 2
eval "${function_to_mock}() { ${function_to_call} \"\$@\"; }"
}
runner__run_all_test_files() {
SBU_BASE_TEST_DIRECTORY=$1
reporter__test_files_start_running
timer__store_current_time "global_time"
results__test_files_start_running
_runner__run_all_test_files_with_pattern_in_directory "$1"
reporter__test_files_end_running "$(timer__get_time_elapsed "global_time")"
runner__tests_are_successful
}
_runner__run_all_test_files_with_pattern_in_directory() {
local file
local files
array__from_lines files <<< "$(_runner__get_test_files_in_directory "$1")"
for file in "${files[@]}"; do
file_runner__run_test_file "${file}"
done
}
_runner__get_test_files_in_directory() {
local files
array__from_lines files <<< "$(find "$1" -name "${SBU_TEST_FILE_PATTERN}" | sort)"
if [[ "${SBU_RANDOM_RUN}" == "${SBU_YES}" ]]; then
array__from_lines files <<< "$(system__randomize_array "${files[@]}")"
fi
array__print "${files[@]}"
}
runner__tests_are_successful() {
(( $(results__get_failing_tests_count) == 0 \
&& $(results__get_skipped_tests_count) == 0 ))
}
file_runner__run_test_file() {
local file=$1
local public_functions=($(parser__get_public_functions_in_file "${file}"))
local test_functions=($(_file_runner__get_test_functions))
reporter__test_file_starts_running "${file}" "${#test_functions[@]}"
( source "${file}"
_file_runner__run_global_setup_if_exists \
&& _file_runner__call_all_tests
_file_runner__run_global_teardown_if_exists )
_file_runner__check_if_global_setup_has_exited
reporter__test_file_ends_running
}
_file_runner__run_all_tests_if_global_setup_is_successful() {
_file_runner__call_all_tests
}
_file_runner__call_all_tests() {
local i
for (( i=0; i < ${#test_functions[@]}; i++ )); do
test_runner__run_test "${test_functions[${i}]}" "${public_functions[@]}"
done
}
_file_runner__skip_all_tests() {
local i
for (( i=0; i < ${#test_functions[@]}; i++ )); do
test_runner__skip_test "${test_functions[${i}]}" "${public_functions[@]}"
done
}
_file_runner__get_test_functions() {
local result=()
local test_function
for test_function in "${public_functions[@]}"; do
if _file_runner__function_is_a_test "${test_function}"\
&& [[ "${test_function}" == ${SBU_TEST_FUNCTION_PATTERN} ]]; then
result+=("${test_function}")
fi
done
_file_runner__get_randomized_test_functions_if_needed "${result[@]}"
}
_file_runner__get_randomized_test_functions_if_needed() {
if [[ "${SBU_RANDOM_RUN}" == "${SBU_YES}" ]]; then
system__randomize_array "$@"
else
array__print "$@"
fi
}
_file_runner__run_global_setup_if_exists() {
database__put "sbu_current_global_setup_has_failed" "${SBU_YES}"
_file_runner__call_function_if_exists "${SBU_GLOBAL_SETUP_FUNCTION_NAME}" \
&& database__put "sbu_current_global_setup_has_failed" "${SBU_NO}"
}
_file_runner__run_global_teardown_if_exists() {
_file_runner__call_function_if_exists "${SBU_GLOBAL_TEARDOWN_FUNCTION_NAME}"
}
_file_runner__function_is_a_test() {
! array__contains "$1" \
"${SBU_GLOBAL_SETUP_FUNCTION_NAME}" \
"${SBU_GLOBAL_TEARDOWN_FUNCTION_NAME}" \
"${SBU_SETUP_FUNCTION_NAME}" \
"${SBU_TEARDOWN_FUNCTION_NAME}"
}
_file_runner__call_function_if_exists() {
local function=$1
shift 1
if array__contains "${function}" "${public_functions[@]}"; then
"${function}"
fi
}
_file_runner__check_if_global_setup_has_exited() {
local has_exited="$(database__get "sbu_current_global_setup_has_failed")"
if [[ "${has_exited}" == "${SBU_YES}" ]]; then
_file_runner__handle_failure_in_global_setup
fi
}
_file_runner__handle_failure_in_global_setup() {
reporter__global_setup_has_failed
_file_runner__skip_all_tests
}
parser__get_public_functions_in_file() {
_parser__find_functions_in_file "$1" \
| _parser__filter_private_functions \
| awk '{ print $1 }'
}
_parser__find_functions_in_file() {
grep -o "${SBU_FUNCTION_DECLARATION_REGEX}" "$1" \
| _parser__get_function_name_from_declaration
}
_parser__filter_private_functions() {
grep -v "${SBU_PRIVATE_FUNCTION_NAME_REGEX}"
}
_parser__get_function_name_from_declaration() {
sed "s/${SBU_FUNCTION_DECLARATION_REGEX}/\2/"
}
timer__store_current_time() {
local id=$1
database__put "sbu_beginning_date_$1" "$(system__get_date_in_seconds)"
}
timer__get_time_elapsed() {
local id=$1
local beginning_date="$(database__get "sbu_beginning_date_$1")"
local ending_date="$(system__get_date_in_seconds)"
[[ -n "${beginning_date}" ]] \
&& system__print "$(( ending_date - beginning_date ))" \
|| system__print "0"
}
results__test_files_start_running() {
database__put "sbu_successful_tests_count" "0"
database__put "sbu_failing_tests_count" "0"
database__put "sbu_skipped_tests_count" "0"
}
results__get_successful_tests_count() {
_results__get_tests_count_of_type "successful"
}
results__increment_successful_tests() {
_results__increment_tests_of_type "successful"
}
results__get_failing_tests_count() {
_results__get_tests_count_of_type "failing"
}
results__increment_failing_tests() {
_results__increment_tests_of_type "failing"
}
results__get_skipped_tests_count() {
_results__get_tests_count_of_type "skipped"
}
results__increment_skipped_tests() {
_results__increment_tests_of_type "skipped"
}
results__get_total_tests_count() {
local successes="$(results__get_successful_tests_count)"
local failures="$(results__get_failing_tests_count)"
local skipped="$(results__get_skipped_tests_count)"
system__print "$(( successes + failures + skipped ))"
}
_results__get_tests_count_of_type() {
local type=$1
database__get "sbu_${type}_tests_count"
}
_results__increment_tests_of_type() {
local type=$1
local count="$(results__get_${type}_tests_count)"
database__put "sbu_${type}_tests_count" "$(( count + 1 ))"
}
test_runner__run_test() {
local test_function=$1
shift 1
reporter__test_starts_running "${test_function}"
timer__store_current_time "test_time"
(
_test_runner__call_setup_if_exists "$@" \
&& _test_runner__call_test_fonction "${test_function}"
local setup_and_test_code=$?
_test_runner__call_teardown_if_exists "$@"
(( $? == ${SBU_SUCCESS_STATUS_CODE} \
&& ${setup_and_test_code} == ${SBU_SUCCESS_STATUS_CODE} ))
)
_test_runner__parse_test_function_result $?
reporter__test_ends_running "$(timer__get_time_elapsed "test_time")"
}
_test_runner__call_test_fonction() {
( "$1" >&${SBU_STANDARD_FD} 2>&${SBU_ERROR_FD} )
}
_test_runner__call_setup_if_exists() {
_test_runner__call_function_if_exits "${SBU_SETUP_FUNCTION_NAME}" "$@"
}
_test_runner__call_teardown_if_exists() {
_test_runner__call_function_if_exits "${SBU_TEARDOWN_FUNCTION_NAME}" "$@"
}
_test_runner__parse_test_function_result() {
if (( $1 == ${SBU_SUCCESS_STATUS_CODE} )); then
results__increment_successful_tests
reporter__test_has_succeeded
else
results__increment_failing_tests
reporter__test_has_failed
fi
}
_test_runner__call_function_if_exits() {
local function=$1
shift 1
if array__contains "${function}" "$@"; then
"${function}"
fi
}
test_runner__skip_test() {
local test_function=$1
reporter__test_starts_running "${test_function}"
results__increment_skipped_tests
reporter__test_is_skipped "${test_function}"
reporter__test_ends_running 0
}
reporter__test_files_start_running() {
_reporter__initialise_file_descriptors
reporter__for_each_reporter \
_reporter__call_function "test_files_start_running" "$@"
}
_reporter__initialise_file_descriptors() {
eval "exec ${SBU_STANDARD_FD}>&1"
eval "exec ${SBU_ERROR_FD}>&2"
}
reporter__global_setup_has_failed() {
reporter__for_each_reporter \
_reporter__call_function "global_setup_has_failed" "$@"
}
reporter__test_file_starts_running() {
reporter__for_each_reporter \
_reporter__call_function "test_file_starts_running" "$@"
}
reporter__test_starts_running() {
reporter__for_each_reporter \
_reporter__call_function "test_starts_running" "$@"
}
reporter__test_has_succeeded() {
reporter__for_each_reporter \
_reporter__call_function "test_has_succeeded" "$@"
}
reporter__test_has_failed() {
reporter__for_each_reporter \
_reporter__call_function "test_has_failed" "$@"
}
reporter__test_is_skipped() {
reporter__for_each_reporter \
_reporter__call_function "test_is_skipped" "$@"
}
reporter__test_ends_running() {
reporter__for_each_reporter \
_reporter__call_function "test_ends_running" "$@"
}
reporter__test_file_ends_running() {
reporter__for_each_reporter \
_reporter__call_function "test_file_ends_running" "$@"
}
reporter__test_files_end_running() {
reporter__for_each_reporter \
_reporter__call_function "test_files_end_running" "$@"
_reporter__release_file_descriptors
}
_reporter__release_file_descriptors() {
eval "exec 1>&${SBU_STANDARD_FD} ${SBU_STANDARD_FD}>&-"
eval "exec 2>&${SBU_ERROR_FD} ${SBU_ERROR_FD}>&-"
}
_reporter__call_function() {
local function=$1
shift 1
"${reporter}_reporter__${function}" "$@"
}
reporter__for_each_reporter() {
local reporter
for reporter in ${SBU_REPORTERS//${SBU_VALUE_SEPARATOR}/ }; do
"$@"
done
}
reporter__print_with_color() {
system__print_with_color "$@" >&${SBU_STANDARD_FD}
}
reporter__print_line() {
system__print_line "$@" >&${SBU_STANDARD_FD}
}
reporter__print_line_with_color() {
system__print_line_with_color "$@" >&${SBU_STANDARD_FD}
}
reporter__print_new_line() {
system__print_new_line >&${SBU_STANDARD_FD}
}
reporter__get_color_code_for_tests_result() {
local color_code=${SBU_GREEN_COLOR_CODE}
if ! runner__tests_are_successful; then
color_code=${SBU_RED_COLOR_CODE}
fi
system__print "${color_code}"
}
reporter__get_test_file_relative_name() {
system__print "${1#${SBU_BASE_TEST_DIRECTORY}\/}"
}
simple_reporter__test_files_start_running() {
:
}
simple_reporter__test_file_starts_running() {
local relative_name="$(reporter__get_test_file_relative_name "$1")"
reporter__print_line "[File] ${relative_name}"
}
simple_reporter__global_setup_has_failed() {
reporter__print_line_with_color \
"Global setup has failed" ${SBU_YELLOW_COLOR_CODE}
}
simple_reporter__test_starts_running() {
reporter__print_line "[Test] $1"
}
simple_reporter__test_has_succeeded() {
reporter__print_line_with_color "OK" ${SBU_GREEN_COLOR_CODE}
}
simple_reporter__test_has_failed() {
reporter__print_line_with_color "KO" ${SBU_RED_COLOR_CODE}
}
simple_reporter__test_is_skipped() {
reporter__print_line_with_color "Skipped" ${SBU_YELLOW_COLOR_CODE}
}
simple_reporter__test_ends_running() {
:
}
simple_reporter__test_file_ends_running() {
reporter__print_new_line
}
simple_reporter__test_files_end_running() {
local time="in $1s"
reporter__print_line "[Results]"
local color="$(reporter__get_color_code_for_tests_result)"
local total_count="$(_simple_reporter__get_total_count_message)"
local failures_count="$(_simple_reporter__get_failures_count_message)"
local skipped_count="$(results__get_skipped_tests_count) skipped"
local message="${total_count}, ${failures_count}, ${skipped_count} ${time}"
reporter__print_line_with_color "${message}" "${color}"
}
_simple_reporter__get_total_count_message() {
local count="$(results__get_total_tests_count)"
system__print "${count} test$(_simple_reporter__get_agreement ${count})"
}
_simple_reporter__get_failures_count_message() {
local count="$(results__get_failing_tests_count)"
system__print "${count} failure$(_simple_reporter__get_agreement ${count})"
}
_simple_reporter__get_agreement() {
(( $1 > 1 )) \
&& system__print "s" \
|| system__print ""
}
dots_reporter__test_files_start_running() {
exec 1>/dev/null
exec 2>/dev/null
}
dots_reporter__test_file_starts_running() {
:
}
dots_reporter__global_setup_has_failed() {
:
}
dots_reporter__test_starts_running() {
:
}
dots_reporter__test_has_succeeded() {
reporter__print_with_color "." ${SBU_GREEN_COLOR_CODE}
}
dots_reporter__test_has_failed() {
reporter__print_with_color "F" ${SBU_RED_COLOR_CODE}
}
dots_reporter__test_is_skipped() {
reporter__print_with_color "S" ${SBU_YELLOW_COLOR_CODE}
}
dots_reporter__test_ends_running() {
:
}
dots_reporter__test_file_ends_running() {
:
}
dots_reporter__test_files_end_running() {
local color="$(reporter__get_color_code_for_tests_result)"
local texte="$(runner__tests_are_successful \
&& system__print "OK" \
|| system__print "KO")"
reporter__print_line_with_color "${texte}" "${color}"
}
junit_reporter__test_files_start_running() {
_junit_reporter__initialise_report_with \
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
_junit_reporter__write_line_to_report "<testsuites>"
}
junit_reporter__test_file_starts_running() {
local file_name=$1
local test_count=$2
local suite_name="$(_junit_reporter__get_suite_name "${file_name}")"
database__put "sbu_current_suite_name" "${suite_name}"
_junit_reporter__write_line_to_report \
" <testsuite name=\"${suite_name}\" tests=\"${test_count}\">"
_junit_reporter__delete_all_outputs_lines "suite"
_junit_reporter__redirect_outputs_to_database "suite"
}
junit_reporter__global_setup_has_failed() {
:
}
junit_reporter__test_starts_running() {
local suite_name="$(database__get "sbu_current_suite_name")"
local test_name="$(xml__encode_text "$1")"
_junit_reporter__write_line_to_report \
" <testcase name=\"${test_name}\" classname=\"${suite_name}\" \
time=\"\${sbu_current_test_time}\">"
_junit_reporter__delete_all_outputs_lines "test"
_junit_reporter__redirect_outputs_to_database "test"
}
junit_reporter__test_has_succeeded() {
:
}
junit_reporter__test_has_failed() {
_junit_reporter__write_line_to_report " <failure>"
_junit_reporter__write_line_to_report " </failure>"
}
junit_reporter__test_is_skipped() {
_junit_reporter__write_line_to_report " <skipped>"
_junit_reporter__write_line_to_report " </skipped>"
}
junit_reporter__test_ends_running() {
_junit_reporter__redirect_outputs_to_database "suite"
_junit_reporter__write_time_in_current_test_case_tag_in_report "$1"
_junit_reporter__flush_all_outputs_to_report_if_any "test"
_junit_reporter__write_line_to_report " </testcase>"
}
_junit_reporter__write_time_in_current_test_case_tag_in_report() {
local test_time=$1
local report_content=$(cat "${SBU_JUNIT_REPORTER_OUTPUT_FILE}")
local content_with_time="$(system__substitute_variable \
"${report_content}" "sbu_current_test_time" "${test_time}")"
system__print_line \
"${content_with_time}" > "${SBU_JUNIT_REPORTER_OUTPUT_FILE}"
}
junit_reporter__test_file_ends_running() {
_junit_reporter__flush_all_outputs_to_report_if_any "suite"
_junit_reporter__write_line_to_report " </testsuite>"
database__put "sbu_current_suite_name" ""
}
junit_reporter__test_files_end_running() {
_junit_reporter__write_line_to_report "</testsuites>"
}
_junit_reporter__get_suite_name() {
local relative_name="$(reporter__get_test_file_relative_name "$1")"
local dots_replaced_by_underscores="${relative_name//./_}"
local slashes_replaced_by_dots="${dots_replaced_by_underscores//\//.}"
xml__encode_text "${slashes_replaced_by_dots}"
}
_junit_reporter__initialise_report_with() {
system__print_line "$1" > "${SBU_JUNIT_REPORTER_OUTPUT_FILE}"
}
_junit_reporter__write_line_to_report() {
system__print_line "$1" >> "${SBU_JUNIT_REPORTER_OUTPUT_FILE}"
}
_junit_reporter__redirect_outputs_to_database() {
local scope=$1
exec 1>>\
"$(database__get_descriptor "sbu_current_${scope}_standard_ouputs_lines")"
exec 2>>\
"$(database__get_descriptor "sbu_current_${scope}_error_ouputs_lines")"
}
_junit_reporter__delete_all_outputs_lines() {
database__put "sbu_current_$1_standard_ouputs_lines"
database__put "sbu_current_$1_error_ouputs_lines"
}
_junit_reporter__flush_all_outputs_to_report_if_any() {
_junit_reporter__flush_outputs_to_report_if_any "$1" "standard"
_junit_reporter__flush_outputs_to_report_if_any "$1" "error"
}
_junit_reporter__flush_outputs_to_report_if_any() {
local scope=$1
local outputs_type=$2
local key="sbu_current_${scope}_${outputs_type}_ouputs_lines"
local outputs="$(database__get "${key}")"
if [[ -n "${outputs}" ]]; then
_junit_reporter__write_outputs_to_report \
"${scope}" "${outputs_type}" "${outputs}"
database__put "${key}" ""
fi
}
_junit_reporter__write_outputs_to_report() {
local scope=$1
local outputs_type=$2
local outputs=$3
local tag="$(_junit_reporter__get_tag_for_outputs_type "${outputs_type}")"
local indentation="$(_junit_reporter__get_indentation_for_scope "${scope}")"
_junit_reporter__write_line_to_report "${indentation}<${tag}>"
_junit_reporter__write_line_to_report "$(xml__encode_text "${outputs}")"
_junit_reporter__write_line_to_report "${indentation}</${tag}>"
}
_junit_reporter__get_tag_for_outputs_type() {
[[ "$1" == "standard" ]] \
&& system__print "system-out" \
|| system__print "system-err"
}
_junit_reporter__get_indentation_for_scope() {
[[ "$1" == "suite" ]] \
&& system__print " " \
|| system__print " "
}
xml__encode_text() {
local encoded=${1//\&/\&\;}
encoded=${encoded//\</\<\;}
encoded=${encoded//\>/\>\;}
encoded=${encoded//\"/\"\;}
encoded=${encoded//\'/\&apos\;}
system__print "${encoded}"
}
database__initialise() {
_SBU_DB_TOKEN="$(system__random)"
_database__ensure_directory_exists
}
database__release() {
rm -rf "$(_database__get_dir)"
}
database__put() {
_database__ensure_directory_exists
system__print "$2" > "$(_database__get_dir)/$1"
}
database__post() {
_database__ensure_directory_exists
system__print "$2" >> "$(_database__get_dir)/$1"
}
database__post_line() {
_database__ensure_directory_exists
system__print_line "$2" >> "$(_database__get_dir)/$1"
}
database__put_variable() {
_database__ensure_directory_exists
database__put "$1" "${!1}"
}
database__get() {
[[ -e "$(_database__get_dir)/$1" ]] && cat "$(_database__get_dir)/$1"
}
database__get_descriptor() {
system__print "$(_database__get_dir)/$1"
}
_database__ensure_directory_exists() {
mkdir -p "$(_database__get_dir)"
}
_database__get_dir() {
system__print "${SBU_TEMP_DIR}/database/${_SBU_DB_TOKEN}"
}
system__get_string_or_default() {
[[ -n "$1" ]] \
&& system__print "$1" \
|| system__print "$2"
}
system__get_date_in_seconds() {
date +%s
}
system__print_line_with_color() {
system__print_with_color "$@"
system__print_new_line
}
system__print_with_color() {
if [[ "${SBU_USE_COLORS}" == "${SBU_YES}" ]]; then
printf "$2$1${SBU_DEFAULT_COLOR_CODE}"
else
system__print "$1"
fi
}
system__print_line() {
system__print "$1"
system__print_new_line
}
system__print() {
printf "%s" "$1"
}
system__print_new_line() {
printf "\n"
}
array__contains() {
local value=$1
shift 1
local i
for (( i=1; i <= $#; i++ )); do
if [[ "${!i}" == "${value}" ]]; then
return ${SBU_SUCCESS_STATUS_CODE}
fi
done
return ${SBU_FAILURE_STATUS_CODE}
}
array__from_lines() {
local IFS=$'\n'
eval "$1=(\$(</dev/stdin))"
}
array__print() {
local element
for element in "$@"; do
system__print_line "${element}"
done
}
system__pretty_print_array() {
local array_as_string=""
local i
for (( i=1; i <= $#; i++ )); do
array_as_string+="${!i}, "
done
array_as_string=${array_as_string/%, /}
printf "[%s]" "${array_as_string}"
}
system__string_contains() {
[[ "$1" == *"$2"* ]]
}
system__randomize_array() {
local copy=("$@")
while (( ${#copy[@]} > 0 )); do
local random_index=$(( $(system__random) % ${#copy[@]} ))
system__print_line "${copy[${random_index}]}"
unset copy[${random_index}]
copy=("${copy[@]}")
done
}
system__random() {
system__print "${RANDOM}"
}
system__substitute_variable() {
local string=$1
local key="\$\{$2\}"
local value=$3
printf "%s" "${string//${key}/${value}}"
}
main__main() {
configuration__load
_main__initialise
local parsed_arguments=0
_main__parse_arguments "$@"
shift ${parsed_arguments}
_main__assert_only_one_argument_left $#
_main__assert_reporters_are_known
SBU_BASE_TEST_DIRECTORY=$1
if [[ "${SBU_NO_RUN}" != "${SBU_YES}" ]]; then
runner__run_all_test_files "$1"
return $?
fi
}
_main__initialise() {
database__initialise
trap _main__release EXIT
}
_main__release() {
database__release
}
_main__parse_arguments() {
local argument
for argument in "$@"; do
case "${argument}" in
-a|--api-cheat-sheet)
_main__print_api_cheat_sheet_and_exit
;;
-c=*|--colors=*)
SBU_USE_COLORS="${argument#*=}"
(( parsed_arguments++ ))
;;
-d=*|--random-run=*)
SBU_RANDOM_RUN="${argument#*=}"
(( parsed_arguments++ ))
;;
-h|--help)
_main__print_full_usage
exit ${SBU_SUCCESS_STATUS_CODE}
;;
-f=*|--file-pattern=*)
SBU_TEST_FILE_PATTERN="${argument#*=}"
(( parsed_arguments++ ))
;;
--no-run)
SBU_NO_RUN="${SBU_YES}"
(( parsed_arguments++ ))
;;
-o=*|--output-file=*)
SBU_JUNIT_REPORTER_OUTPUT_FILE="${argument#*=}"
(( parsed_arguments++ ))
;;
-t=*|--test-pattern=*)
SBU_TEST_FUNCTION_PATTERN="${argument#*=}"
(( parsed_arguments++ ))
;;
-r=*|--reporters=*)
SBU_REPORTERS="${argument#*=}"
(( parsed_arguments++ ))
;;
-*|--*)
_main__print_illegal_option "${argument}"
_main__print_usage_and_exit_with_code ${SBU_FAILURE_STATUS_CODE}
;;
esac
done
}
_main__assert_reporters_are_known() {
reporter__for_each_reporter _main__fail_if_reporter_unknown
}
_main__fail_if_reporter_unknown() {
if ! array__contains "${reporter}" "simple" "dots" "junit"; then
system__print_line \
"$(_main__get_script_name): unknown reporter <${reporter}>"
exit ${SBU_FAILURE_STATUS_CODE}
fi
}
_main__print_illegal_option() {
local option="${1%=*}"
option="${option#-}"
option="${option#-}"
system__print_line "$(_main__get_script_name): illegal option -- ${option}"
}
_main__assert_only_one_argument_left() {
if (( $1 > 1 )); then
system__print_line "$(_main__get_script_name): only one path is allowed"
_main__print_usage_and_exit_with_code ${SBU_FAILURE_STATUS_CODE}
fi
}
_main__get_script_name() {
basename "${BASH_SOURCE[0]}"
}
_main__print_usage_and_exit_with_code() {
_main__print_usage
exit $1
}
_main__print_full_usage() {
_main__print_usage
local script="$(_main__get_script_name)"
system__print_new_line
system__print_line "\
[options]
-a, --api-cheat-sheet
print api cheat sheet like assertions
-c, --colors=${SBU_YES} or ${SBU_NO}
tests output with colors or no
-d, --random-run=${SBU_YES} or ${SBU_NO}
tests files and functions randomly run or no
-f, --file-pattern=<pattern>
pattern to filter test files
-h
print usage
-o, --output-file=<file>
output file for JUnit reporter
-r, --reporters=<reporter1,reporter2>
comma-separated reporters (simple, dots or junit)
-t, --test-pattern=<pattern>
pattern to filter test function in files
[examples]
${script} .
run all tests in current directory
${script} -p=*test.sh sources/test
run all tests files ending with test.sh in sources/test"
}
_main__print_usage() {
system__print_line "\
usage: $(_main__get_script_name) [options] path
run all tests in path"
}
_main__print_api_cheat_sheet_and_exit() {
system__print_line "\
[assertions]
assertion__equal (value, other)
-> assert that <value> is equal to <other>
assertion__different (value, other)
-> assert that <value> is different from <other>
assertion__string_contains (string, substring)
-> assert that <string> contains <substring>
assertion__string_does_not_contain (string, substring)
-> assert that <string> does not contain <substring>
assertion__string_empty (string)
-> assert that <string> is empty
assertion__string_not_empty (string)
-> assert that <string> is not empty
assertion__array_contains (element, array[0], array[1], ...)
-> assert that the <array> contains the <element>
assertion__array_does_not_contain (element, array elements...)
-> assert that the <array> does not contain the <element>
assertion__successful (command)
-> assert that the <command> is successful
assertion__failing (command)
-> assert that the <command> is failing
assertion__status_code_is_success (code)
-> assert that the status <code> is 0
assertion__status_code_is_failure (code)
-> assert that the status <code> is not 0
[special functions]
${SBU_GLOBAL_SETUP_FUNCTION_NAME}
-> Executed before all tests in a file
${SBU_GLOBAL_TEARDOWN_FUNCTION_NAME}
-> Executed after all tests in a file
${SBU_SETUP_FUNCTION_NAME}
-> Executed before each test in a file
${SBU_TEARDOWN_FUNCTION_NAME}
-> Executed after each test in a file
[mocks]
mock__make_function_do_nothing (function_to_mock)
-> make function do nothing
mock__make_function_prints (function_to_mock, message)
-> make function prints a message
mock__make_function_call (function_to_mock, function_to_call)
-> make function call another function"
exit ${SBU_SUCCESS_STATUS_CODE}
}
main__main "$@"