diff --git a/CHANGELOG.md b/CHANGELOG.md index b1962715..f04135b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased ### Added +- `assert_array_length ` asserts an array has exactly `n` elements (#743) - `assert_file_permissions ` asserts a file's octal permission mode (`644`, `0755`); portable across GNU/BSD `stat` (#742) ### Fixed diff --git a/docs/assertions.md b/docs/assertions.md index 39a42817..81212065 100644 --- a/docs/assertions.md +++ b/docs/assertions.md @@ -613,6 +613,27 @@ function test_failure() { ``` ::: +## assert_array_length +> `assert_array_length "expected_length" "array"` + +Reports an error if `array` does not have exactly `expected_length` elements. + +::: code-group +```bash [Example] +function test_success() { + local haystack=(foo bar baz) + + assert_array_length 3 "${haystack[@]}" +} + +function test_failure() { + local haystack=(foo bar baz) + + assert_array_length 2 "${haystack[@]}" +} +``` +::: + ## assert_successful_code > `assert_successful_code` diff --git a/src/assert_arrays.sh b/src/assert_arrays.sh index 94672151..2f917cc6 100644 --- a/src/assert_arrays.sh +++ b/src/assert_arrays.sh @@ -78,6 +78,30 @@ function assert_array_contains() { bashunit::state::add_assertions_passed } +function assert_array_length() { + bashunit::assert::should_skip && return 0 + + local expected="$1" + local test_fn + test_fn="$(bashunit::helper::find_test_function_name)" + local label + label="$(bashunit::helper::normalize_test_function_name "$test_fn")" + shift + + # Use $# / $* rather than building an array: on Bash 3.0 under `set -u`, + # expanding "$@" into an array with zero elements is an unbound-variable error. + local actual_length="$#" + + if [ "$expected" != "$actual_length" ]; then + bashunit::assert::mark_failed + bashunit::console_results::print_failed_test \ + "${label}" "$*" "to have length ${expected}" "but got ${actual_length}" + return + fi + + bashunit::state::add_assertions_passed +} + function assert_array_not_contains() { bashunit::assert::should_skip && return 0 diff --git a/tests/acceptance/snapshots/bashunit_test_sh.test_bashunit_should_display_all_assert_docs.snapshot b/tests/acceptance/snapshots/bashunit_test_sh.test_bashunit_should_display_all_assert_docs.snapshot index 3657a9d4..9e0977ec 100644 --- a/tests/acceptance/snapshots/bashunit_test_sh.test_bashunit_should_display_all_assert_docs.snapshot +++ b/tests/acceptance/snapshots/bashunit_test_sh.test_bashunit_should_display_all_assert_docs.snapshot @@ -254,6 +254,13 @@ Reports an error if `needle` is not an element of `haystack`. - assert_array_not_contains is the inverse of this assertion and takes the same arguments. +## assert_array_length +-------------- +> `assert_array_length "expected_length" "array"` + +Reports an error if `array` does not have exactly `expected_length` elements. + + ## assert_successful_code -------------- > `assert_successful_code` diff --git a/tests/unit/assert_advanced_test.sh b/tests/unit/assert_advanced_test.sh index 208442a0..fc29dd07 100644 --- a/tests/unit/assert_advanced_test.sh +++ b/tests/unit/assert_advanced_test.sh @@ -118,6 +118,29 @@ function test_unsuccessful_assert_array_not_contains() { "$(assert_array_not_contains "123" "${distros[@]}")" } +function test_successful_assert_array_length() { + local distros + distros=(Ubuntu 123 Linux\ Mint) + + assert_empty "$(assert_array_length 3 "${distros[@]}")" +} + +function test_successful_assert_array_length_with_empty_array() { + # Passing no elements (expanding an empty array under `set -u` is an + # "unbound variable" error on Bash 3.2, so we call it with just the length). + assert_empty "$(assert_array_length 0)" +} + +function test_unsuccessful_assert_array_length() { + local distros + distros=(Ubuntu 123 Linux\ Mint) + + assert_same \ + "$(bashunit::console_results::print_failed_test \ + "Unsuccessful assert array length" "Ubuntu 123 Linux Mint" "to have length 2" "but got 3")" \ + "$(assert_array_length 2 "${distros[@]}")" +} + function test_successful_assert_arrays_equal() { local expected_values expected_values=(Ubuntu 123 Linux\ Mint)