From 6959d91535d5b6bafd60c7eb6b50c3b3c31334f4 Mon Sep 17 00:00:00 2001 From: Artur Gajowy Date: Thu, 5 Jan 2017 03:02:47 +0100 Subject: [PATCH] Add support for `.bats.sh` convention tests --- README.md | 28 +++++++++++++++++-- libexec/bats | 3 ++ libexec/bats-preprocess | 6 ++-- test/bats.bats | 12 ++++++++ .../bats/bash_tests/bash_test.bats.sh | 3 ++ 5 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/bats/bash_tests/bash_test.bats.sh diff --git a/README.md b/README.md index 235bf1ee..c7bf51aa 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,9 @@ You can force TAP output from a terminal by invoking Bats with the You can invoke the `bats` interpreter with multiple test file arguments, or with a path to a directory containing multiple `.bats` -files. Bats will run each test file individually and aggregate the -results. If any test case fails, `bats` exits with a `1` status code. +and / or `.bats.sh` files. Bats will run each test file individually and +aggregate the results. If any test case fails, `bats` exits with a `1` +status code. ## Writing tests @@ -80,6 +81,29 @@ For more details about how Bats evaluates test files, see [Bats Evaluation Process](https://github.com/sstephenson/bats/wiki/Bats-Evaluation-Process) on the wiki. +### Bash-compatible convention syntax + +If your tools don't have built-in support for `.bats` syntax, you can +still use Bats with its support for `.bats.sh` convention tests. Each +function declaration starting with the `funciton` keyword is going to be +converted to a Bats test. For example, running the following test file: + +```bash +#!/usr/bin/env bats + +function test_using_bash_convention_syntax { + result="$(echo 2+2 | bc)" + [ "$result" -eq 4 ] +} +``` + +will output: + + $ bats bash_addition.bats.sh + ✓ test_using_bash_convention_syntax + + 1 tests, 0 failures + ### `run`: Test other commands Many Bats tests need to run a command and then make assertions about diff --git a/libexec/bats b/libexec/bats index 71f392f7..f196958b 100755 --- a/libexec/bats +++ b/libexec/bats @@ -118,6 +118,9 @@ for filename in "${arguments[@]}"; do for suite_filename in "$(expand_path "$filename")"/*.bats; do filenames["${#filenames[@]}"]="$suite_filename" done + for suite_filename in "$(expand_path "$filename")"/*.bats.sh; do + filenames["${#filenames[@]}"]="$suite_filename" + done shopt -u nullglob else filenames["${#filenames[@]}"]="$(expand_path "$filename")" diff --git a/libexec/bats-preprocess b/libexec/bats-preprocess index 04297ed0..cbb6a64b 100755 --- a/libexec/bats-preprocess +++ b/libexec/bats-preprocess @@ -31,13 +31,13 @@ encode_name() { tests=() index=0 -pattern='^ *@test *([^ ].*) *\{ *(.*)$' +pattern='^ *(@test *|function *)([^ ].*) *\{ *(.*)$' while IFS= read -r line; do let index+=1 if [[ "$line" =~ $pattern ]]; then - quoted_name="${BASH_REMATCH[1]}" - body="${BASH_REMATCH[2]}" + quoted_name="${BASH_REMATCH[2]}" + body="${BASH_REMATCH[3]}" name="$(eval echo "$quoted_name")" encoded_name="$(encode_name "$name")" tests["${#tests[@]}"]="$encoded_name" diff --git a/test/bats.bats b/test/bats.bats index f1aff293..0261eab2 100755 --- a/test/bats.bats +++ b/test/bats.bats @@ -262,3 +262,15 @@ fixtures bats [ $status -eq 0 ] [ "${lines[1]}" = "ok 1 loop_func" ] } + +@test "runs a single explicitly passed .bats.sh file" { + run bats "$FIXTURE_ROOT/bash_tests/bash_test.bats.sh" + [ $status -eq 0 ] + [ "${lines[1]}" = "ok 1 test_bash_syntax" ] +} + +@test "discovers .bats.sh test files" { + run bats "$FIXTURE_ROOT/bash_tests" + [ $status -eq 0 ] + [ "${lines[1]}" = "ok 1 test_bash_syntax" ] +} diff --git a/test/fixtures/bats/bash_tests/bash_test.bats.sh b/test/fixtures/bats/bash_tests/bash_test.bats.sh new file mode 100644 index 00000000..138958d8 --- /dev/null +++ b/test/fixtures/bats/bash_tests/bash_test.bats.sh @@ -0,0 +1,3 @@ +function test_bash_syntax { + echo 'It works!' +}