Skip to content

Commit 196fb4a

Browse files
authored
Merge pull request #530 from TypedDevs/feat/528-improve-how-to-use-custom-assertions
Improve how to use custom assertions
2 parents 3332295 + 72980ef commit 196fb4a

10 files changed

Lines changed: 425 additions & 59 deletions

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Fixed
6+
- Custom assertions now display the correct test function name in failure messages
7+
38
## [0.28.0](https://github.com/TypedDevs/bashunit/compare/0.27.0...0.28.0) - 2025-12-01
49

510
### Added

docs/custom-asserts.md

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,33 @@ Check the internal functional tests: `tests/functional/custom_asserts_test.sh` (
1010
When using the bashunit facade, assertions automatically respect the guard behavior: if a previous assertion in the same test already failed, subsequent assertions are skipped. This matches popular testing libraries default behavior.
1111
:::
1212

13-
## assertion_failed
13+
::: info Test name detection
14+
Custom assertions automatically display the correct **test function name** in failure messages, not the custom assertion name. This makes it easy to identify which test failed, even when using deeply nested custom assertions.
15+
:::
16+
17+
## API Reference
18+
19+
### assertion_failed
1420
> `bashunit::assertion_failed <expected> <actual> <failure_condition_message?>`
1521
16-
## assertion_passed
22+
Marks the current assertion as failed and prints a failure message.
23+
24+
| Parameter | Description |
25+
|-----------|-------------|
26+
| `expected` | The expected value |
27+
| `actual` | The actual value received |
28+
| `failure_condition_message` | Optional message describing the failure condition (default: "but got") |
29+
30+
### assertion_passed
1731
> `bashunit::assertion_passed`
1832
19-
## Example
33+
Marks the current assertion as passed. Call this when your custom assertion succeeds.
34+
35+
## Examples
36+
37+
### Basic custom assertion
2038

2139
```bash
22-
# Your custom assert using the bashunit facade
2340
function assert_foo() {
2441
local actual="$1"
2542

@@ -31,8 +48,76 @@ function assert_foo() {
3148
bashunit::assertion_passed
3249
}
3350

34-
# Your test using your custom assert
35-
function test_assert_foo_passed() {
36-
assert_foo "foo"
51+
function test_value_is_foo() {
52+
assert_foo "foo" # Passes
53+
}
54+
55+
function test_value_is_not_foo() {
56+
assert_foo "bar" # Fails with: "Failed: Value is not foo"
57+
}
58+
```
59+
60+
### Using fail() for simple messages
61+
62+
You can also use `fail` for custom assertions that just need a message:
63+
64+
```bash
65+
function assert_valid_json() {
66+
local json="$1"
67+
68+
if ! echo "$json" | jq . > /dev/null 2>&1; then
69+
fail "Invalid JSON: $json"
70+
return
71+
fi
72+
73+
bashunit::assertion_passed
74+
}
75+
76+
function test_api_returns_valid_json() {
77+
local response='{"status": "ok"}'
78+
assert_valid_json "$response"
3779
}
3880
```
81+
82+
### Composing with existing assertions
83+
84+
Custom assertions can call other bashunit assertions internally:
85+
86+
```bash
87+
function assert_http_success() {
88+
local status_code="$1"
89+
90+
assert_greater_or_equal_than "200" "$status_code"
91+
assert_less_than "300" "$status_code"
92+
}
93+
94+
function test_api_returns_success() {
95+
local status_code=200
96+
assert_http_success "$status_code"
97+
}
98+
```
99+
100+
### Custom assertion with custom failure message
101+
102+
```bash
103+
function assert_positive_number() {
104+
local actual="$1"
105+
106+
if [[ "$actual" -le 0 ]]; then
107+
bashunit::assertion_failed "positive number" "$actual" "got"
108+
return
109+
fi
110+
111+
bashunit::assertion_passed
112+
}
113+
```
114+
115+
## Best practices
116+
117+
1. **Always return after failure**: Call `return` after `bashunit::assertion_failed` or `fail` to stop execution of your custom assertion.
118+
119+
2. **Always mark success**: Call `bashunit::assertion_passed` or `state::add_assertions_passed` when your assertion succeeds.
120+
121+
3. **Use descriptive names**: Name your custom assertions clearly, e.g., `assert_valid_email`, `assert_file_contains_header`.
122+
123+
4. **Keep assertions focused**: Each custom assertion should test one specific condition.

0 commit comments

Comments
 (0)