Skip to content

Commit c97696c

Browse files
committed
chore: enable chain asserts standalone assertions
1 parent 2f4068d commit c97696c

6 files changed

Lines changed: 85 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- Improve clock performance
1313
- Make install.sh args more flexible
1414
- Improve Windows detection allowing parallel tests on Git Bash, MSYS and Cygwin
15+
- Enable chain asserts standalone assertions
1516

1617
## [0.20.0](https://github.com/TypedDevs/bashunit/compare/0.19.1...0.20.0) - 2025-06-01
1718

bashunit

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,31 @@ source "$BASHUNIT_ROOT_DIR/src/main.sh"
3333
_ASSERT_FN=""
3434
_FILTER=""
3535
_RAW_ARGS=()
36+
_ASSERT_FNS=()
37+
_ASSERT_ARGS_LIST=()
38+
_CURRENT_ASSERT_ARGS=()
39+
_ASSERT_COUNT=0
40+
_CURRENT_ASSERT_FN=""
3641
_ARGS=()
3742
_BENCH_MODE=false
3843

3944
check_os::init
4045
clock::init
4146

4247
# Argument parsing
43-
while [[ $# -gt 0 ]]; do
44-
case "$1" in
45-
-a|--assert)
46-
_ASSERT_FN="$2"
47-
shift
48-
;;
48+
while [[ $# -gt 0 ]]; do
49+
case "$1" in
50+
-a|--assert)
51+
if [[ -n "$_CURRENT_ASSERT_FN" ]]; then
52+
_ASSERT_FNS+=("$_CURRENT_ASSERT_FN")
53+
joined="$(printf '%s\n' "${_CURRENT_ASSERT_ARGS[@]}")"
54+
_ASSERT_ARGS_LIST+=("$joined")
55+
_ASSERT_COUNT=$(( _ASSERT_COUNT + 1 ))
56+
_CURRENT_ASSERT_ARGS=()
57+
fi
58+
_CURRENT_ASSERT_FN="$2"
59+
shift
60+
;;
4961
-f|--filter)
5062
_FILTER="$2"
5163
shift
@@ -106,11 +118,20 @@ while [[ $# -gt 0 ]]; do
106118
trap '' EXIT && exit 0
107119
;;
108120
*)
109-
_RAW_ARGS+=("$1")
121+
if [[ -n "$_CURRENT_ASSERT_FN" ]]; then
122+
_CURRENT_ASSERT_ARGS+=("$1")
123+
else
124+
_RAW_ARGS+=("$1")
125+
fi
110126
;;
111127
esac
112128
shift
113129
done
130+
if [[ -n "$_CURRENT_ASSERT_FN" ]]; then
131+
_ASSERT_FNS+=("$_CURRENT_ASSERT_FN")
132+
joined="$(printf '%s\n' "${_CURRENT_ASSERT_ARGS[@]}")"
133+
_ASSERT_ARGS_LIST+=("$joined")
134+
fi
114135

115136
# Expand positional arguments after all options have been processed
116137
if [[ ${#_RAW_ARGS[@]} -gt 0 ]]; then
@@ -132,8 +153,16 @@ set +eu
132153
#################
133154
# Main execution
134155
#################
135-
if [[ -n "$_ASSERT_FN" ]]; then
136-
main::exec_assert "$_ASSERT_FN" "${_ARGS[@]}"
156+
if [[ ${#_ASSERT_FNS[@]} -gt 0 ]]; then
157+
if [[ ${#_ASSERT_FNS[@]} -eq 1 ]]; then
158+
args=()
159+
while IFS= read -r line; do
160+
args+=("$line")
161+
done <<< "${_ASSERT_ARGS_LIST[0]}"
162+
main::exec_assert "${_ASSERT_FNS[0]}" "${args[@]}"
163+
else
164+
main::exec_assert_chain
165+
fi
137166
elif [[ "$_BENCH_MODE" == true ]]; then
138167
main::exec_benchmarks "$_FILTER" "${_ARGS[@]}"
139168
else

docs/assertions.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,13 @@ function test_failure() {
366366
```
367367
:::
368368
369+
You can chain another assertion to inspect the generated output when using
370+
`assert_exit_code` standalone with the `-a` option:
371+
372+
```bash
373+
bashunit -a exit_code "1" "my_program" -a contains "error"
374+
```
375+
369376
## assert_array_contains
370377
> `assert_array_contains "needle" "haystack"`
371378

docs/standalone.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ OUTPUT=$(./bashunit -a exit_code "1" "$PHPSTAN_PATH analyze \
7373
```
7474
:::
7575

76+
You can also chain assertions directly using multiple `-a` flags.
77+
The output from `exit_code` will be passed as the last argument of the next assertion:
78+
79+
::: code-group
80+
```bash [Example]
81+
./bashunit -a exit_code "1" "my_program" -a contains "some error"
82+
```
83+
```[Output]
84+
# No output
85+
```
86+
:::
87+
7688
### Full control over the stdout and stderr
7789

7890
The stdout will be used for the callable result, while bashunit output will be on stderr.

src/main.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,28 @@ function main::exec_assert() {
164164
return "$bashunit_exit_code"
165165
}
166166

167+
function main::exec_assert_chain() {
168+
local output=""
169+
local exit_code=0
170+
171+
for idx in "${!_ASSERT_FNS[@]}"; do
172+
local fn="${_ASSERT_FNS[$idx]}"
173+
args=()
174+
while IFS= read -r line; do
175+
args+=("$line")
176+
done <<< "${_ASSERT_ARGS_LIST[$idx]}"
177+
if [[ $idx -gt 0 ]]; then
178+
args+=("$output")
179+
fi
180+
state::initialize_assertions_count
181+
output=$(main::exec_assert "$fn" "${args[@]}")
182+
exit_code=$?
183+
done
184+
185+
[[ -n "$output" ]] && echo "$output"
186+
return "$exit_code"
187+
}
188+
167189
function main::handle_assert_exit_code() {
168190
local cmd="$1"
169191
local output

tests/acceptance/bashunit_direct_fn_call_test.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,8 @@ function test_bashunit_assert_exit_code_str_successful_and_exit_code_ok() {
138138
assert_same "something to stdout" "$output"
139139
assert_empty "$(cat "$temp")"
140140
}
141+
142+
function test_bashunit_assert_exit_code_and_contains_chained() {
143+
./bashunit -a exit_code "1" "bash -c 'echo some error; exit 1'" -a contains "some error"
144+
assert_successful_code
145+
}

0 commit comments

Comments
 (0)