|  | 
| 1 | 1 | '\" t | 
| 2 | 2 | .\"     Title: bash_unit | 
| 3 | 3 | .\"    Author: [see the "AUTHOR(S)" section] | 
| 4 |  | -.\" Generator: Asciidoctor 2.0.21 | 
| 5 |  | -.\"      Date: 2024-03-05 | 
|  | 4 | +.\" Generator: Asciidoctor 2.0.23 | 
|  | 5 | +.\"      Date: 2025-01-08 | 
| 6 | 6 | .\"    Manual: \ \& | 
| 7 | 7 | .\"    Source: \ \& | 
| 8 | 8 | .\"  Language: English | 
| 9 | 9 | .\" | 
| 10 |  | -.TH "BASH_UNIT" "1" "2024-03-05" "\ \&" "\ \&" | 
|  | 10 | +.TH "BASH_UNIT" "1" "2025-01-08" "\ \&" "\ \&" | 
| 11 | 11 | .ie \n(.g .ds Aq \(aq | 
| 12 | 12 | .el       .ds Aq ' | 
| 13 | 13 | .ss \n[.ss] 0 | 
| @@ -42,6 +42,140 @@ You might want to take a look at \c | 
| 42 | 42 | .URL "getting_started" "how to get started" | 
| 43 | 43 | before continuing reading this documentation. | 
| 44 | 44 | .sp | 
|  | 45 | +The following functions are available in your tests (see below for detailed documentation): | 
|  | 46 | +.sp | 
|  | 47 | +.RS 4 | 
|  | 48 | +.ie n \{\ | 
|  | 49 | +\h'-04'\(bu\h'+03'\c | 
|  | 50 | +.\} | 
|  | 51 | +.el \{\ | 
|  | 52 | +.  sp -1 | 
|  | 53 | +.  IP \(bu 2.3 | 
|  | 54 | +.\} | 
|  | 55 | +\f(CRfail [message]\fP | 
|  | 56 | +.RE | 
|  | 57 | +.sp | 
|  | 58 | +.RS 4 | 
|  | 59 | +.ie n \{\ | 
|  | 60 | +\h'-04'\(bu\h'+03'\c | 
|  | 61 | +.\} | 
|  | 62 | +.el \{\ | 
|  | 63 | +.  sp -1 | 
|  | 64 | +.  IP \(bu 2.3 | 
|  | 65 | +.\} | 
|  | 66 | +\f(CRassert <assertion> [message]\fP | 
|  | 67 | +.RE | 
|  | 68 | +.sp | 
|  | 69 | +.RS 4 | 
|  | 70 | +.ie n \{\ | 
|  | 71 | +\h'-04'\(bu\h'+03'\c | 
|  | 72 | +.\} | 
|  | 73 | +.el \{\ | 
|  | 74 | +.  sp -1 | 
|  | 75 | +.  IP \(bu 2.3 | 
|  | 76 | +.\} | 
|  | 77 | +\f(CRassert_fail <assertion> [message]\fP | 
|  | 78 | +.RE | 
|  | 79 | +.sp | 
|  | 80 | +.RS 4 | 
|  | 81 | +.ie n \{\ | 
|  | 82 | +\h'-04'\(bu\h'+03'\c | 
|  | 83 | +.\} | 
|  | 84 | +.el \{\ | 
|  | 85 | +.  sp -1 | 
|  | 86 | +.  IP \(bu 2.3 | 
|  | 87 | +.\} | 
|  | 88 | +\f(CRassert_status_code <expected_status_code> <assertion> [message]\fP | 
|  | 89 | +.RE | 
|  | 90 | +.sp | 
|  | 91 | +.RS 4 | 
|  | 92 | +.ie n \{\ | 
|  | 93 | +\h'-04'\(bu\h'+03'\c | 
|  | 94 | +.\} | 
|  | 95 | +.el \{\ | 
|  | 96 | +.  sp -1 | 
|  | 97 | +.  IP \(bu 2.3 | 
|  | 98 | +.\} | 
|  | 99 | +\f(CRassert_equals <expected> <actual> [message]\fP | 
|  | 100 | +.RE | 
|  | 101 | +.sp | 
|  | 102 | +.RS 4 | 
|  | 103 | +.ie n \{\ | 
|  | 104 | +\h'-04'\(bu\h'+03'\c | 
|  | 105 | +.\} | 
|  | 106 | +.el \{\ | 
|  | 107 | +.  sp -1 | 
|  | 108 | +.  IP \(bu 2.3 | 
|  | 109 | +.\} | 
|  | 110 | +\f(CRassert_not_equals <unexpected> <actual> [message]\fP | 
|  | 111 | +.RE | 
|  | 112 | +.sp | 
|  | 113 | +.RS 4 | 
|  | 114 | +.ie n \{\ | 
|  | 115 | +\h'-04'\(bu\h'+03'\c | 
|  | 116 | +.\} | 
|  | 117 | +.el \{\ | 
|  | 118 | +.  sp -1 | 
|  | 119 | +.  IP \(bu 2.3 | 
|  | 120 | +.\} | 
|  | 121 | +\f(CRassert_matches <expected\-regex> <actual> [message]\fP | 
|  | 122 | +.RE | 
|  | 123 | +.sp | 
|  | 124 | +.RS 4 | 
|  | 125 | +.ie n \{\ | 
|  | 126 | +\h'-04'\(bu\h'+03'\c | 
|  | 127 | +.\} | 
|  | 128 | +.el \{\ | 
|  | 129 | +.  sp -1 | 
|  | 130 | +.  IP \(bu 2.3 | 
|  | 131 | +.\} | 
|  | 132 | +\f(CRassert_not_matches <unexpected\-regex> <actual> [message]\fP | 
|  | 133 | +.RE | 
|  | 134 | +.sp | 
|  | 135 | +.RS 4 | 
|  | 136 | +.ie n \{\ | 
|  | 137 | +\h'-04'\(bu\h'+03'\c | 
|  | 138 | +.\} | 
|  | 139 | +.el \{\ | 
|  | 140 | +.  sp -1 | 
|  | 141 | +.  IP \(bu 2.3 | 
|  | 142 | +.\} | 
|  | 143 | +\f(CRassert_within_delta <expected num> <actual num> <max delta> [message]\fP | 
|  | 144 | +.RE | 
|  | 145 | +.sp | 
|  | 146 | +.RS 4 | 
|  | 147 | +.ie n \{\ | 
|  | 148 | +\h'-04'\(bu\h'+03'\c | 
|  | 149 | +.\} | 
|  | 150 | +.el \{\ | 
|  | 151 | +.  sp -1 | 
|  | 152 | +.  IP \(bu 2.3 | 
|  | 153 | +.\} | 
|  | 154 | +\f(CRassert_no_diff <expected> <actual> [message]\fP | 
|  | 155 | +.RE | 
|  | 156 | +.sp | 
|  | 157 | +.RS 4 | 
|  | 158 | +.ie n \{\ | 
|  | 159 | +\h'-04'\(bu\h'+03'\c | 
|  | 160 | +.\} | 
|  | 161 | +.el \{\ | 
|  | 162 | +.  sp -1 | 
|  | 163 | +.  IP \(bu 2.3 | 
|  | 164 | +.\} | 
|  | 165 | +\f(CRskip_if <condition> <pattern>\fP | 
|  | 166 | +.RE | 
|  | 167 | +.sp | 
|  | 168 | +.RS 4 | 
|  | 169 | +.ie n \{\ | 
|  | 170 | +\h'-04'\(bu\h'+03'\c | 
|  | 171 | +.\} | 
|  | 172 | +.el \{\ | 
|  | 173 | +.  sp -1 | 
|  | 174 | +.  IP \(bu 2.3 | 
|  | 175 | +.\} | 
|  | 176 | +\f(CRfake <command> [replacement code]\fP | 
|  | 177 | +.RE | 
|  | 178 | +.sp | 
| 45 | 179 | \fI(by the way, the documentation you are reading is itself tested with bash\-unit)\fP | 
| 46 | 180 | .sp | 
| 47 | 181 | \fBbash_unit\fP is free software you may contribute to. See \c | 
| @@ -84,56 +218,76 @@ quiet mode. | 
| 84 | 218 | Will only output the status of each test with no further | 
| 85 | 219 | information even in case of failure. | 
| 86 | 220 | .RE | 
| 87 |  | -.SS "\c .URL "https://pre\-commit.com" "pre\-commit" hook" | 
|  | 221 | +.SS "GitHub Actions" | 
| 88 | 222 | .sp | 
| 89 |  | -You can run \f(CRbash_unit\fP as a \c | 
| 90 |  | -.URL "https://pre\-commit.com" "pre\-commit" "" | 
| 91 |  | -hook. | 
|  | 223 | +Here is an example of how you could integrate \fBbash_unit\fP with \c | 
|  | 224 | +.URL "https://docs.github.com/fr/actions" "GitHub Actions" ":" | 
| 92 | 225 | .sp | 
| 93 |  | -Add the following to your \c | 
| 94 |  | -.URL "https://pre\-commit.com" "pre\-commit" "" | 
| 95 |  | -configuration. By default it will run scripts that are identified as shell scripts that match the path \f(CR^tests/(.*/)?test_.*\(rs.sh$\fP. | 
|  | 226 | +.if n .RS 4 | 
|  | 227 | +.nf | 
|  | 228 | +.fam C | 
|  | 229 | +name: bash_unit tests | 
|  | 230 | +on: | 
|  | 231 | +  push: | 
|  | 232 | +    branches: [ main ] | 
|  | 233 | +  pull_request: | 
|  | 234 | +    branches: [ main ] | 
|  | 235 | + | 
|  | 236 | +jobs: | 
|  | 237 | +  ubuntu: | 
|  | 238 | +    runs\-on: ubuntu\-latest | 
|  | 239 | +    steps: | 
|  | 240 | +    \- uses: actions/checkout@v4 | 
|  | 241 | +    \- name: Unit testing with bash_unit | 
|  | 242 | +      run: | | 
|  | 243 | +        curl \-s https://raw.githubusercontent.com/pgrange/bash_unit/master/install.sh | bash | 
|  | 244 | +        FORCE_COLOR=true ./bash_unit tests/test_* | 
|  | 245 | +.fam | 
|  | 246 | +.fi | 
|  | 247 | +.if n .RE | 
|  | 248 | +.sp | 
|  | 249 | +See this bash_unit \c | 
|  | 250 | +.URL "https://github.com/pgrange/bash_unit_getting_started" "getting started gitlab project" "" | 
|  | 251 | +for a working example. | 
|  | 252 | +.SS "GitLab CI" | 
|  | 253 | +.sp | 
|  | 254 | +Here is an example of how you could integrate \fBbash_unit\fP with \c | 
|  | 255 | +.URL "https://docs.gitlab.com/ee/ci/" "GitLab CI" ":" | 
| 96 | 256 | .sp | 
| 97 | 257 | .if n .RS 4 | 
| 98 | 258 | .nf | 
| 99 | 259 | .fam C | 
| 100 |  | -repos: | 
| 101 |  | -  \- repo: https://github.com/pgrange/bash_unit | 
| 102 |  | -    rev: v2.2.0 | 
| 103 |  | -    hooks: | 
| 104 |  | -      \- id: bash\-unit | 
| 105 |  | -        always\-run: true | 
|  | 260 | +test: | 
|  | 261 | +  image: debian | 
|  | 262 | +  script: | 
|  | 263 | +    \- apt\-get update | 
|  | 264 | +    \- apt\-get install \-\-no\-install\-recommends \-y curl ca\-certificates | 
|  | 265 | +    \- curl \-s https://raw.githubusercontent.com/pgrange/bash_unit/master/install.sh | bash | 
|  | 266 | +    \- FORCE_COLOR=true ./bash_unit tests/test_* | 
| 106 | 267 | .fam | 
| 107 | 268 | .fi | 
| 108 | 269 | .if n .RE | 
| 109 |  | -.SH "RUNNING \f(CRbash_unit\fP IN THE TEST SCRIPT" | 
| 110 | 270 | .sp | 
| 111 |  | -In some cases you want to run \f(CRbash_unit\fP from inside the test script. | 
|  | 271 | +See this bash_unit \c | 
|  | 272 | +.URL "https://gitlab.com/pgrange/bash_unit_getting_started" "getting started gitlab project" "" | 
|  | 273 | +for a working example. | 
|  | 274 | +.SS "pre\-commit hook" | 
| 112 | 275 | .sp | 
| 113 |  | -One example is this project’s \f(CRtest_doc.sh\fP test script. | 
|  | 276 | +You can run \f(CRbash_unit\fP as a \c | 
|  | 277 | +.URL "https://pre\-commit.com" "pre\-commit" "" | 
|  | 278 | +hook. | 
| 114 | 279 | .sp | 
| 115 |  | -One method to define a \f(CRBASH_UNIT\fP variable is shown below: | 
|  | 280 | +Add the following to your pre\-commit configuration. By default it will run scripts that are identified as shell scripts that match the path \f(CR^tests/(.*/)?test_.*\(rs.sh$\fP. | 
| 116 | 281 | .sp | 
| 117 | 282 | .if n .RS 4 | 
| 118 | 283 | .nf | 
| 119 | 284 | .fam C | 
| 120 |  | -# Function to recursively search upwards for file | 
| 121 |  | -_find_file() { | 
| 122 |  | -    local dir="$1" | 
| 123 |  | -    local file="$2" | 
| 124 |  | -    while [ "${dir}" != "/" ]; do | 
| 125 |  | -        if [ \-f "${dir}/${file}" ]; then | 
| 126 |  | -            echo "${dir}/${file}" | 
| 127 |  | -            return 0 | 
| 128 |  | -        fi | 
| 129 |  | -        dir=$(dirname "${dir}") | 
| 130 |  | -    done | 
| 131 |  | -    return 1 | 
| 132 |  | -} | 
| 133 |  | - | 
| 134 |  | -B_U=$(_find_file "$(dirname "$(realpath "$0")")" bash_unit) | 
| 135 |  | -# shellcheck disable=2089 | 
| 136 |  | -BASH_UNIT="eval FORCE_COLOR=false \(rs"$B_U\(rs"" | 
|  | 285 | +repos: | 
|  | 286 | +  \- repo: https://github.com/pgrange/bash_unit | 
|  | 287 | +    rev: v2.2.0 | 
|  | 288 | +    hooks: | 
|  | 289 | +      \- id: bash\-unit | 
|  | 290 | +        always\-run: true | 
| 137 | 291 | .fam | 
| 138 | 292 | .fi | 
| 139 | 293 | .if n .RE | 
| @@ -318,6 +472,7 @@ ok \- test_fake_exports_faked_in_subshells | 
| 318 | 472 | ok \- test_fake_transmits_params_to_fake_code | 
| 319 | 473 | ok \- test_fake_transmits_params_to_fake_code_as_array | 
| 320 | 474 | ok \- test_should_pretty_format_even_when_LANG_is_unset | 
|  | 475 | +1..30 | 
| 321 | 476 | .fam | 
| 322 | 477 | .fi | 
| 323 | 478 | .if n .RE | 
| @@ -906,20 +1061,20 @@ code() { | 
| 906 | 1061 | 
 | 
| 907 | 1062 | test_code_succeeds_if_apache_runs() { | 
| 908 | 1063 |   fake ps <<EOF | 
| 909 |  | -  PID TTY          TIME CMD | 
| 910 |  | -13525 pts/7    00:00:01 bash | 
| 911 |  | -24162 pts/7    00:00:00 ps | 
| 912 |  | - 8387 ?            0:00 /usr/sbin/apache2 \-k start | 
|  | 1064 | +  PID TTY\&          TIME CMD | 
|  | 1065 | +13525 pts/7\&    00:00:01 bash | 
|  | 1066 | +24162 pts/7\&    00:00:00 ps | 
|  | 1067 | + 8387 ?\&            0:00 /usr/sbin/apache2 \-k start | 
| 913 | 1068 | EOF | 
| 914 | 1069 | 
 | 
| 915 | 1070 |   assert code "code should succeed when apache is running" | 
| 916 | 1071 | } | 
| 917 | 1072 | 
 | 
| 918 | 1073 | test_code_fails_if_apache_does_not_run() { | 
| 919 | 1074 |   fake ps <<EOF | 
| 920 |  | -  PID TTY          TIME CMD | 
| 921 |  | -13525 pts/7    00:00:01 bash | 
| 922 |  | -24162 pts/7    00:00:00 ps | 
|  | 1075 | +  PID TTY\&          TIME CMD | 
|  | 1076 | +13525 pts/7\&    00:00:01 bash | 
|  | 1077 | +24162 pts/7\&    00:00:00 ps | 
| 923 | 1078 | EOF | 
| 924 | 1079 | 
 | 
| 925 | 1080 |   assert_fails code "code should fail when apache is not running" | 
| @@ -1058,10 +1213,10 @@ code() { | 
| 1058 | 1213 | test_code_gives_ps_appropriate_parameters() { | 
| 1059 | 1214 |   _ps() { | 
| 1060 | 1215 |     cat <<EOF | 
| 1061 |  | -  PID TTY          TIME CMD | 
| 1062 |  | -13525 pts/7    00:00:01 bash | 
| 1063 |  | -24162 pts/7    00:00:00 ps | 
| 1064 |  | - 8387 ?            0:00 /usr/sbin/apache2 \-k start | 
|  | 1216 | +  PID TTY\&          TIME CMD | 
|  | 1217 | +13525 pts/7\&    00:00:01 bash | 
|  | 1218 | +24162 pts/7\&    00:00:00 ps | 
|  | 1219 | + 8387 ?\&            0:00 /usr/sbin/apache2 \-k start | 
| 1065 | 1220 | EOF | 
| 1066 | 1221 |     assert_equals ax "${FAKE_PARAMS[@]}" | 
| 1067 | 1222 |   } | 
|  | 
0 commit comments