Skip to content

chore: enable chain asserts standalone assertions #432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Improve clock performance
- Make install.sh args more flexible
- Improve Windows detection allowing parallel tests on Git Bash, MSYS and Cygwin
- Enable chain asserts standalone assertions

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

Expand Down
47 changes: 38 additions & 9 deletions bashunit
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,31 @@ source "$BASHUNIT_ROOT_DIR/src/main.sh"
_ASSERT_FN=""
_FILTER=""
_RAW_ARGS=()
_ASSERT_FNS=()
_ASSERT_ARGS_LIST=()
_CURRENT_ASSERT_ARGS=()
_ASSERT_COUNT=0
_CURRENT_ASSERT_FN=""
_ARGS=()
_BENCH_MODE=false

check_os::init
clock::init

# Argument parsing
while [[ $# -gt 0 ]]; do
case "$1" in
-a|--assert)
_ASSERT_FN="$2"
shift
;;
while [[ $# -gt 0 ]]; do
case "$1" in
-a|--assert)
if [[ -n "$_CURRENT_ASSERT_FN" ]]; then
_ASSERT_FNS+=("$_CURRENT_ASSERT_FN")
joined="$(printf '%s\n' "${_CURRENT_ASSERT_ARGS[@]}")"
_ASSERT_ARGS_LIST+=("$joined")
_ASSERT_COUNT=$(( _ASSERT_COUNT + 1 ))
_CURRENT_ASSERT_ARGS=()
fi
_CURRENT_ASSERT_FN="$2"
shift
;;
-f|--filter)
_FILTER="$2"
shift
Expand Down Expand Up @@ -106,11 +118,20 @@ while [[ $# -gt 0 ]]; do
trap '' EXIT && exit 0
;;
*)
_RAW_ARGS+=("$1")
if [[ -n "$_CURRENT_ASSERT_FN" ]]; then
_CURRENT_ASSERT_ARGS+=("$1")
else
_RAW_ARGS+=("$1")
fi
;;
esac
shift
done
if [[ -n "$_CURRENT_ASSERT_FN" ]]; then
_ASSERT_FNS+=("$_CURRENT_ASSERT_FN")
joined="$(printf '%s\n' "${_CURRENT_ASSERT_ARGS[@]}")"
_ASSERT_ARGS_LIST+=("$joined")
fi

# Expand positional arguments after all options have been processed
if [[ ${#_RAW_ARGS[@]} -gt 0 ]]; then
Expand All @@ -132,8 +153,16 @@ set +eu
#################
# Main execution
#################
if [[ -n "$_ASSERT_FN" ]]; then
main::exec_assert "$_ASSERT_FN" "${_ARGS[@]}"
if [[ ${#_ASSERT_FNS[@]} -gt 0 ]]; then
if [[ ${#_ASSERT_FNS[@]} -eq 1 ]]; then
args=()
while IFS= read -r line; do
args+=("$line")
done <<< "${_ASSERT_ARGS_LIST[0]}"
main::exec_assert "${_ASSERT_FNS[0]}" "${args[@]}"
else
main::exec_assert_chain
fi
elif [[ "$_BENCH_MODE" == true ]]; then
main::exec_benchmarks "$_FILTER" "${_ARGS[@]}"
else
Expand Down
7 changes: 7 additions & 0 deletions docs/assertions.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ function test_failure() {
```
:::

You can chain another assertion to inspect the generated output when using
`assert_exit_code` standalone with the `-a` option:

```bash
bashunit -a exit_code "1" "my_program" -a contains "error"
```

## assert_array_contains
> `assert_array_contains "needle" "haystack"`

Expand Down
12 changes: 12 additions & 0 deletions docs/standalone.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ OUTPUT=$(./bashunit -a exit_code "1" "$PHPSTAN_PATH analyze \
```
:::

You can also chain assertions directly using multiple `-a` flags.
The output from `exit_code` will be passed as the last argument of the next assertion:

::: code-group
```bash [Example]
./bashunit -a exit_code "1" "my_program" -a contains "some error"
```
```[Output]
# No output
```
:::

### Full control over the stdout and stderr

The stdout will be used for the callable result, while bashunit output will be on stderr.
Expand Down
22 changes: 22 additions & 0 deletions src/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,28 @@ function main::exec_assert() {
return "$bashunit_exit_code"
}

function main::exec_assert_chain() {
local output=""
local exit_code=0

for idx in "${!_ASSERT_FNS[@]}"; do
local fn="${_ASSERT_FNS[$idx]}"
args=()
while IFS= read -r line; do
args+=("$line")
done <<< "${_ASSERT_ARGS_LIST[$idx]}"
if [[ $idx -gt 0 ]]; then
args+=("$output")
fi
state::initialize_assertions_count
output=$(main::exec_assert "$fn" "${args[@]}")
exit_code=$?
done

[[ -n "$output" ]] && echo "$output"
return "$exit_code"
}

function main::handle_assert_exit_code() {
local cmd="$1"
local output
Expand Down
5 changes: 5 additions & 0 deletions tests/acceptance/bashunit_direct_fn_call_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,8 @@ function test_bashunit_assert_exit_code_str_successful_and_exit_code_ok() {
assert_same "something to stdout" "$output"
assert_empty "$(cat "$temp")"
}

function test_bashunit_assert_exit_code_and_contains_chained() {
./bashunit -a exit_code "1" "bash -c 'echo some error; exit 1'" -a contains "some error"
assert_successful_code
}
Loading