Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bats/helpers: Add create_forwarding_script #192

Merged
merged 1 commit into from
Aug 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 38 additions & 19 deletions lib/bats/helpers
Original file line number Diff line number Diff line change
Expand Up @@ -296,51 +296,70 @@ split_bats_output_into_lines() {
# added to `PATH` and exported if it isn't already present.
#
# You may need to call `restore_program_in_path` immediately after `run` to
# avoid side-effects in the rest of your test program, especially when using the
# `--in-process` option.
#
# Options:
# --in-process Set this when calling `run` on an in-process function
# avoid side-effects in the rest of your test program.
#
# Arguments:
# cmd_name: Name of the command from PATH to stub
# ...: Lines comprising the stub script
stub_program_in_path() {
local cmd_name="$1"
local bindir_pattern="^${BATS_TEST_BINDIR}:"
local in_process

if [[ "$1" == '--in-process' ]]; then
in_process='true'
shift
fi
create_bats_test_script "${BATS_TEST_BINDIR#$BATS_TEST_ROOTDIR/}/$1" "${@:2}"
create_bats_test_script "${BATS_TEST_BINDIR#$BATS_TEST_ROOTDIR/}/$cmd_name" \
"${@:2}"

if [[ ! "$PATH" =~ $bindir_pattern ]]; then
export PATH="$BATS_TEST_BINDIR:$PATH"
fi
}

if [[ -n "$in_process" ]]; then
hash "$1"
# Creates a forwarding wrapper in `BATS_TEST_BINDIR` for an existing command
#
# If the command doesn't exist on the system, no forwarding script will be
# created. The current value of `PATH` will be available to the wrapped command,
# in case it requires `PATH` to invoke its own helpers, like `git` does.
#
# This enables a test to use `PATH="$BATS_TEST_BINDIR" run ...` to make a few
# system commands available while hiding the rest. This is useful for test cases
# in which specific commands can't be found. E.g. `tests/template.bats` contains
# several such cases.
#
# Call `restore_program_in_path` after `run` to remove the forwarding script
# from `PATH` and avoid test failures due to side effects.
#
# Arguments:
# cmd_name: Name of the system command to wrap with a forwarding script
create_forwarding_script() {
set "$DISABLE_BATS_SHELL_OPTIONS"
local cmd_name="$1"

if command -v "$cmd_name"; then
stub_program_in_path "$@" \
"#! $BASH" \
"PATH='$PATH' \"$(command -v "$cmd_name")\" \"\$@\""
fi
restore_bats_shell_options
}

# Removes a stub program from `PATH`
#
# This will return an error if the stub doesn't exist, to help avoid errors
# when the `cmd_name` arguments to `stub_program_in_path` and this function
# don't match.
# when the `cmd_name` arguments to `stub_program_in_path` or
# `create_forwarding_script` and this function don't match.
#
# Arguments:
# cmd_name: Name of the command from PATH to stub
#
# Returns:
# Zero if the stub program exists and is removed, nonzero otherwise
restore_program_in_path() {
if [[ -e "$BATS_TEST_BINDIR/$1" ]]; then
rm -f "$BATS_TEST_BINDIR/$1"
hash "$1"
local cmd_name="$1"
export PATH="${PATH#$BATS_TEST_BINDIR:}"

if [[ -e "$BATS_TEST_BINDIR/$cmd_name" ]]; then
rm -f "$BATS_TEST_BINDIR/$cmd_name"
else
printf "Bats test stub program doesn't exist: %s\n" "$1"
printf "Bats test stub program doesn't exist: %s\n" "$cmd_name"
return 1
fi
}
Expand Down
18 changes: 16 additions & 2 deletions tests/bats-helpers.bats
Original file line number Diff line number Diff line change
Expand Up @@ -247,19 +247,33 @@ __check_dirs_exist() {
assert_success 'ugo+rwx foo.txt'
}

@test "$SUITE: {stub,restore}_program_in_path for testing in-process function" {
@test "$SUITE: {stub,restore}_program_in_path for testing functions" {
local orig_path="$(command -v mkdir)"

stub_program_in_path --in-process 'mkdir' 'echo "$@"'
stub_program_in_path 'mkdir' 'echo "$@"'
run command -v mkdir
assert_success "$BATS_TEST_BINDIR/mkdir"

restore_program_in_path 'mkdir'
run command -v mkdir
assert_success "$orig_path"
fail_if matches "$BATS_TEST_BINDIR" "$PATH"
}

@test "$SUITE: restore_program_in_path fails when stub doesn't exist" {
run restore_program_in_path 'foobar'
assert_failure "Bats test stub program doesn't exist: foobar"
}

@test "$SUITE: create_forwarding_script does nothing if program doesn't exist" {
create_forwarding_script 'some-noexistent-program-name'
fail_if matches "^${BATS_TEST_BINDIR}:" "$PATH"
run command -v 'some-noexistent-program-name'
assert_failure
}

@test "$SUITE: create_forwarding_script script with PATH=\$BATS_TEST_BINDIR" {
create_forwarding_script 'bash'
PATH="$BATS_TEST_BINDIR" run command -v 'bash'
assert_success "$BATS_TEST_BINDIR/bash"
}
26 changes: 0 additions & 26 deletions tests/template.bats
Original file line number Diff line number Diff line change
Expand Up @@ -154,32 +154,6 @@ create_fake_tarball_if_not_using_real_url() {
restore_bats_shell_options "$result"
}

# Creates a script in `BATS_TEST_BINDIR` to stand in for a program on `PATH`
#
# This enables a test to use `PATH="$BATS_TEST_BINDIR" run ...` to hide programs
# installed on the system to test cases when specific programs can't be found,
# while others remain available.
#
# Creates `BATS_TEST_BINDIR` if it doesn't already exist. If the program
# doesn't exist on the system, no forwarding script will be created.
#
# Arguments:
# program_name: Name of the system program to forward
create_forwarding_script() {
set "$DISABLE_BATS_SHELL_OPTIONS"
local real_program="$(command -v "$1")"
local script="$BATS_TEST_BINDIR/$1"

if [[ ! -d "$BATS_TEST_BINDIR" ]] && ! mkdir -p "$BATS_TEST_BINDIR"; then
restore_bats_shell_options '1'
return
elif [[ -n "$real_program" ]]; then
printf '%s\n' "#! $BASH" "PATH='$PATH' \"$real_program\" \"\$@\"" >"$script"
chmod 700 "$script"
fi
restore_bats_shell_options
}

# Used to mimic each of curl, wget, and fetch while testing downloads.
#
# This way we can test all of the download program selection logic regardless of
Expand Down