From 6adc2ed8a81cefda66d5c9d80231f4de33e54cf4 Mon Sep 17 00:00:00 2001 From: SauronBot Date: Mon, 27 Apr 2026 00:57:42 +0200 Subject: [PATCH 1/3] feat(assert): add arrays equal assertion --- docs/assertions.md | 25 +++++++++ src/assert_arrays.sh | 52 +++++++++++++++++++ ...it_should_display_all_assert_docs.snapshot | 9 ++++ tests/unit/assert_advanced_test.sh | 35 +++++++++++++ 4 files changed, 121 insertions(+) diff --git a/docs/assertions.md b/docs/assertions.md index 6fefe26c..971db190 100644 --- a/docs/assertions.md +++ b/docs/assertions.md @@ -560,6 +560,31 @@ function test_interactive_prompt() { ``` ::: +## assert_arrays_equal +> `assert_arrays_equal "expected..." -- "actual..."` + +Reports an error if the arrays have different lengths or any element differs at the same index. + +Use `--` to separate the expected array from the actual array. + +::: code-group +```bash [Example] +function test_success() { + local expected=(foo bar baz) + local actual=(foo bar baz) + + assert_arrays_equal "${expected[@]}" -- "${actual[@]}" +} + +function test_failure() { + local expected=(foo bar baz) + local actual=(foo baz bar) + + assert_arrays_equal "${expected[@]}" -- "${actual[@]}" +} +``` +::: + ## assert_array_contains > `assert_array_contains "needle" "haystack"` diff --git a/src/assert_arrays.sh b/src/assert_arrays.sh index f18f6278..9880cccb 100644 --- a/src/assert_arrays.sh +++ b/src/assert_arrays.sh @@ -1,5 +1,57 @@ #!/usr/bin/env bash +function assert_arrays_equal() { + bashunit::assert::should_skip && return 0 + + local label + label="$(bashunit::assert::label)" + + local -a expected + local -a actual + local found_separator=false + local argument + + for argument in "$@"; do + if [ "$found_separator" = false ] && [ "$argument" = "--" ]; then + found_separator=true + continue + fi + + if [ "$found_separator" = true ]; then + actual[${#actual[@]}]="$argument" + else + expected[${#expected[@]}]="$argument" + fi + done + + if [ "$found_separator" = false ]; then + bashunit::assert::mark_failed + bashunit::console_results::print_failed_test "$label" "--" "but got " "missing array separator" + return + fi + + if [ "${#expected[@]}" -ne "${#actual[@]}" ]; then + bashunit::assert::mark_failed + bashunit::console_results::print_failed_test \ + "$label" "${expected[*]}" "but got " "${actual[*]}" \ + "Expected length" "${#expected[@]}, actual length ${#actual[@]}" + return + fi + + local index + for ((index = 0; index < ${#expected[@]}; index++)); do + if [ "${expected[$index]}" != "${actual[$index]}" ]; then + bashunit::assert::mark_failed + bashunit::console_results::print_failed_test \ + "$label" "${expected[*]}" "but got " "${actual[*]}" \ + "Different index" "$index" + return + fi + done + + bashunit::state::add_assertions_passed +} + function assert_array_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 3bfd9242..e8232e44 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 @@ -236,6 +236,15 @@ Use `--stdout-contains` / `--stdout-not-contains` (and the `stderr-*` variants) for substring matching when you don't want to assert against the full output. +## assert_arrays_equal +-------------- +> `assert_arrays_equal "expected..." -- "actual..."` + +Reports an error if the arrays have different lengths or any element differs at the same index. + +Use `--` to separate the expected array from the actual array. + + ## assert_array_contains -------------- > `assert_array_contains "needle" "haystack"` diff --git a/tests/unit/assert_advanced_test.sh b/tests/unit/assert_advanced_test.sh index 084c8c6f..ad2854b4 100644 --- a/tests/unit/assert_advanced_test.sh +++ b/tests/unit/assert_advanced_test.sh @@ -118,6 +118,41 @@ function test_unsuccessful_assert_array_not_contains() { "$(assert_array_not_contains "123" "${distros[@]}")" } +function test_successful_assert_arrays_equal() { + local expected + expected=(Ubuntu 123 Linux\ Mint) + local actual + actual=(Ubuntu 123 Linux\ Mint) + + assert_empty "$(assert_arrays_equal "${expected[@]}" -- "${actual[@]}")" +} + +function test_unsuccessful_assert_arrays_equal_with_different_lengths() { + local expected + expected=(Ubuntu 123 Linux\ Mint) + local actual + actual=(Ubuntu 123) + + assert_same \ + "$(bashunit::console_results::print_failed_test \ + "Unsuccessful assert arrays equal with different lengths" \ + "Ubuntu 123 Linux Mint" "but got " "Ubuntu 123" "Expected length" "3, actual length 2")" \ + "$(assert_arrays_equal "${expected[@]}" -- "${actual[@]}")" +} + +function test_unsuccessful_assert_arrays_equal_with_different_elements() { + local expected + expected=(Ubuntu 123 Linux\ Mint) + local actual + actual=(Ubuntu 321 Linux\ Mint) + + assert_same \ + "$(bashunit::console_results::print_failed_test \ + "Unsuccessful assert arrays equal with different elements" \ + "Ubuntu 123 Linux Mint" "but got " "Ubuntu 321 Linux Mint" "Different index" "1")" \ + "$(assert_arrays_equal "${expected[@]}" -- "${actual[@]}")" +} + function test_successful_assert_line_count_empty_str() { assert_empty "$(assert_line_count 0 "")" } From fd60e4da27e3b65e7a76097db155a4c2793cd524 Mon Sep 17 00:00:00 2001 From: SauronBot Date: Mon, 27 Apr 2026 01:02:00 +0200 Subject: [PATCH 2/3] fix: satisfy shellcheck for array assertion --- src/assert_arrays.sh | 20 ++++++++++---------- tests/unit/assert_advanced_test.sh | 30 +++++++++++++++--------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/assert_arrays.sh b/src/assert_arrays.sh index 9880cccb..d00446cc 100644 --- a/src/assert_arrays.sh +++ b/src/assert_arrays.sh @@ -6,8 +6,8 @@ function assert_arrays_equal() { local label label="$(bashunit::assert::label)" - local -a expected - local -a actual + local -a expected_values + local -a actual_values local found_separator=false local argument @@ -18,9 +18,9 @@ function assert_arrays_equal() { fi if [ "$found_separator" = true ]; then - actual[${#actual[@]}]="$argument" + actual_values[${#actual_values[@]}]="$argument" else - expected[${#expected[@]}]="$argument" + expected_values[${#expected_values[@]}]="$argument" fi done @@ -30,20 +30,20 @@ function assert_arrays_equal() { return fi - if [ "${#expected[@]}" -ne "${#actual[@]}" ]; then + if [ "${#expected_values[@]}" -ne "${#actual_values[@]}" ]; then bashunit::assert::mark_failed bashunit::console_results::print_failed_test \ - "$label" "${expected[*]}" "but got " "${actual[*]}" \ - "Expected length" "${#expected[@]}, actual length ${#actual[@]}" + "$label" "${expected_values[*]}" "but got " "${actual_values[*]}" \ + "Expected length" "${#expected_values[@]}, actual length ${#actual_values[@]}" return fi local index - for ((index = 0; index < ${#expected[@]}; index++)); do - if [ "${expected[$index]}" != "${actual[$index]}" ]; then + for ((index = 0; index < ${#expected_values[@]}; index++)); do + if [ "${expected_values[$index]}" != "${actual_values[$index]}" ]; then bashunit::assert::mark_failed bashunit::console_results::print_failed_test \ - "$label" "${expected[*]}" "but got " "${actual[*]}" \ + "$label" "${expected_values[*]}" "but got " "${actual_values[*]}" \ "Different index" "$index" return fi diff --git a/tests/unit/assert_advanced_test.sh b/tests/unit/assert_advanced_test.sh index ad2854b4..208442a0 100644 --- a/tests/unit/assert_advanced_test.sh +++ b/tests/unit/assert_advanced_test.sh @@ -119,38 +119,38 @@ function test_unsuccessful_assert_array_not_contains() { } function test_successful_assert_arrays_equal() { - local expected - expected=(Ubuntu 123 Linux\ Mint) - local actual - actual=(Ubuntu 123 Linux\ Mint) + local expected_values + expected_values=(Ubuntu 123 Linux\ Mint) + local actual_values + actual_values=(Ubuntu 123 Linux\ Mint) - assert_empty "$(assert_arrays_equal "${expected[@]}" -- "${actual[@]}")" + assert_empty "$(assert_arrays_equal "${expected_values[@]}" -- "${actual_values[@]}")" } function test_unsuccessful_assert_arrays_equal_with_different_lengths() { - local expected - expected=(Ubuntu 123 Linux\ Mint) - local actual - actual=(Ubuntu 123) + local expected_values + expected_values=(Ubuntu 123 Linux\ Mint) + local actual_values + actual_values=(Ubuntu 123) assert_same \ "$(bashunit::console_results::print_failed_test \ "Unsuccessful assert arrays equal with different lengths" \ "Ubuntu 123 Linux Mint" "but got " "Ubuntu 123" "Expected length" "3, actual length 2")" \ - "$(assert_arrays_equal "${expected[@]}" -- "${actual[@]}")" + "$(assert_arrays_equal "${expected_values[@]}" -- "${actual_values[@]}")" } function test_unsuccessful_assert_arrays_equal_with_different_elements() { - local expected - expected=(Ubuntu 123 Linux\ Mint) - local actual - actual=(Ubuntu 321 Linux\ Mint) + local expected_values + expected_values=(Ubuntu 123 Linux\ Mint) + local actual_values + actual_values=(Ubuntu 321 Linux\ Mint) assert_same \ "$(bashunit::console_results::print_failed_test \ "Unsuccessful assert arrays equal with different elements" \ "Ubuntu 123 Linux Mint" "but got " "Ubuntu 321 Linux Mint" "Different index" "1")" \ - "$(assert_arrays_equal "${expected[@]}" -- "${actual[@]}")" + "$(assert_arrays_equal "${expected_values[@]}" -- "${actual_values[@]}")" } function test_successful_assert_line_count_empty_str() { From 1c46b4e23cb9ce3def7ac791711a556b1f31746e Mon Sep 17 00:00:00 2001 From: SauronBot Date: Mon, 27 Apr 2026 01:07:02 +0200 Subject: [PATCH 3/3] fix: initialize arrays for strict mode --- src/assert_arrays.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assert_arrays.sh b/src/assert_arrays.sh index d00446cc..94672151 100644 --- a/src/assert_arrays.sh +++ b/src/assert_arrays.sh @@ -6,8 +6,8 @@ function assert_arrays_equal() { local label label="$(bashunit::assert::label)" - local -a expected_values - local -a actual_values + local -a expected_values=() + local -a actual_values=() local found_separator=false local argument