Skip to content

Commit ed06155

Browse files
committed
feat: add set_test_title
1 parent 011be03 commit ed06155

File tree

10 files changed

+114
-16
lines changed

10 files changed

+114
-16
lines changed

bashunit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ source "$BASHUNIT_ROOT_DIR/src/colors.sh"
4949
source "$BASHUNIT_ROOT_DIR/src/console_header.sh"
5050
source "$BASHUNIT_ROOT_DIR/src/console_results.sh"
5151
source "$BASHUNIT_ROOT_DIR/src/helpers.sh"
52+
source "$BASHUNIT_ROOT_DIR/src/test_title.sh"
5253
source "$BASHUNIT_ROOT_DIR/src/upgrade.sh"
5354
source "$BASHUNIT_ROOT_DIR/src/assertions.sh"
5455
source "$BASHUNIT_ROOT_DIR/src/reports.sh"

docs/test-files.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@ test_getFunctionsToRun_with_filter_should_return_matching_functions() { ... }
3535
You're free to use any of Bash's syntax options to define these functions.
3636
:::
3737
38+
## Custom test titles
39+
40+
By default, **bashunit** derives the name shown in reports from the test function name.
41+
If you need a more descriptive title, you can override it inside the test using `set_test_title`:
42+
43+
::: code-group
44+
```bash [Example]
45+
function test_handles_invalid_input() {
46+
set_test_title "🔥 handles invalid input with 💣"
47+
# test logic...
48+
}
49+
```
50+
:::
51+
52+
The provided title is used only for display purposes. The original function name is still
53+
used internally, and custom titles are reset automatically after each test, so there's
54+
no need for manual cleanup. Setting a new title again will replace the previous one for the same test.
55+
3856
## `set_up` function
3957
4058
The `set_up` auxiliary function is called, if it is present in the test file, before each test function in the test file is executed.

src/helpers.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ function helper::normalize_test_function_name() {
1111
local original_fn_name="${1-}"
1212
local interpolated_fn_name="${2-}"
1313

14+
local custom_title
15+
custom_title="$(state::get_test_title)"
16+
if [[ -n "$custom_title" ]]; then
17+
echo "$custom_title"
18+
return
19+
fi
20+
1421
if [[ -n "${interpolated_fn_name-}" ]]; then
1522
original_fn_name="$interpolated_fn_name"
1623
fi

src/runner.sh

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ function runner::run_test() {
201201
export BASHUNIT_CURRENT_TEST_ID="${sanitized_fn_name}_$$"
202202
fi
203203

204+
state::reset_test_title
205+
204206
local interpolated_fn_name="$(helper::interpolate_function_name "$fn_name" "$@")"
205207
local current_assertions_failed="$(state::get_assertions_failed)"
206208
local current_assertions_snapshot="$(state::get_assertions_snapshot)"
@@ -291,21 +293,38 @@ function runner::run_test() {
291293
local total_assertions="$(state::calculate_total_assertions "$test_execution_result")"
292294
local test_exit_code="$(state::get_test_exit_code)"
293295

296+
local encoded_test_title
297+
encoded_test_title="${test_execution_result##*##TEST_TITLE=}"
298+
encoded_test_title="${encoded_test_title%%##*}"
299+
local test_title=""
300+
if [[ -n "$encoded_test_title" ]]; then
301+
if command -v base64 >/dev/null; then
302+
test_title="$(echo "$encoded_test_title" | base64 -d)"
303+
else
304+
test_title="$(echo "$encoded_test_title" | openssl enc -d -base64)"
305+
fi
306+
fi
307+
308+
state::set_test_title "$test_title"
309+
local label
310+
label="$(helper::normalize_test_function_name "$fn_name" "$interpolated_fn_name")"
311+
state::reset_test_title
312+
294313
if [[ -n $runtime_error || $test_exit_code -ne 0 ]]; then
295314
state::add_tests_failed
296-
console_results::print_error_test "$fn_name" "$runtime_error"
297-
reports::add_test_failed "$test_file" "$fn_name" "$duration" "$total_assertions"
315+
console_results::print_error_test "$label" "$runtime_error"
316+
reports::add_test_failed "$test_file" "$label" "$duration" "$total_assertions"
298317
runner::write_failure_result_output "$test_file" "$fn_name" "$runtime_error"
299-
internal_log "Test error" "$fn_name" "$runtime_error"
318+
internal_log "Test error" "$label" "$runtime_error"
300319
return
301320
fi
302321

303322
if [[ "$current_assertions_failed" != "$(state::get_assertions_failed)" ]]; then
304323
state::add_tests_failed
305-
reports::add_test_failed "$test_file" "$fn_name" "$duration" "$total_assertions"
324+
reports::add_test_failed "$test_file" "$label" "$duration" "$total_assertions"
306325
runner::write_failure_result_output "$test_file" "$fn_name" "$subshell_output"
307326

308-
internal_log "Test failed" "$fn_name"
327+
internal_log "Test failed" "$label"
309328

310329
if env::is_stop_on_failure_enabled; then
311330
if parallel::is_enabled; then
@@ -319,36 +338,34 @@ function runner::run_test() {
319338

320339
if [[ "$current_assertions_snapshot" != "$(state::get_assertions_snapshot)" ]]; then
321340
state::add_tests_snapshot
322-
console_results::print_snapshot_test "$fn_name"
323-
reports::add_test_snapshot "$test_file" "$fn_name" "$duration" "$total_assertions"
324-
internal_log "Test snapshot" "$fn_name"
341+
console_results::print_snapshot_test "$label"
342+
reports::add_test_snapshot "$test_file" "$label" "$duration" "$total_assertions"
343+
internal_log "Test snapshot" "$label"
325344
return
326345
fi
327346

328347
if [[ "$current_assertions_incomplete" != "$(state::get_assertions_incomplete)" ]]; then
329348
state::add_tests_incomplete
330-
reports::add_test_incomplete "$test_file" "$fn_name" "$duration" "$total_assertions"
331-
internal_log "Test incomplete" "$fn_name"
349+
reports::add_test_incomplete "$test_file" "$label" "$duration" "$total_assertions"
350+
internal_log "Test incomplete" "$label"
332351
return
333352
fi
334353

335354
if [[ "$current_assertions_skipped" != "$(state::get_assertions_skipped)" ]]; then
336355
state::add_tests_skipped
337-
reports::add_test_skipped "$test_file" "$fn_name" "$duration" "$total_assertions"
338-
internal_log "Test skipped" "$fn_name"
356+
reports::add_test_skipped "$test_file" "$label" "$duration" "$total_assertions"
357+
internal_log "Test skipped" "$label"
339358
return
340359
fi
341360

342-
local label="$(helper::normalize_test_function_name "$fn_name" "$interpolated_fn_name")"
343-
344361
if [[ "$fn_name" == "$interpolated_fn_name" ]]; then
345362
console_results::print_successful_test "${label}" "$duration" "$@"
346363
else
347364
console_results::print_successful_test "${label}" "$duration"
348365
fi
349366
state::add_tests_passed
350-
reports::add_test_passed "$test_file" "$fn_name" "$duration" "$total_assertions"
351-
internal_log "Test passed" "$fn_name"
367+
reports::add_test_passed "$test_file" "$label" "$duration" "$total_assertions"
368+
internal_log "Test passed" "$label"
352369
}
353370

354371
function runner::decode_subshell_output() {

src/state.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ _DUPLICATED_FUNCTION_NAMES=""
1414
_FILE_WITH_DUPLICATED_FUNCTION_NAMES=""
1515
_DUPLICATED_TEST_FUNCTIONS_FOUND=false
1616
_TEST_OUTPUT=""
17+
_TEST_TITLE=""
1718
_TEST_EXIT_CODE=0
1819

1920
function state::get_tests_passed() {
@@ -132,6 +133,18 @@ function state::set_test_exit_code() {
132133
_TEST_EXIT_CODE="$1"
133134
}
134135

136+
function state::get_test_title() {
137+
echo "$_TEST_TITLE"
138+
}
139+
140+
function state::set_test_title() {
141+
_TEST_TITLE="$1"
142+
}
143+
144+
function state::reset_test_title() {
145+
_TEST_TITLE=""
146+
}
147+
135148
function state::set_duplicated_functions_merged() {
136149
state::set_duplicated_test_functions_found
137150
state::set_file_with_duplicated_function_names "$1"
@@ -145,17 +158,21 @@ function state::initialize_assertions_count() {
145158
_ASSERTIONS_INCOMPLETE=0
146159
_ASSERTIONS_SNAPSHOT=0
147160
_TEST_OUTPUT=""
161+
_TEST_TITLE=""
148162
}
149163

150164
function state::export_subshell_context() {
151165
local encoded_test_output
166+
local encoded_test_title
152167

153168
if base64 --help 2>&1 | grep -q -- "-w"; then
154169
# Alpine requires the -w 0 option to avoid wrapping
155170
encoded_test_output=$(echo -n "$_TEST_OUTPUT" | base64 -w 0)
171+
encoded_test_title=$(echo -n "$_TEST_TITLE" | base64 -w 0)
156172
else
157173
# macOS and others: default base64 without wrapping
158174
encoded_test_output=$(echo -n "$_TEST_OUTPUT" | base64)
175+
encoded_test_title=$(echo -n "$_TEST_TITLE" | base64)
159176
fi
160177

161178
cat <<EOF
@@ -165,6 +182,7 @@ function state::export_subshell_context() {
165182
##ASSERTIONS_INCOMPLETE=$_ASSERTIONS_INCOMPLETE\
166183
##ASSERTIONS_SNAPSHOT=$_ASSERTIONS_SNAPSHOT\
167184
##TEST_EXIT_CODE=$_TEST_EXIT_CODE\
185+
##TEST_TITLE=$encoded_test_title\
168186
##TEST_OUTPUT=$encoded_test_output\
169187
##
170188
EOF

src/test_title.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
function set_test_title() {
4+
state::set_test_title "$1"
5+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
function set_up_before_script() {
5+
TEST_ENV_FILE="tests/acceptance/fixtures/.env.default"
6+
}
7+
8+
function test_bashunit_resets_custom_title_between_tests() {
9+
local test_file=./tests/acceptance/fixtures/test_custom_title.sh
10+
local output
11+
output="$(./bashunit --no-parallel --env "$TEST_ENV_FILE" "$test_file")"
12+
assert_successful_code "$output"
13+
assert_contains "🔥 handles invalid input with 💣" "$output"
14+
assert_contains "Default title" "$output"
15+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
3+
function test_custom_title() {
4+
set_test_title "🔥 handles invalid input with 💣"
5+
assert_true true
6+
}
7+
8+
function test_default_title() {
9+
assert_true true
10+
}

tests/unit/helpers_test.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ function test_normalize_test_function_name_camel_case() {
3232
assert_same "SomeLogic" "$(helper::normalize_test_function_name "testSomeLogic")"
3333
}
3434

35+
function test_normalize_test_function_name_custom_title() {
36+
set_test_title "🔥 handles invalid input with 💣"
37+
assert_same "🔥 handles invalid input with 💣" "$(helper::normalize_test_function_name "test_handles_invalid_input")"
38+
}
39+
3540
function test_get_functions_to_run_no_filter_should_return_all_functions() {
3641
local functions=("prefix_function1" "prefix_function2" "other_function" "prefix_function3")
3742

tests/unit/state_test.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ function test_initialize_assertions_count() {
255255
##ASSERTIONS_INCOMPLETE=0\
256256
##ASSERTIONS_SNAPSHOT=0\
257257
##TEST_EXIT_CODE=0\
258+
##TEST_TITLE=\
258259
##TEST_OUTPUT=\
259260
##"\
260261
"$export_assertions_count"
@@ -284,6 +285,7 @@ function test_export_assertions_count() {
284285
##ASSERTIONS_INCOMPLETE=12\
285286
##ASSERTIONS_SNAPSHOT=33\
286287
##TEST_EXIT_CODE=1\
288+
##TEST_TITLE=\
287289
##TEST_OUTPUT=$(echo -n "something" | base64)##"\
288290
"$export_assertions_count"
289291
}

0 commit comments

Comments
 (0)