Skip to content

Commit

Permalink
Merge pull request #3 from keithy/master
Browse files Browse the repository at this point in the history
Some improvements
  • Loading branch information
holmesjr authored Aug 18, 2019
2 parents 90324c9 + e57b916 commit ad72e1e
Show file tree
Hide file tree
Showing 13 changed files with 1,299 additions and 24 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: bash

script:
- make -C tests
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE.md)
[![Build Status](https://travis-ci.com/keithy/bash-spec-2.svg?branch=master)](https://travis-ci.com/keithy/bash-spec-2)
[![GitHub issues](https://img.shields.io/github/issues/keithy/bash-spec-2.svg)](https://github.com/keithy/bash-spec-2/issues)
[![Latest Version](https://img.shields.io/github/release/keithy/bash-spec-2.svg)](https://github.com/keithy/bash-spec-2/releases)

New for 2.1
===========
#### Supporting other coding styles/formats
```
old format: describe "title" "$( ... )"
alt format: describe "title" && { ... } (most readable but variables are not locally scoped)
alt format2: describe "title" && ( ... ) (compromise?)
```
#### Assertions on expressions
```
[[ some_expression ]]
should_succeed
[[ some_expression ]]
should_fail
```
#### Cleaner support for arrays and vars - pass by reference

```
expect_var varname to_be 5
expect_array arrayname to_contain 5
```

#### Unofficial bash strict mode

http://redsymbol.net/articles/unofficial-bash-strict-mode/

#### Travis-CI

bash-spec
=========

Expand Down Expand Up @@ -65,7 +98,8 @@ When converted to lowercase

### Matchers

Most of the matchers from the original bash-spec survived. The to_be_installed matcher went away, because it didn't work and wasn't super useful. It can be resurrected if someone cares enough.
Most of the matchers from the original bash-spec survived. The to_be_installed matcher went away,
because it didn't work and wasn't super useful. It can be resurrected if someone cares enough.

The available matchers are:

Expand All @@ -80,7 +114,10 @@ Each matcher has a negated mode (`not to_be`, `not to_match` etc)

### Blocks and the notably absent "before" syntax

You'll have noticed that the command substitution syntax is used. This provides something similar to independent blocks, since each "$( )" spawns a subshell that doesn't affect other subshells or the parent shell. Each subshell also gets a copy of the environment in the parent shell, making a "before" syntax unnecessary.
You'll have noticed that the command substitution syntax is used.
This provides something similar to independent blocks, since each "$( )" spawns a subshell that doesn't
affect other subshells or the parent shell. Each subshell also gets a copy of the environment in the parent shell,
making a "before" syntax unnecessary.

The [bash-spec test suite](https://github.com/realestate-com-au/bash-spec-2/blob/master/test_bash-spec.sh) has some good examples of this.

Expand All @@ -92,3 +129,4 @@ bash-spec-2 works hand in hand with [stub.sh](https://github.com/jimeh/stub.sh)

- An equivalent for let blocks (memoized, lazy evaluated) might be useful
- Proper nesting of the output would be cool

98 changes: 98 additions & 0 deletions bash-spec-baby.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
#==================================================================================
## Minimal testing framework for bash scripts.
## usage:
##
## [[ some_expression ]]
## should_succeed
## [[ some_expression ]]
## should_fail
##
## bash-spec Author: Dave Nicolette
## Date: 29 Jul 2014
## Modified by REA Group 2014
## bash-spec-baby by keithy@consultant.com 03/2019
#==================================================================================

# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -uo pipefail
IFS=$'\n\t'
shopt -s nullglob # make sure globs are empty arrays if nothing is found

result_file=$(mktemp)

_passed_=0
_failed_=0

exec 6<&1
exec > "$result_file"

function show_help {
exec 1>&6 6>&-
rm -f -- "$result_file"
grep "^##" $BASH_SOURCE | sed 's/^##//'
}

function output_results {
exec 1>&6 6>&-
local results="$(<$result_file)"
rm -f -- "$result_file"
local passes=$(printf '%s' "$results" | grep -F PASS | wc -l)
local fails=$(printf '%s' "$results" | grep -F '**** FAIL' | wc -l )
printf '%s\n--SUMMARY\n%d PASSED\n%d FAILED\n' "$results" "$passes" "$fails"
[[ ${fails:-1} -eq 0 ]]
exit $?
}

function pass {
echo " PASS"
}

function fail {
echo "**** FAIL - expected:$( if [[ "$_negation_" == true ]]; then echo ' NOT'; fi; ) '$_expected_' | actual: '${_actual_[@]}'"
}

function should_succeed {
_actual_=$?
_expected_=0
_negation_=false
_pass_=false
[[ $_actual_ == $_expected_ ]] && _pass_=true
_expected_="0(success)"
_actual_="$_actual_(failed)"
_negation_check_
}

function should_fail {
_actual_=$?
_expected_=0
_negation_=false
_pass_=true
[[ $_actual_ == $_expected_ ]] && _pass_=false
_expected_="NOT 0(fail)"
_actual_="0(succeeded)"
_negation_check_
}

# pattern - user supplied return variable name
function capture {
mapfile -t "${!#}" < "$1"
}

#kph asks why?
TEMP="$(getopt -o h --long help \
-n 'javawrap' -- $@)"

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

eval set -- "$TEMP"

while true; do
case "$1" in
h | help ) show_help; exit 0 ;;
-- ) shift ;;
* ) shift; break ;;
esac
done

trap output_results EXIT
114 changes: 95 additions & 19 deletions bash-spec.sh
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
#!/bin/bash
#==================================================================================
# BDD-style testing framework for bash scripts.
#
# expect variable [not] to_be value Compare scalar values for equality
# expect variable [not] to_match regex Regex match
# expect array [not] to_contain value Look for a value in an array
# expect filename [not] to_exist Verify file existence
# expect filename [not] to_have_mode modestring Verify file mode (permissions)
# expect [not] to_be_true condition Verify exit mode as boolean
#
#!/usr/bin/env bash
##==================================================================================
## BDD-style testing framework for bash scripts.
##
## expect variable [not] to_be value Compare scalar values for equality
## expect variable [not] to_match regex Regex match
## expect array [not] to_contain value Look for a value in an array
## expect_array arrayname [not] to_contain value Look for a value in an array (by ref)
## expect_var variablename [not] to_contain value Look for a value in a variable (by ref)
## expect filename [not] to_exist Verify file existence
## expect filename [not] to_have_mode modestring Verify file mode (permissions)
## expect [not] to_be_true condition Verify exit mode as boolean
## [[ some_expression ]]
## should_succeed
## [[ some_expression ]]
## should_fail
##
# Original Author: Dave Nicolette
# Version 1.0.0 29 Jul 2014
# Release
# Author: Dave Nicolette
# Date: 29 Jul 2014
# License: MIT
# (GPL3 licence added to bash-spec after the bash-spec-2 fork)
# Modified by REA Group 2014
# License: MIT
# Modified by keithy@consultant.com 03/2019
# License: MIT
#==================================================================================

# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -uo pipefail
IFS=$'\n\t'
shopt -s nullglob # make sure globs are empty arrays if nothing is found

result_file=$(mktemp)

# XXX: should use mktemp for proper random file name -- (GM)
result_file="$RANDOM"
_passed_=0
_failed_=0

exec 6<&1
exec > "$result_file"

function show_help {
exec 1>&6 6>&-
rm -f -- "$result_file"
grep "^##" $BASH_SOURCE | sed 's/^##//'
}

function output_results {
exec 1>&6 6>&-
local results="$(<$result_file)"
Expand Down Expand Up @@ -58,15 +82,18 @@ function _negation_check_ {
}

function it {
printf ' %s\n %s\n' "$1" "$2"
echo " $1"
[ -z ${2+x} ] || echo " $2"
}

function describe {
printf '%s\n%s\n' "$1" "$2"
echo "$1"
[ -z ${2+x} ] || echo "$2"
}

function context {
printf '%s\n%s\n' "$1" "$2"
echo "$1"
[ -z ${2+x} ] || echo "$2"
}

function pass {
Expand All @@ -77,9 +104,32 @@ function fail {
echo "**** FAIL - expected:$( if [[ "$_negation_" == true ]]; then echo ' NOT'; fi; ) '$_expected_' | actual: '${_actual_[@]}'"
}

function should_succeed {
_actual_=$?
_expected_=0
_negation_=false
_pass_=false
[[ $_actual_ == $_expected_ ]] && _pass_=true
_expected_="0(success)"
_actual_="$_actual_(failed)"
_negation_check_
}

function should_fail {
_actual_=$?
_expected_=0
_negation_=false
_pass_=true
[[ $_actual_ == $_expected_ ]] && _pass_=false
_expected_="NOT 0(fail)"
_actual_="0(succeeded)"
_negation_check_
}

function expect {
_expected_=
_negation_=false
_pass_=false
declare -a _actual_
until [[ "${1:0:3}" == to_ || "$1" == not || -z "$1" ]]; do
_actual_+=("$1")
Expand All @@ -88,6 +138,26 @@ function expect {
"$@"
}

function expect_var {
_expected_=
_negation_=false
declare -n _actual_=$1
until [[ "${1:0:3}" == to_ || "$1" == not || -z "$1" ]]; do
shift
done
"$@"
}

function expect_array {
_expected_=
_negation_=false
declare -n _actual_=$1
until [[ "${1:0:3}" == to_ || "$1" == not || -z "$1" ]]; do
shift
done
"$@"
}

function not {
_negation_=true
"$@"
Expand Down Expand Up @@ -160,6 +230,12 @@ function to_have_mode {
_negation_check_
}

# pattern - user supplied return variable name
function capture {
mapfile -t "${!#}" < "$1"
}

#kph asks why?
TEMP="$(getopt -o h --long help \
-n 'javawrap' -- $@)"

Expand All @@ -169,8 +245,8 @@ eval set -- "$TEMP"

while true; do
case "$1" in
-h | --help ) show_help; exit 0 ;;
-- ) shift; break ;;
h | help ) show_help; exit 0 ;;
-- ) break ;;
* ) break ;;
esac
done
Expand Down
5 changes: 5 additions & 0 deletions tests/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
TESTS ?= $(wildcard *.sh)

include Makefile.test


Loading

0 comments on commit ad72e1e

Please sign in to comment.