From d556d22272a0de92fbb3ba45c78e3562589b5bc8 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Sun, 19 Jul 2026 15:56:29 +0200 Subject: [PATCH] perf(test): mock measure_ms in assert_duration failure paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The three failure-path tests only exercise the threshold comparison and the failure message, yet each paid a real 'sleep 1' — 3s of the file's 3.3s runtime. Mock bashunit::duration::measure_ms (heredoc form, so call args are not appended to the fake reading) and assert against fake commands instead: ~3.3s -> ~0.4s. One success path keeps a real short sleep so measure_ms integration stays covered end-to-end, guarded to skip under the last-resort date-seconds clock whose 1s resolution would read 'sleep 0.2' as 0ms. Closes #826 --- tests/unit/assert_duration_test.sh | 31 +++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/tests/unit/assert_duration_test.sh b/tests/unit/assert_duration_test.sh index 40472ef4..35645b57 100644 --- a/tests/unit/assert_duration_test.sh +++ b/tests/unit/assert_duration_test.sh @@ -9,12 +9,17 @@ function test_successful_assert_duration_within_fast_command() { assert_empty "$(assert_duration "echo hello" 5000)" } +# Failure paths mock bashunit::duration::measure_ms: they exercise the +# threshold comparison and failure message, not the timing itself, so a real +# `sleep 1` per test only slowed the suite down (#826). function test_unsuccessful_assert_duration_exceeds_threshold() { + bashunit::mock bashunit::duration::measure_ms <<<"2000" + assert_same \ "$(bashunit::console_results::print_failed_test \ "Unsuccessful assert duration exceeds threshold" \ - "1000" "to complete within (ms)" "sleep 1")" \ - "$(assert_duration "sleep 1" 1000)" + "1000" "to complete within (ms)" "fake_slow_command")" \ + "$(assert_duration "fake_slow_command" 1000)" } function test_successful_assert_duration_less_than() { @@ -22,21 +27,33 @@ function test_successful_assert_duration_less_than() { } function test_unsuccessful_assert_duration_less_than() { + bashunit::mock bashunit::duration::measure_ms <<<"2000" + assert_same \ "$(bashunit::console_results::print_failed_test \ "Unsuccessful assert duration less than" \ - "100" "to complete within (ms)" "sleep 1")" \ - "$(assert_duration_less_than "sleep 1" 100)" + "100" "to complete within (ms)" "fake_slow_command")" \ + "$(assert_duration_less_than "fake_slow_command" 100)" } +# Keep one success path on a real (short) sleep so measure_ms integration +# stays covered end-to-end. The last-resort date-seconds clock has 1s +# resolution and would measure a sub-second sleep as 0ms, so skip there. function test_successful_assert_duration_greater_than() { - assert_empty "$(assert_duration_greater_than "sleep 1" 500)" + bashunit::clock::now_to_slot >/dev/null 2>&1 || true + if [ "${_BASHUNIT_CLOCK_NOW_IMPL:-}" = "date-seconds" ]; then + bashunit::skip "clock has 1s resolution" && return + fi + + assert_empty "$(assert_duration_greater_than "sleep 0.2" 100)" } function test_unsuccessful_assert_duration_greater_than() { + bashunit::mock bashunit::duration::measure_ms <<<"3" + assert_same \ "$(bashunit::console_results::print_failed_test \ "Unsuccessful assert duration greater than" \ - "5000" "to take at least (ms)" "echo hello")" \ - "$(assert_duration_greater_than "echo hello" 5000)" + "5000" "to take at least (ms)" "fake_fast_command")" \ + "$(assert_duration_greater_than "fake_fast_command" 5000)" }