Merge pull request 'Add better helper functions' (#6) from better-helper-functions into main
Reviewed-on: https://codeberg.org/svenvanheugten/git-check-assertions/pulls/6
This commit is contained in:
commit
a330b66ad0
3 changed files with 155 additions and 9 deletions
38
README.md
38
README.md
|
|
@ -50,6 +50,29 @@ If you use Nix with flakes, you can simply add it to your program's devshell ins
|
|||
)
|
||||
```
|
||||
|
||||
## What do you put in your commit messages?
|
||||
|
||||
Simply add a bash script enclosed in a `git-check-assertions` block to a commit message, e.g.:
|
||||
|
||||
~~~
|
||||
```git-check-assertions
|
||||
dotnet build
|
||||
dotnet test --no-build
|
||||
```
|
||||
~~~
|
||||
|
||||
This script will be run with `set -euo pipefail`, and the commit will be considered correct if the script exits succesfully.
|
||||
|
||||
You can technically assert that a command fails by writing `! ... || exit 1`, or write assertions about a command's output by piping it to `grep`, but doing so won't lead to very useful error messages when things go wrong. To make those things easier, there are some helper functions included, which are inspired by [bats](https://github.com/bats-core/bats-core) and [bats-assert](https://github.com/bats-core/bats-assert):
|
||||
|
||||
* `run <command>`: run a command, capturing its exit status in `status` and combined stdout/stderr in `output`.
|
||||
* `assert_success`: succeed if `run` produced a zero exit status.
|
||||
* `assert_failure`: succeed if `run` produced a non-zero exit status.
|
||||
* `assert_output <string>`: succeed if `output` exactly matches the string.
|
||||
* `assert_output --partial <string>`: succeed if `output` contains the string.
|
||||
|
||||
I'm considering taking `bats-assert` as a dependency, but for now, this very minimal set of functions with a similar interface should get you on your way.
|
||||
|
||||
## Examples of commit messages
|
||||
|
||||
Assert that a commit builds:
|
||||
|
|
@ -65,16 +88,18 @@ Assert that a commit builds and that the tests succeed:
|
|||
~~~
|
||||
```git-check-assertions
|
||||
dotnet build
|
||||
dotnet test --no-build
|
||||
run dotnet test --no-build
|
||||
assert_success
|
||||
```
|
||||
~~~
|
||||
|
||||
Assert that a commit builds, but that the tests do not succeed (`assert_fails` is a helper function included in `git-check-assertions`):
|
||||
Assert that a commit builds, but that the tests do not succeed:
|
||||
|
||||
~~~
|
||||
```git-check-assertions
|
||||
dotnet build
|
||||
assert_fails dotnet test --no-build
|
||||
run dotnet test --no-build
|
||||
assert_failure
|
||||
```
|
||||
~~~
|
||||
|
||||
|
|
@ -83,7 +108,9 @@ Assert that a commit builds, and that the tests fail with exactly the error that
|
|||
~~~
|
||||
```git-check-assertions
|
||||
dotnet build
|
||||
(assert_fails dotnet test --no-build) | grep "Invalid URL"
|
||||
run dotnet test --no-build
|
||||
assert_failure
|
||||
assert_output --partial "Invalid URL"
|
||||
```
|
||||
~~~
|
||||
|
||||
|
|
@ -94,6 +121,7 @@ Assert that a commit builds, and that a specific change breaks the tests (as dis
|
|||
dotnet test
|
||||
sed -i '/crucial code/d' Main.fs
|
||||
dotnet build
|
||||
assert_fails dotnet test --no-build
|
||||
run dotnet test --no-build
|
||||
assert_failure
|
||||
```
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -24,14 +24,45 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
assert_fails() {
|
||||
! "$@" || {
|
||||
# helper functions inspired by bats/bats-assert
|
||||
run() {
|
||||
set +e
|
||||
output="$("$@" 2>&1)"
|
||||
status=$?
|
||||
set -e
|
||||
return 0
|
||||
}
|
||||
assert_success() {
|
||||
if [ "$status" -ne 0 ]; then
|
||||
echo "Expected command to succeed, but it failed."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
assert_failure() {
|
||||
if [ "$status" -eq 0 ]; then
|
||||
echo "Expected command to fail, but it succeeded."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
assert_output() {
|
||||
if [ "${1:-}" = "--partial" ]; then
|
||||
local expected="$2"
|
||||
if [[ "$output" != *"$expected"* ]]; then
|
||||
echo "Expected output to contain: $expected"
|
||||
echo "Actual output: $output"
|
||||
exit 1
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
if [ "$output" != "$1" ]; then
|
||||
echo "Expected output to equal: $1"
|
||||
echo "Actual output: $output"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
export -f assert_fails
|
||||
export -f run assert_success assert_failure assert_output
|
||||
|
||||
# main flow
|
||||
orig_ref="$(git symbolic-ref --quiet --short HEAD || git rev-parse HEAD)"
|
||||
base="$(git merge-base main HEAD)"
|
||||
mapfile -t commits < <(git rev-list --reverse "${base}..HEAD")
|
||||
|
|
|
|||
|
|
@ -112,3 +112,90 @@ commit_with_assertion() {
|
|||
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "assert_success should succeed if the executed command succeeded" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run exit 0\nassert_success'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "assert_success should fail if the executed command failed" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run exit 1\nassert_success'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_failure
|
||||
assert_output --partial "Expected command to succeed, but it failed."
|
||||
}
|
||||
|
||||
@test "assert_failure should succeed if the executed command failed" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run exit 1\nassert_failure'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "assert_failure should fail if the executed command succeeded" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run exit 0\nassert_failure'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_failure
|
||||
assert_output --partial "Expected command to fail, but it succeeded."
|
||||
}
|
||||
|
||||
@test "assert_output should succeed if the output matches the given string" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run echo hello\nassert_output hello'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "assert_output should fail if the output does not match the given string" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run echo hello\nassert_output goodbye'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_failure
|
||||
assert_output --partial "Expected output to equal: goodbye"
|
||||
assert_output --partial "Actual output: hello"
|
||||
}
|
||||
|
||||
@test "assert_output should also check stderr output" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run sh -c "echo err 1>&2"\nassert_output err'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "assert_output --partial should succeed if output contains the given string" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run echo hello\nassert_output --partial ell'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "assert_output --partial should fail if output does not contain the given string" {
|
||||
git checkout -b feature
|
||||
commit_with_assertion $'run echo hello\nassert_output --partial xyz'
|
||||
|
||||
run git-check-assertions
|
||||
|
||||
assert_failure
|
||||
assert_output --partial "Expected output to contain: xyz"
|
||||
assert_output --partial "Actual output: hello"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue