From 9fa0589bbcf2d7647ffc2b8bd3c8916347a4fb07 Mon Sep 17 00:00:00 2001 From: n0vember Date: Thu, 14 Oct 2021 00:50:51 +0200 Subject: [PATCH 1/3] add new assert_no_diff assertion directive a regular action when testing scripts is to test generated files to match a valid content. This is often done using assert with the following line: assert "diff 'path/to/exepected file' 'path/to/generated file'" newly assertion tool assert_no_diff makes intention clearer by using the following syntax: assert_no_diff "path/to/expected file" "path/to/generated file" goal is to make clearer the facts that: - what is expected is that there is no difference - what is compared are two files --- README.adoc | 141 +++++++++++++++++++++++++++------------------ bash_unit | 10 ++++ tests/test_core.sh | 12 ++++ 3 files changed, 108 insertions(+), 55 deletions(-) diff --git a/README.adoc b/README.adoc index c6270ff..94bf86f 100644 --- a/README.adoc +++ b/README.adoc @@ -88,27 +88,30 @@ To run tests, simply call *bash_unit* with all your tests files as parameter. Fo ```output Running tests in tests/test_core.sh - Running test_assert_equals_fails_when_not_equal ... SUCCESS - Running test_assert_equals_succeed_when_equal ... SUCCESS - Running test_assert_fails ... SUCCESS - Running test_assert_fails_fails ... SUCCESS - Running test_assert_fails_succeeds ... SUCCESS - Running test_assert_not_equals_fails_when_equal ... SUCCESS - Running test_assert_not_equals_succeeds_when_not_equal ... SUCCESS - Running test_assert_shows_stderr_on_failure ... SUCCESS - Running test_assert_shows_stdout_on_failure ... SUCCESS - Running test_assert_status_code_fails ... SUCCESS - Running test_assert_status_code_succeeds ... SUCCESS - Running test_assert_succeeds ... SUCCESS - Running test_fail_fails ... SUCCESS - Running test_fail_prints_failure_message ... SUCCESS - Running test_fail_prints_where_is_error ... SUCCESS - Running test_fake_actually_fakes_the_command ... SUCCESS - Running test_fake_can_fake_inline ... SUCCESS - Running test_fake_echo_stdin_when_no_params ... SUCCESS - Running test_fake_exports_faked_in_subshells ... SUCCESS - Running test_fake_transmits_params_to_fake_code ... SUCCESS -Overall result: SUCCESS + Running test_assert_equals_fails_when_not_equal ... SUCCESS ✓ + Running test_assert_equals_succeed_when_equal ... SUCCESS ✓ + Running test_assert_fails ... SUCCESS ✓ + Running test_assert_fails_fails ... SUCCESS ✓ + Running test_assert_fails_succeeds ... SUCCESS ✓ + Running test_assert_no_diff_fails_when_diff ... SUCCESS ✓ + Running test_assert_no_diff_succeeds_when_no_diff ... SUCCESS ✓ + Running test_assert_not_equals_fails_when_equal ... SUCCESS ✓ + Running test_assert_not_equals_succeeds_when_not_equal ... SUCCESS ✓ + Running test_assert_shows_stderr_on_failure ... SUCCESS ✓ + Running test_assert_shows_stdout_on_failure ... SUCCESS ✓ + Running test_assert_status_code_fails ... SUCCESS ✓ + Running test_assert_status_code_succeeds ... SUCCESS ✓ + Running test_assert_succeeds ... SUCCESS ✓ + Running test_bash_unit_changes_cwd_to_current_test_file_directory ... SUCCESS ✓ + Running test_fail_fails ... SUCCESS ✓ + Running test_fail_prints_failure_message ... SUCCESS ✓ + Running test_fail_prints_where_is_error ... SUCCESS ✓ + Running test_fake_actually_fakes_the_command ... SUCCESS ✓ + Running test_fake_can_fake_inline ... SUCCESS ✓ + Running test_fake_echo_stdin_when_no_params ... SUCCESS ✓ + Running test_fake_exports_faked_in_subshells ... SUCCESS ✓ + Running test_fake_transmits_params_to_fake_code ... SUCCESS ✓ +Overall result: SUCCESS ✓ ``` You might also want to run only specific tests, you may do so with the @@ -121,20 +124,22 @@ functions against this pattern. ```output Running tests in tests/test_core.sh - Running test_assert_equals_fails_when_not_equal ... SUCCESS - Running test_assert_equals_succeed_when_equal ... SUCCESS - Running test_assert_fails ... SUCCESS - Running test_assert_fails_fails ... SUCCESS - Running test_assert_fails_succeeds ... SUCCESS - Running test_assert_not_equals_fails_when_equal ... SUCCESS - Running test_assert_not_equals_succeeds_when_not_equal ... SUCCESS - Running test_assert_shows_stderr_on_failure ... SUCCESS - Running test_assert_shows_stdout_on_failure ... SUCCESS - Running test_assert_status_code_fails ... SUCCESS - Running test_assert_status_code_succeeds ... SUCCESS - Running test_assert_succeeds ... SUCCESS - Running test_fail_fails ... SUCCESS -Overall result: SUCCESS + Running test_assert_equals_fails_when_not_equal ... SUCCESS ✓ + Running test_assert_equals_succeed_when_equal ... SUCCESS ✓ + Running test_assert_fails ... SUCCESS ✓ + Running test_assert_fails_fails ... SUCCESS ✓ + Running test_assert_fails_succeeds ... SUCCESS ✓ + Running test_assert_no_diff_fails_when_diff ... SUCCESS ✓ + Running test_assert_no_diff_succeeds_when_no_diff ... SUCCESS ✓ + Running test_assert_not_equals_fails_when_equal ... SUCCESS ✓ + Running test_assert_not_equals_succeeds_when_not_equal ... SUCCESS ✓ + Running test_assert_shows_stderr_on_failure ... SUCCESS ✓ + Running test_assert_shows_stdout_on_failure ... SUCCESS ✓ + Running test_assert_status_code_fails ... SUCCESS ✓ + Running test_assert_status_code_succeeds ... SUCCESS ✓ + Running test_assert_succeeds ... SUCCESS ✓ + Running test_fail_fails ... SUCCESS ✓ +Overall result: SUCCESS ✓ ``` *bash_unit* supports the http://testanything.org/[Test Anything Protocol] so you can ask for a tap formatted @@ -146,26 +151,29 @@ output with the _-f_ option. ```output # Running tests in tests/test_core.sh -ok - test_assert_equals_fails_when_not_equal -ok - test_assert_equals_succeed_when_equal -ok - test_assert_fails -ok - test_assert_fails_fails -ok - test_assert_fails_succeeds -ok - test_assert_not_equals_fails_when_equal -ok - test_assert_not_equals_succeeds_when_not_equal -ok - test_assert_shows_stderr_on_failure -ok - test_assert_shows_stdout_on_failure -ok - test_assert_status_code_fails -ok - test_assert_status_code_succeeds -ok - test_assert_succeeds -ok - test_fail_fails -ok - test_fail_prints_failure_message -ok - test_fail_prints_where_is_error -ok - test_fake_actually_fakes_the_command -ok - test_fake_can_fake_inline -ok - test_fake_echo_stdin_when_no_params -ok - test_fake_exports_faked_in_subshells -ok - test_fake_transmits_params_to_fake_code +ok ✓ test_assert_equals_fails_when_not_equal +ok ✓ test_assert_equals_succeed_when_equal +ok ✓ test_assert_fails +ok ✓ test_assert_fails_fails +ok ✓ test_assert_fails_succeeds +ok ✓ test_assert_no_diff_fails_when_diff +ok ✓ test_assert_no_diff_succeeds_when_no_diff +ok ✓ test_assert_not_equals_fails_when_equal +ok ✓ test_assert_not_equals_succeeds_when_not_equal +ok ✓ test_assert_shows_stderr_on_failure +ok ✓ test_assert_shows_stdout_on_failure +ok ✓ test_assert_status_code_fails +ok ✓ test_assert_status_code_succeeds +ok ✓ test_assert_succeeds +ok ✓ test_bash_unit_changes_cwd_to_current_test_file_directory +ok ✓ test_fail_fails +ok ✓ test_fail_prints_failure_message +ok ✓ test_fail_prints_where_is_error +ok ✓ test_fake_actually_fakes_the_command +ok ✓ test_fake_can_fake_inline +ok ✓ test_fake_echo_stdin_when_no_params +ok ✓ test_fake_exports_faked_in_subshells +ok ✓ test_fake_transmits_params_to_fake_code ``` == How to write tests @@ -403,6 +411,29 @@ doc:2:test_obvious_equality_with_assert_not_equals() Running test_obvious_inequality_with_assert_not_equals ... SUCCESS ``` +=== *assert_no_diff* + + assert_no_diff [message] + +Assert for equality of content between the two files _expected_ and _actual_. + +```test +test_obvious_diff_with_assert_no_diff(){ + assert_no_diff <(echo foo) <(echo bar) "dynamic files should have no difference" +} +test_obvious_equality_with_assert_no_diff(){ + assert_no_diff "$0" "$0" +} +``` + +```output + Running test_obvious_diff_with_assert_no_diff ... FAILURE ✗ +dynamic files should have no difference + expected '/dev/fd/62' to be identical to '/dev/fd/63' but was different +doc:2:test_obvious_diff_with_assert_no_diff() + Running test_obvious_equality_with_assert_no_diff ... SUCCESS ✓ +``` + == *fake* function fake [replacement code] diff --git a/bash_unit b/bash_unit index 99d0b07..5249131 100755 --- a/bash_unit +++ b/bash_unit @@ -121,6 +121,16 @@ assert_not_equals() { fail "$message expected different value than [$unexpected] but was the same" } +assert_no_diff() { + local expected=$1 + local actual=$2 + local message=${3:-} + [[ -z $message ]] || message="$message\n" + + diff "${expected}" "${actual}" >/dev/null || \ + fail "$message expected '${actual}' to be identical to '${expected}' but was different" +} + fake() { local command=$1 shift diff --git a/tests/test_core.sh b/tests/test_core.sh index 70700fc..33abd03 100644 --- a/tests/test_core.sh +++ b/tests/test_core.sh @@ -57,6 +57,18 @@ test_assert_not_equals_succeeds_when_not_equal() { 'assert_not_equals should succeed' } +test_assert_no_diff_succeeds_when_no_diff() { + assert \ + "assert_no_diff <(echo foo) <(echo foo)" \ + "assert_no_diff should succeed" +} + +test_assert_no_diff_fails_when_diff() { + assert_fails \ + "assert_no_diff <(echo foo) <(echo bar)" \ + "assert_no_diff should fail" +} + test_fail_prints_failure_message() { message=$(with_bash_unit_log fail 'failure message' | line 2) From ee67fec9991df43a5fc2e7051161676479e6d9d9 Mon Sep 17 00:00:00 2001 From: n0vember Date: Thu, 14 Oct 2021 00:54:00 +0200 Subject: [PATCH 2/3] fix release script env usage in shebang line was not compatible with env as provided by coreutils 9.0. If arguments are to be passed to the command given to env, -S option is to be used. --- release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release b/release index a712f66..bc7a8cb 100755 --- a/release +++ b/release @@ -1,4 +1,4 @@ -#!/usr/bin/env bash -e +#!/usr/bin/env -S bash -e token_file=token From 45747a803a290682f76bfdeb788aa01a812d6bad Mon Sep 17 00:00:00 2001 From: n0vember Date: Thu, 14 Oct 2021 00:55:20 +0200 Subject: [PATCH 3/3] prepare release v1.8.0 --- bash_unit | 2 +- docs/man/man1/bash_unit.1 | 184 ++++++++++++++++++++++++-------------- 2 files changed, 120 insertions(+), 66 deletions(-) diff --git a/bash_unit b/bash_unit index 5249131..559bdd5 100755 --- a/bash_unit +++ b/bash_unit @@ -16,7 +16,7 @@ # # https://github.com/pgrange/bash_unit -VERSION=v1.7.2 +VERSION=v1.8.0 ESCAPE=$(printf "\033") NOCOLOR="${ESCAPE}[0m" diff --git a/docs/man/man1/bash_unit.1 b/docs/man/man1/bash_unit.1 index 8447a2a..17be695 100644 --- a/docs/man/man1/bash_unit.1 +++ b/docs/man/man1/bash_unit.1 @@ -1,13 +1,13 @@ '\" t .\" Title: bash_unit .\" Author: [see the "AUTHOR(S)" section] -.\" Generator: Asciidoctor 2.0.13 -.\" Date: 2021-06-01 +.\" Generator: Asciidoctor 2.0.16 +.\" Date: 2021-10-14 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "BASH_UNIT" "1" "2021-06-01" "\ \&" "\ \&" +.TH "BASH_UNIT" "1" "2021-10-14" "\ \&" "\ \&" .ie \n(.g .ds Aq \(aq .el .ds Aq ' .ss \n[.ss] 0 @@ -31,7 +31,7 @@ bash_unit \- bash unit testing enterprise edition framework for professionals! .SH "SYNOPSIS" .sp -\fBbash_unit\fP [\-f tap] [\-p ] [test_file] +\fBbash_unit\fP [\-f tap] [\-p ] [\-r] [test_file] .SH "DESCRIPTION" .sp \fBbash_unit\fP allows you to write unit tests (functions starting with \fBtest\fP), @@ -55,6 +55,14 @@ You can specify several patterns by repeating this option for each pattern. .RE .sp +\fB\-r\fP +.RS 4 +executes test cases in random order. +Only affects the order within a test file (files are always +executed in the order in which they are specified on the +command line). +.RE +.sp \fB\-f\fP \fIoutput_format\fP .RS 4 specify an alternative output format. @@ -76,26 +84,30 @@ To run tests, simply call \fBbash_unit\fP with all your tests files as parameter .nf .fam C Running tests in tests/test_core.sh - Running test_assert_equals_fails_when_not_equal ... SUCCESS - Running test_assert_equals_succeed_when_equal ... SUCCESS - Running test_assert_fails ... SUCCESS - Running test_assert_fails_fails ... SUCCESS - Running test_assert_fails_succeeds ... SUCCESS - Running test_assert_not_equals_fails_when_equal ... SUCCESS - Running test_assert_not_equals_succeeds_when_not_equal ... SUCCESS - Running test_assert_shows_stderr_on_failure ... SUCCESS - Running test_assert_shows_stdout_on_failure ... SUCCESS - Running test_assert_status_code_fails ... SUCCESS - Running test_assert_status_code_succeeds ... SUCCESS - Running test_assert_succeeds ... SUCCESS - Running test_fail_fails ... SUCCESS - Running test_fail_prints_failure_message ... SUCCESS - Running test_fail_prints_where_is_error ... SUCCESS - Running test_fake_actually_fakes_the_command ... SUCCESS - Running test_fake_can_fake_inline ... SUCCESS - Running test_fake_echo_stdin_when_no_params ... SUCCESS - Running test_fake_exports_faked_in_subshells ... SUCCESS - Running test_fake_transmits_params_to_fake_code ... SUCCESS + Running test_assert_equals_fails_when_not_equal ... SUCCESS ✓ + Running test_assert_equals_succeed_when_equal ... SUCCESS ✓ + Running test_assert_fails ... SUCCESS ✓ + Running test_assert_fails_fails ... SUCCESS ✓ + Running test_assert_fails_succeeds ... SUCCESS ✓ + Running test_assert_no_diff_fails_when_diff ... SUCCESS ✓ + Running test_assert_no_diff_succeeds_when_no_diff ... SUCCESS ✓ + Running test_assert_not_equals_fails_when_equal ... SUCCESS ✓ + Running test_assert_not_equals_succeeds_when_not_equal ... SUCCESS ✓ + Running test_assert_shows_stderr_on_failure ... SUCCESS ✓ + Running test_assert_shows_stdout_on_failure ... SUCCESS ✓ + Running test_assert_status_code_fails ... SUCCESS ✓ + Running test_assert_status_code_succeeds ... SUCCESS ✓ + Running test_assert_succeeds ... SUCCESS ✓ + Running test_bash_unit_changes_cwd_to_current_test_file_directory ... SUCCESS ✓ + Running test_fail_fails ... SUCCESS ✓ + Running test_fail_prints_failure_message ... SUCCESS ✓ + Running test_fail_prints_where_is_error ... SUCCESS ✓ + Running test_fake_actually_fakes_the_command ... SUCCESS ✓ + Running test_fake_can_fake_inline ... SUCCESS ✓ + Running test_fake_echo_stdin_when_no_params ... SUCCESS ✓ + Running test_fake_exports_faked_in_subshells ... SUCCESS ✓ + Running test_fake_transmits_params_to_fake_code ... SUCCESS ✓ +Overall result: SUCCESS ✓ .fam .fi .if n .RE @@ -116,19 +128,22 @@ functions against this pattern. .nf .fam C Running tests in tests/test_core.sh - Running test_assert_equals_fails_when_not_equal ... SUCCESS - Running test_assert_equals_succeed_when_equal ... SUCCESS - Running test_assert_fails ... SUCCESS - Running test_assert_fails_fails ... SUCCESS - Running test_assert_fails_succeeds ... SUCCESS - Running test_assert_not_equals_fails_when_equal ... SUCCESS - Running test_assert_not_equals_succeeds_when_not_equal ... SUCCESS - Running test_assert_shows_stderr_on_failure ... SUCCESS - Running test_assert_shows_stdout_on_failure ... SUCCESS - Running test_assert_status_code_fails ... SUCCESS - Running test_assert_status_code_succeeds ... SUCCESS - Running test_assert_succeeds ... SUCCESS - Running test_fail_fails ... SUCCESS + Running test_assert_equals_fails_when_not_equal ... SUCCESS ✓ + Running test_assert_equals_succeed_when_equal ... SUCCESS ✓ + Running test_assert_fails ... SUCCESS ✓ + Running test_assert_fails_fails ... SUCCESS ✓ + Running test_assert_fails_succeeds ... SUCCESS ✓ + Running test_assert_no_diff_fails_when_diff ... SUCCESS ✓ + Running test_assert_no_diff_succeeds_when_no_diff ... SUCCESS ✓ + Running test_assert_not_equals_fails_when_equal ... SUCCESS ✓ + Running test_assert_not_equals_succeeds_when_not_equal ... SUCCESS ✓ + Running test_assert_shows_stderr_on_failure ... SUCCESS ✓ + Running test_assert_shows_stdout_on_failure ... SUCCESS ✓ + Running test_assert_status_code_fails ... SUCCESS ✓ + Running test_assert_status_code_succeeds ... SUCCESS ✓ + Running test_assert_succeeds ... SUCCESS ✓ + Running test_fail_fails ... SUCCESS ✓ +Overall result: SUCCESS ✓ .fam .fi .if n .RE @@ -150,26 +165,29 @@ output with the \fI\-f\fP option. .nf .fam C # Running tests in tests/test_core.sh -ok \- test_assert_equals_fails_when_not_equal -ok \- test_assert_equals_succeed_when_equal -ok \- test_assert_fails -ok \- test_assert_fails_fails -ok \- test_assert_fails_succeeds -ok \- test_assert_not_equals_fails_when_equal -ok \- test_assert_not_equals_succeeds_when_not_equal -ok \- test_assert_shows_stderr_on_failure -ok \- test_assert_shows_stdout_on_failure -ok \- test_assert_status_code_fails -ok \- test_assert_status_code_succeeds -ok \- test_assert_succeeds -ok \- test_fail_fails -ok \- test_fail_prints_failure_message -ok \- test_fail_prints_where_is_error -ok \- test_fake_actually_fakes_the_command -ok \- test_fake_can_fake_inline -ok \- test_fake_echo_stdin_when_no_params -ok \- test_fake_exports_faked_in_subshells -ok \- test_fake_transmits_params_to_fake_code +ok ✓ test_assert_equals_fails_when_not_equal +ok ✓ test_assert_equals_succeed_when_equal +ok ✓ test_assert_fails +ok ✓ test_assert_fails_fails +ok ✓ test_assert_fails_succeeds +ok ✓ test_assert_no_diff_fails_when_diff +ok ✓ test_assert_no_diff_succeeds_when_no_diff +ok ✓ test_assert_not_equals_fails_when_equal +ok ✓ test_assert_not_equals_succeeds_when_not_equal +ok ✓ test_assert_shows_stderr_on_failure +ok ✓ test_assert_shows_stdout_on_failure +ok ✓ test_assert_status_code_fails +ok ✓ test_assert_status_code_succeeds +ok ✓ test_assert_succeeds +ok ✓ test_bash_unit_changes_cwd_to_current_test_file_directory +ok ✓ test_fail_fails +ok ✓ test_fail_prints_failure_message +ok ✓ test_fail_prints_where_is_error +ok ✓ test_fake_actually_fakes_the_command +ok ✓ test_fake_can_fake_inline +ok ✓ test_fake_echo_stdin_when_no_params +ok ✓ test_fake_exports_faked_in_subshells +ok ✓ test_fake_transmits_params_to_fake_code .fam .fi .if n .RE @@ -316,13 +334,13 @@ It may also be fun to use assert to check for the expected content of a file. .nf .fam C code() { - echo \(aqnot so cool\(aq > /tmp/the_file + echo \*(Aqnot so cool\*(Aq > /tmp/the_file } test_code_write_appropriate_content_in_the_file() { code - assert "diff <(echo \(aqthis is cool\(aq) /tmp/the_file" + assert "diff <(echo \*(Aqthis is cool\*(Aq) /tmp/the_file" } .fam .fi @@ -360,19 +378,19 @@ If the evaluated expression does not fail, then \fBassert_fail\fP will fail and .nf .fam C code() { - echo \(aqnot so cool\(aq > /tmp/the_file + echo \*(Aqnot so cool\*(Aq > /tmp/the_file } test_code_does_not_write_cool_in_the_file() { code - assert_fails "grep cool /tmp/the_file" "should not write \(aqcool\(aq in /tmp/the_file" + assert_fails "grep cool /tmp/the_file" "should not write \*(Aqcool\*(Aq in /tmp/the_file" } test_code_does_not_write_this_in_the_file() { code - assert_fails "grep this /tmp/the_file" "should not write \(aqthis\(aq in /tmp/the_file" + assert_fails "grep this /tmp/the_file" "should not write \*(Aqthis\*(Aq in /tmp/the_file" } .fam .fi @@ -382,7 +400,7 @@ test_code_does_not_write_this_in_the_file() { .nf .fam C Running test_code_does_not_write_cool_in_the_file ... FAILURE -should not write \(aqcool\(aq in /tmp/the_file +should not write \*(Aqcool\*(Aq in /tmp/the_file out> not so cool doc:8:test_code_does_not_write_cool_in_the_file() Running test_code_does_not_write_this_in_the_file ... SUCCESS @@ -500,6 +518,42 @@ doc:2:test_obvious_equality_with_assert_not_equals() .fam .fi .if n .RE +.SS "\fBassert_no_diff\fP" +.sp +.if n .RS 4 +.nf +.fam C +assert_no_diff [message] +.fam +.fi +.if n .RE +.sp +Assert for equality of content between the two files \fIexpected\fP and \fIactual\fP. +.sp +.if n .RS 4 +.nf +.fam C +test_obvious_diff_with_assert_no_diff(){ + assert_no_diff <(echo foo) <(echo bar) "dynamic files should have no difference" +} +test_obvious_equality_with_assert_no_diff(){ + assert_no_diff "$0" "$0" +} +.fam +.fi +.if n .RE +.sp +.if n .RS 4 +.nf +.fam C + Running test_obvious_diff_with_assert_no_diff ... FAILURE ✗ +dynamic files should have no difference + expected \*(Aq/dev/fd/62\*(Aq to be identical to \*(Aq/dev/fd/63\*(Aq but was different +doc:2:test_obvious_diff_with_assert_no_diff() + Running test_obvious_equality_with_assert_no_diff ... SUCCESS ✓ +.fam +.fi +.if n .RE .SH "\fBFAKE\fP FUNCTION" .sp .if n .RS 4 @@ -849,7 +903,7 @@ code() { } test_code_gives_ps_appropriate_parameters() { - fake ps \(aqecho $FAKE_PARAMS >/tmp/fake_params\(aq + fake ps \*(Aqecho $FAKE_PARAMS >/tmp/fake_params\*(Aq code || true @@ -886,7 +940,7 @@ test_get_data_from_fake() { #Fasten you seat belt ... coproc cat exec {test_channel}>&${COPROC[1]} - fake ps \(aqecho $FAKE_PARAMS >&$test_channel\(aq + fake ps \*(Aqecho $FAKE_PARAMS >&$test_channel\*(Aq code || true