Skip to content

Commit 1400383

Browse files
authored
perf(helpers): inline normalize+random in generate_id; drop grep fork (#673)
1 parent 1cae56f commit 1400383

3 files changed

Lines changed: 64 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Hot-path coverage flag now cached in `_BASHUNIT_COVERAGE_ON`, removing a function dispatch per call (#664)
88
- Parallel runner blocks on `wait -n` on Bash 4.3+ instead of polling `jobs -r`, removing sleep-induced slot-release latency (#667)
99
- Hot-path result helpers (`extract_encoded_field`, `extract_subshell_type`, `format_subshell_output`, `compute_total_assertions`) use outvar pattern, dropping a fork per call per test (#662)
10+
- `generate_id` and `normalize_variable_name` drop `grep` and `random_str` forks via pure-bash globbing/inlining (#663)
1011

1112
## [0.36.0](https://github.com/TypedDevs/bashunit/compare/0.35.0...0.36.0) - 2026-05-07
1213

src/helpers.sh

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -268,14 +268,15 @@ function bashunit::helper::find_files_recursive() {
268268

269269
function bashunit::helper::normalize_variable_name() {
270270
local input_string="$1"
271-
local normalized_string
272-
273-
normalized_string="${input_string//[^a-zA-Z0-9_]/_}"
274-
275-
local _re='^[a-zA-Z_]'
276-
if [ "$(builtin echo "$normalized_string" | "$GREP" -cE "$_re" || true)" -eq 0 ]; then
277-
normalized_string="_$normalized_string"
278-
fi
271+
local normalized_string="${input_string//[^a-zA-Z0-9_]/_}"
272+
273+
# First character must be alpha or underscore. Empty string also gets a `_`
274+
# prefix to satisfy the same identifier rule. Uses pure-bash globbing to
275+
# avoid a per-call grep fork (called once per test via generate_id).
276+
case "${normalized_string:0:1}" in
277+
[a-zA-Z_]) ;;
278+
*) normalized_string="_$normalized_string" ;;
279+
esac
279280

280281
builtin echo "$normalized_string"
281282
}
@@ -439,12 +440,23 @@ function bashunit::helper::get_function_line_number() {
439440

440441
function bashunit::helper::generate_id() {
441442
local basename="$1"
442-
local sanitized_basename
443-
sanitized_basename="$(bashunit::helper::normalize_variable_name "$basename")"
443+
# Inline normalize_variable_name + random_str to avoid two forks per call.
444+
# generate_id is called once per test and per file load.
445+
local sanitized="${basename//[^a-zA-Z0-9_]/_}"
446+
case "${sanitized:0:1}" in
447+
[a-zA-Z_]) ;;
448+
*) sanitized="_$sanitized" ;;
449+
esac
444450
if bashunit::env::is_parallel_run_enabled; then
445-
echo "${sanitized_basename}_$$_$(bashunit::random_str 6)"
451+
local _chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
452+
local _suffix=''
453+
local _i
454+
for ((_i = 0; _i < 6; _i++)); do
455+
_suffix="$_suffix${_chars:RANDOM%${#_chars}:1}"
456+
done
457+
echo "${sanitized}_$$_${_suffix}"
446458
else
447-
echo "${sanitized_basename}_$$"
459+
echo "${sanitized}_$$"
448460
fi
449461
}
450462

tests/unit/helpers_test.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,45 @@ function test_check_duplicate_functions_without_function_keyword() {
127127
assert_general_error "$(bashunit::helper::check_duplicate_functions "$file")"
128128
}
129129

130+
function test_generate_id_uses_pid_suffix_when_not_parallel() {
131+
local _orig="${BASHUNIT_PARALLEL_RUN-}"
132+
export BASHUNIT_PARALLEL_RUN=false
133+
134+
local id
135+
id="$(bashunit::helper::generate_id "test_foo")"
136+
assert_same "test_foo_$$" "$id"
137+
138+
export BASHUNIT_PARALLEL_RUN="$_orig"
139+
}
140+
141+
function test_generate_id_appends_random_suffix_when_parallel() {
142+
local _orig="${BASHUNIT_PARALLEL_RUN-}"
143+
export BASHUNIT_PARALLEL_RUN=true
144+
145+
local id1 id2
146+
id1="$(bashunit::helper::generate_id "test_foo")"
147+
id2="$(bashunit::helper::generate_id "test_foo")"
148+
149+
assert_matches "^test_foo_${$}_[a-zA-Z0-9]{6}$" "$id1"
150+
assert_matches "^test_foo_${$}_[a-zA-Z0-9]{6}$" "$id2"
151+
152+
export BASHUNIT_PARALLEL_RUN="$_orig"
153+
}
154+
155+
function test_generate_id_sanitizes_basename() {
156+
local _orig="${BASHUNIT_PARALLEL_RUN-}"
157+
export BASHUNIT_PARALLEL_RUN=false
158+
159+
local id
160+
id="$(bashunit::helper::generate_id "my-file.sh")"
161+
assert_same "my_file_sh_$$" "$id"
162+
163+
id="$(bashunit::helper::generate_id "123start")"
164+
assert_same "_123start_$$" "$id"
165+
166+
export BASHUNIT_PARALLEL_RUN="$_orig"
167+
}
168+
130169
function test_normalize_variable_name() {
131170
assert_same "valid_name123" "$(bashunit::helper::normalize_variable_name "valid_name123")"
132171
assert_same "non_valid_symbols__________" "$(bashunit::helper::normalize_variable_name "non_valid_symbols!@#$%^&*()")"

0 commit comments

Comments
 (0)