Merge pull request #1559 from nwinkler/update-bats-core

Update bats-core to lastest master
This commit is contained in:
Nils Winkler
2020-05-01 13:53:54 +02:00
committed by GitHub
13 changed files with 121 additions and 242 deletions

5
.gitmodules vendored
View File

@@ -1,6 +1,7 @@
[submodule "test_lib/bats-core"]
path = test_lib/bats-core
url = https://github.com/bats-core/bats-core
branch = tags/v1.2.0
[submodule "test_lib/bats-support"]
path = test_lib/bats-support
url = https://github.com/bats-core/bats-support
@@ -11,5 +12,5 @@
branch = tags/v2.0.0
[submodule "test_lib/bats-file"]
path = test_lib/bats-file
url = https://github.com/tralston/bats-file
branch = tags/v0.3.0
url = https://github.com/bats-core/bats-file
branch = tags/v0.3.0

View File

@@ -1,4 +1,13 @@
## Testing with [Bats](https://github.com/sstephenson/bats#installing-bats-from-source)
# Testing with Bats
## Overview
The Bash-it unit tests leverage the [Bats unit test framework for Bash](https://github.com/bats-core/bats-core).
There is no need to install Bats explicitly, the test run script will automatically download and install Bats and its dependencies.
When making changes to Bash-it, the tests are automatically executed in a test build environment on [Travis CI](https://travis-ci.com).
## Test Execution
To execute the unit tests, please run the `run` script:
@@ -10,4 +19,22 @@ To execute the unit tests, please run the `run` script:
test/run
```
The `run` script will automatically install [Bats](https://github.com/sstephenson/bats#installing-bats-from-source) if it is not already present, and will then run all tests found under the `test` directory, including subdirectories.
The `run` script will automatically install if it is not already present, and will then run all tests found under the `test` directory, including subdirectories.
To run only a subset of the tests, you can provide the name of the test subdirectory that you want to run, e.g. like this for the tests in the `test/themes` directory:
```bash
# If you are in the root `.bash_it` directory:
test/run test/themes
```
By default, the tests run in single-threaded mode.
If you want to speed up the test execution, you can install the [GNU `parallel` tool](https://www.gnu.org/software/parallel/), which is supported by Bats.
When using `parallel`, the `test/run` script will use a number of threads in parallel, depending on the available CPU cores of your system.
This can speed up test execution significantly.
## Writing Tests
When adding or modifying tests, please stick to the format and conventions of the existing test cases.
The `test_helper.bash` script provides a couple of reusable helper functions that you should use when writing a test case,
for example for setting up an isolated test environment.

View File

@@ -4,36 +4,10 @@ load ../test_helper
load ../../lib/composure
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
echo "Bi : $BASH_IT"
echo "Lib: $lib_directory"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
setup_test_fixture
# Copy the test fixture to the Bash-it folder
rsync -a "$BASH_IT/test/fixtures/bash_it/" "$BASH_IT/"
# Don't pollute the user's actual $HOME directory
# Use a test home directory instead
export BASH_IT_TEST_CURRENT_HOME="${HOME}"
export BASH_IT_TEST_HOME="$(cd "${BASH_IT}/.." && pwd)/BASH_IT_TEST_HOME"
mkdir -p "${BASH_IT_TEST_HOME}"
export HOME="${BASH_IT_TEST_HOME}"
}
function local_teardown {
export HOME="${BASH_IT_TEST_CURRENT_HOME}"
rm -rf "${BASH_IT_TEST_HOME}"
assert_equal "${BASH_IT_TEST_CURRENT_HOME}" "${HOME}"
}
@test "bash-it: verify that the test fixture is available" {

View File

@@ -5,36 +5,7 @@ load ../../lib/composure
load ../../completion/available/bash-it.completion
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
# Don't pollute the user's actual $HOME directory
# Use a test home directory instead
export BASH_IT_TEST_CURRENT_HOME="${HOME}"
export BASH_IT_TEST_HOME="$(cd "${BASH_IT}/.." && pwd)/BASH_IT_TEST_HOME"
mkdir -p "${BASH_IT_TEST_HOME}"
export HOME="${BASH_IT_TEST_HOME}"
}
function local_teardown {
export HOME="${BASH_IT_TEST_CURRENT_HOME}"
rm -rf "${BASH_IT_TEST_HOME}"
assert_equal "${BASH_IT_TEST_CURRENT_HOME}" "${HOME}"
setup_test_fixture
}
@test "completion bash-it: ensure that the _bash-it-comp function is available" {

View File

@@ -14,31 +14,7 @@ case $OSTYPE in
esac
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
# Don't pollute the user's actual $HOME directory
# Use a test home directory instead
export BASH_IT_TEST_CURRENT_HOME="${HOME}"
export BASH_IT_TEST_HOME="$(cd "${BASH_IT}/.." && pwd)/BASH_IT_TEST_HOME"
mkdir -p "${BASH_IT_TEST_HOME}"
export HOME="${BASH_IT_TEST_HOME}"
}
function local_teardown {
export HOME="${BASH_IT_TEST_CURRENT_HOME}"
rm -rf "${BASH_IT_TEST_HOME}"
assert_equal "${BASH_IT_TEST_CURRENT_HOME}" "${HOME}"
setup_test_fixture
}
@test "install: verify that the install script exists" {

View File

@@ -14,31 +14,7 @@ case $OSTYPE in
esac
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
# Don't pollute the user's actual $HOME directory
# Use a test home directory instead
export BASH_IT_TEST_CURRENT_HOME="${HOME}"
export BASH_IT_TEST_HOME="$(cd "${BASH_IT}/.." && pwd)/BASH_IT_TEST_HOME"
mkdir -p "${BASH_IT_TEST_HOME}"
export HOME="${BASH_IT_TEST_HOME}"
}
function local_teardown {
export HOME="${BASH_IT_TEST_CURRENT_HOME}"
rm -rf "${BASH_IT_TEST_HOME}"
assert_equal "${BASH_IT_TEST_CURRENT_HOME}" "${HOME}"
setup_test_fixture
}
@test "uninstall: verify that the uninstall script exists" {

View File

@@ -11,21 +11,7 @@ cite _about _param _example _group _author _version
load ../../lib/helpers
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
setup_test_fixture
}
# TODO Create global __is_enabled function

View File

@@ -18,22 +18,7 @@ cite _about _param _example _group _author _version
load ../../lib/helpers
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
rm -rf "$BASH_IT"/tmp/cache
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
setup_test_fixture
export OLD_PATH="$PATH"
export PATH="/usr/bin:/bin:/usr/sbin"

View File

@@ -9,22 +9,7 @@ load ../../lib/search
cite _about _param _example _group _author _version
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
rm -rf "$BASH_IT"/tmp/cache
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
setup_test_fixture
}
function has_match() {

View File

@@ -6,21 +6,7 @@ load ../../lib/composure
load ../../plugins/available/ruby.plugin
function local_setup {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git $lib_directory/../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
setup_test_fixture
export OLD_PATH="$PATH"
export PATH="/usr/bin:/bin:/usr/sbin"

View File

@@ -16,4 +16,33 @@ else
test_dirs=( "$1" )
fi
exec $bats_executable ${CI:+--tap} "${test_dirs[@]}"
# Make sure that the `parallel` command is installed,
# AND that it is the GNU version of `parallel`.
# If that is the case, try to guess the number of CPU cores,
# so we can run `bats` in parallel processing mode, which is a lot faster.
if command -v parallel &> /dev/null \
&& parallel -V &> /dev/null \
&& { parallel -V 2> /dev/null | grep -q '^GNU\>'; }
then
# Expect to run at least on a dual-core CPU; slightly degraded performance
# shouldn't matter otherwise.
declare -i -r test_jobs_default=2
declare -i -r test_jobs_effective="$(
if [ "${TEST_JOBS:-detect}" = "detect" ] \
&& command -v nproc &> /dev/null
then
nproc
elif [ -n "${TEST_JOBS}" ] \
&& [ "${TEST_JOBS}" != "detect" ]
then
echo "${TEST_JOBS}"
else
echo ${test_jobs_default}
fi
)"
exec "$bats_executable" ${CI:+--tap} --jobs ${test_jobs_effective} \
"${test_dirs[@]}"
else
# Run `bats` in single-threaded mode.
exec "$bats_executable" ${CI:+--tap} "${test_dirs[@]}"
fi

View File

@@ -6,34 +6,12 @@ unset TODO
unset SCM_CHECK
unset BASH_IT_AUTOMATIC_RELOAD_AFTER_CONFIG_CHANGE
BASH_IT_TEST_DIR="${BATS_TMPDIR}/.bash_it"
# guard against executing this block twice due to bats internals
if [ "$BASH_IT_ROOT" != "${BASH_IT_TEST_DIR}/root" ]; then
export BASH_IT_ROOT="${BASH_IT_TEST_DIR}/root"
export BASH_IT=$BASH_IT_TEST_DIR
fi
export TEST_MAIN_DIR="${BATS_TEST_DIRNAME}/.."
export TEST_DEPS_DIR="${TEST_DEPS_DIR-${TEST_MAIN_DIR}/../test_lib}"
# be independent of git's system configuration
export GIT_CONFIG_NOSYSTEM
# Some tools, e.g. `git` use configuration files from the $HOME directory,
# which interferes with our tests. The only way to keep `git` from doing this
# seems to set HOME explicitly to a separate location.
# Refer to https://git-scm.com/docs/git-config#FILES.
unset XDG_CONFIG_HOME
export HOME="${BATS_TMPDIR}/home"
mkdir -p "${HOME}"
# For `git` tests to run well, user name and email need to be set.
# Refer to https://git-scm.com/docs/git-commit#_commit_information.
# This goes to the test-specific config, due to the $HOME overridden above.
git config --global user.name "John Doe"
git config --global user.email "johndoe@example.com"
load "${TEST_DEPS_DIR}/bats-support/load.bash"
load "${TEST_DEPS_DIR}/bats-assert/load.bash"
load "${TEST_DEPS_DIR}/bats-file/load.bash"
@@ -46,9 +24,58 @@ local_teardown() {
true
}
# This function sets up a local test fixture, i.e. a completely
# fresh and isolated Bash-it directory. This is done to avoid
# messing with your own Bash-it source directory.
# If you need this, call it in your .bats file's `local_setup` function.
setup_test_fixture() {
mkdir -p "$BASH_IT"
lib_directory="$(cd "$(dirname "$0")" && pwd)"
# Use rsync to copy Bash-it to the temp folder
# rsync is faster than cp, since we can exclude the large ".git" folder
rsync -qavrKL -d --delete-excluded --exclude=.git --exclude=enabled $lib_directory/../../../.. "$BASH_IT"
rm -rf "$BASH_IT"/enabled
rm -rf "$BASH_IT"/aliases/enabled
rm -rf "$BASH_IT"/completion/enabled
rm -rf "$BASH_IT"/plugins/enabled
mkdir -p "$BASH_IT"/enabled
mkdir -p "$BASH_IT"/aliases/enabled
mkdir -p "$BASH_IT"/completion/enabled
mkdir -p "$BASH_IT"/plugins/enabled
# Some tests use the BASH_IT_TEST_HOME variable, e.g. install/uninstall
export BASH_IT_TEST_HOME="$TEST_TEMP_DIR"
}
setup() {
# The `temp_make` function from "bats-file" requires the tralston/bats-file fork,
# since the original ztombol/bats-file's `temp_make` does not work on macOS.
TEST_TEMP_DIR="$(temp_make --prefix 'bash-it-test-')"
export TEST_TEMP_DIR
export BASH_IT_TEST_DIR="${TEST_TEMP_DIR}/.bash_it"
export BASH_IT_ROOT="${BASH_IT_TEST_DIR}/root"
export BASH_IT=$BASH_IT_TEST_DIR
mkdir -p -- "${BASH_IT_ROOT}"
# Some tools, e.g. `git` use configuration files from the $HOME directory,
# which interferes with our tests. The only way to keep `git` from doing this
# seems to set HOME explicitly to a separate location.
# Refer to https://git-scm.com/docs/git-config#FILES.
unset XDG_CONFIG_HOME
export HOME="${TEST_TEMP_DIR}"
mkdir -p "${HOME}"
# For `git` tests to run well, user name and email need to be set.
# Refer to https://git-scm.com/docs/git-commit#_commit_information.
# This goes to the test-specific config, due to the $HOME overridden above.
git config --global user.name "John Doe"
git config --global user.email "johndoe@example.com"
local_setup
}
@@ -56,49 +83,5 @@ teardown() {
local_teardown
rm -rf "${BASH_IT_TEST_DIR}"
}
# Fail and display path of the link if it does not exist. Also fails
# if the path exists, but is not a link.
# This function is the logical complement of `assert_file_not_exist'.
# There is no dedicated function for checking that a link does not exist.
#
# Globals:
# BATSLIB_FILE_PATH_REM
# BATSLIB_FILE_PATH_ADD
# Arguments:
# $1 - path
# Returns:
# 0 - link exists and is a link
# 1 - otherwise
# Outputs:
# STDERR - details, on failure
assert_link_exist() {
local -r file="$1"
local -r target="$2"
if [[ ! -L "$file" ]]; then
local -r rem="$BATSLIB_FILE_PATH_REM"
local -r add="$BATSLIB_FILE_PATH_ADD"
if [[ -e "$file" ]]; then
batslib_print_kv_single 4 'path' "${file/$rem/$add}" \
| batslib_decorate 'exists, but is not a link' \
| fail
else
batslib_print_kv_single 4 'path' "${file/$rem/$add}" \
| batslib_decorate 'link does not exist' \
| fail
fi
else
if [ -n "$target" ]; then
local link_target=''
link_target=$(readlink "$file")
if [[ "$link_target" != "$target" ]]; then
batslib_print_kv_single_or_multi 8 'path' "${file/$rem/$add}" \
'expected' "$target" \
'actual' "$link_target" \
| batslib_decorate 'link exists, but does not point to target file' \
| fail
fi
fi
fi
temp_del "${TEST_TEMP_DIR}"
}