diff --git a/README.md b/README.md index d3e1cf8..ff7fe44 100644 --- a/README.md +++ b/README.md @@ -398,6 +398,11 @@ The rbenv source code is [hosted on GitHub](https://github.com/sstephenson/rbenv). It's clean, modular, and easy to understand, even if you're not a shell hacker. +Tests are executed using [Bats](https://github.com/sstephenson/bats): + + $ bats test + $ bats test/.bats + Please feel free to submit pull requests and file bugs on the [issue tracker](https://github.com/sstephenson/rbenv/issues). diff --git a/libexec/rbenv---version b/libexec/rbenv---version index ba5c562..79cb64d 100755 --- a/libexec/rbenv---version +++ b/libexec/rbenv---version @@ -14,8 +14,9 @@ set -e version="0.4.0" -cd "$RBENV_ROOT" -git_revision="$(git describe --tags HEAD 2>/dev/null || true)" -git_revision="${git_revision#v}" +if cd "$RBENV_ROOT" 2>/dev/null; then + git_revision="$(git describe --tags HEAD 2>/dev/null || true)" + git_revision="${git_revision#v}" +fi echo "rbenv ${git_revision:-$version}" diff --git a/libexec/rbenv-shims b/libexec/rbenv-shims index 713ca5a..9a1b055 100755 --- a/libexec/rbenv-shims +++ b/libexec/rbenv-shims @@ -11,6 +11,8 @@ if [ "$1" = "--complete" ]; then exit fi +shopt -s nullglob + for command in "${RBENV_ROOT}/shims/"*; do if [ "$1" = "--short" ]; then echo "${command##*/}" diff --git a/test/commands.bats b/test/commands.bats new file mode 100644 index 0000000..2cac394 --- /dev/null +++ b/test/commands.bats @@ -0,0 +1,27 @@ +#!/usr/bin/env bats + +load test_helper + +@test "commands" { + run rbenv-commands + assert_success + assert_line "init" + assert_line "rehash" + assert_line "shell" + refute_line "sh-shell" + assert_line "echo" +} + +@test "commands --sh" { + run rbenv-commands --sh + assert_success + refute_line "init" + assert_line "shell" +} + +@test "commands --no-sh" { + run rbenv-commands --no-sh + assert_success + assert_line "init" + refute_line "shell" +} diff --git a/test/global.bats b/test/global.bats new file mode 100644 index 0000000..f6dcc3e --- /dev/null +++ b/test/global.bats @@ -0,0 +1,31 @@ +#!/usr/bin/env bats + +load test_helper + +@test "default" { + run rbenv global + assert_success + assert_output "system" +} + +@test "read RBENV_ROOT/version" { + mkdir -p "$RBENV_ROOT" + echo "1.2.3" > "$RBENV_ROOT/version" + run rbenv-global + assert_success + assert_output "1.2.3" +} + +@test "set RBENV_ROOT/version" { + mkdir -p "$RBENV_ROOT/versions/1.2.3" + run rbenv-global "1.2.3" + assert_success + run rbenv global + assert_success "1.2.3" +} + +@test "fail setting invalid RBENV_ROOT/version" { + mkdir -p "$RBENV_ROOT" + run rbenv-global "1.2.3" + assert_failure "rbenv: version \`1.2.3' not installed" +} diff --git a/test/libexec/rbenv-echo b/test/libexec/rbenv-echo new file mode 100755 index 0000000..0a802df --- /dev/null +++ b/test/libexec/rbenv-echo @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +eval "echo \$$1" diff --git a/test/local.bats b/test/local.bats new file mode 100644 index 0000000..5ccdb2b --- /dev/null +++ b/test/local.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load test_helper + +setup() { + mkdir -p "${RBENV_TEST_DIR}/myproject" + cd "${RBENV_TEST_DIR}/myproject" +} + +@test "no version" { + assert [ ! -e "${PWD}/.ruby-version" ] + run rbenv-local + assert_failure "rbenv: no local version configured for this directory" +} + +@test "local version" { + echo "1.2.3" > .ruby-version + run rbenv-local + assert_success "1.2.3" +} + +@test "ignores version in parent directory" { + echo "1.2.3" > .ruby-version + mkdir -p "subdir" && cd "subdir" + run rbenv-local + assert_failure +} + +@test "ignores RBENV_DIR" { + echo "1.2.3" > .ruby-version + mkdir -p "$HOME" + echo "2.0-home" > "${HOME}/.ruby-version" + RBENV_DIR="$HOME" run rbenv-local + assert_success "1.2.3" +} + +@test "sets local version" { + mkdir -p "${RBENV_ROOT}/versions/1.2.3" + run rbenv-local 1.2.3 + assert_success "" + assert [ "$(cat .ruby-version)" = "1.2.3" ] +} + +@test "changes local version" { + echo "1.0-pre" > .ruby-version + mkdir -p "${RBENV_ROOT}/versions/1.2.3" + run rbenv-local + assert_success "1.0-pre" + run rbenv-local 1.2.3 + assert_success "" + run rbenv-local + assert_success "1.2.3" +} diff --git a/test/prefix.bats b/test/prefix.bats new file mode 100644 index 0000000..b7afa87 --- /dev/null +++ b/test/prefix.bats @@ -0,0 +1,25 @@ +#!/usr/bin/env bats + +load test_helper + +@test "prefix" { + mkdir -p "${RBENV_TEST_DIR}/myproject" + cd "${RBENV_TEST_DIR}/myproject" + echo "1.2.3" > .ruby-version + mkdir -p "${RBENV_ROOT}/versions/1.2.3" + run rbenv-prefix + assert_success "${RBENV_ROOT}/versions/1.2.3" +} + +@test "prefix for invalid version" { + RBENV_VERSION="1.2.3" run rbenv-prefix + assert_failure "rbenv: version \`1.2.3' not installed" +} + +@test "prefix for system" { + mkdir -p "${RBENV_TEST_DIR}/bin" + touch "${RBENV_TEST_DIR}/bin/ruby" + chmod +x "${RBENV_TEST_DIR}/bin/ruby" + RBENV_VERSION="system" run rbenv-prefix + assert_success "$RBENV_TEST_DIR" +} diff --git a/test/rbenv.bats b/test/rbenv.bats new file mode 100644 index 0000000..e8a939a --- /dev/null +++ b/test/rbenv.bats @@ -0,0 +1,47 @@ +#!/usr/bin/env bats + +load test_helper + +@test "blank invocation" { + run rbenv + assert_success + assert [ "${lines[0]}" = "rbenv 0.4.0" ] +} + +@test "invalid command" { + run rbenv does-not-exist + assert_failure + assert_output "rbenv: no such command \`does-not-exist'" +} + +@test "default RBENV_ROOT" { + RBENV_ROOT="" HOME=/home/mislav run rbenv root + assert_success + assert_output "/home/mislav/.rbenv" +} + +@test "inherited RBENV_ROOT" { + RBENV_ROOT=/opt/rbenv run rbenv root + assert_success + assert_output "/opt/rbenv" +} + +@test "default RBENV_DIR" { + run rbenv echo RBENV_DIR + assert_output "$(pwd)" +} + +@test "inherited RBENV_DIR" { + dir="${BATS_TMPDIR}/myproject" + mkdir -p "$dir" + RBENV_DIR="$dir" run rbenv echo RBENV_DIR + assert_output "$dir" +} + +@test "invalid RBENV_DIR" { + dir="${BATS_TMPDIR}/does-not-exist" + assert [ ! -d "$dir" ] + RBENV_DIR="$dir" run rbenv echo RBENV_DIR + assert_failure + assert_output "rbenv: cannot change working directory to \`$dir'" +} diff --git a/test/rehash.bats b/test/rehash.bats index 22f26d0..6e9e890 100755 --- a/test/rehash.bats +++ b/test/rehash.bats @@ -1,33 +1,27 @@ #!/usr/bin/env bats -export PATH="${BATS_TEST_DIRNAME}/../libexec:$PATH" - -RBENV_TEST_ROOT="${BATS_TMPDIR}/rbenv" -export RBENV_ROOT="$RBENV_TEST_ROOT" - -teardown() { - rm -rf "$RBENV_TEST_ROOT" -} +load test_helper @test "empty rehash" { + assert [ ! -d "${RBENV_ROOT}/shims" ] run rbenv-rehash - [ "$status" -eq 0 ] - [ -d "${RBENV_TEST_ROOT}/shims" ] - rmdir "${RBENV_TEST_ROOT}/shims" + assert_success + assert [ -d "${RBENV_ROOT}/shims" ] + rmdir "${RBENV_ROOT}/shims" } -@test "shims directory not writable" { - mkdir -p "${RBENV_TEST_ROOT}/shims" - chmod -w "${RBENV_TEST_ROOT}/shims" +@test "non-writable shims directory" { + mkdir -p "${RBENV_ROOT}/shims" + chmod -w "${RBENV_ROOT}/shims" run rbenv-rehash - [ "$status" -eq 1 ] - [ "$output" = "rbenv: cannot rehash: ${RBENV_TEST_ROOT}/shims isn't writable" ] + assert_failure + assert_output "rbenv: cannot rehash: ${RBENV_ROOT}/shims isn't writable" } @test "rehash in progress" { - mkdir -p "${RBENV_TEST_ROOT}/shims" - touch "${RBENV_TEST_ROOT}/shims/.rbenv-shim" + mkdir -p "${RBENV_ROOT}/shims" + touch "${RBENV_ROOT}/shims/.rbenv-shim" run rbenv-rehash - [ "$status" -eq 1 ] - [ "$output" = "rbenv: cannot rehash: ${RBENV_TEST_ROOT}/shims/.rbenv-shim exists" ] + assert_failure + assert_output "rbenv: cannot rehash: ${RBENV_ROOT}/shims/.rbenv-shim exists" } diff --git a/test/shell.bats b/test/shell.bats new file mode 100644 index 0000000..9477898 --- /dev/null +++ b/test/shell.bats @@ -0,0 +1,35 @@ +#!/usr/bin/env bats + +load test_helper + +@test "no shell version" { + mkdir -p "${RBENV_TEST_DIR}/myproject" + cd "${RBENV_TEST_DIR}/myproject" + echo "1.2.3" > .ruby-version + RBENV_VERSION="" run rbenv-sh-shell + assert_failure "rbenv: no shell-specific version configured" +} + +@test "shell version" { + RBENV_VERSION="1.2.3" run rbenv-sh-shell + assert_success 'echo "$RBENV_VERSION"' +} + +@test "shell unset" { + run rbenv-sh-shell --unset + assert_success "unset RBENV_VERSION" +} + +@test "shell change invalid version" { + run rbenv-sh-shell 1.2.3 + assert_failure + assert_line "rbenv: version \`1.2.3' not installed" + assert_line "return 1" +} + +@test "shell change version" { + mkdir -p "${RBENV_ROOT}/versions/1.2.3" + run rbenv-sh-shell 1.2.3 + assert_success 'export RBENV_VERSION="1.2.3"' + refute_line "return 1" +} diff --git a/test/shims.bats b/test/shims.bats new file mode 100644 index 0000000..194554a --- /dev/null +++ b/test/shims.bats @@ -0,0 +1,29 @@ +#!/usr/bin/env bats + +load test_helper + +@test "no shims" { + run rbenv-shims + assert_success + assert [ -z "$output" ] +} + +@test "shims" { + mkdir -p "${RBENV_ROOT}/shims" + touch "${RBENV_ROOT}/shims/ruby" + touch "${RBENV_ROOT}/shims/irb" + run rbenv-shims + assert_success + assert_line "${RBENV_ROOT}/shims/ruby" + assert_line "${RBENV_ROOT}/shims/irb" +} + +@test "shims --short" { + mkdir -p "${RBENV_ROOT}/shims" + touch "${RBENV_ROOT}/shims/ruby" + touch "${RBENV_ROOT}/shims/irb" + run rbenv-shims --short + assert_success + assert_line "irb" + assert_line "ruby" +} diff --git a/test/test_helper.bash b/test/test_helper.bash new file mode 100644 index 0000000..7d52e44 --- /dev/null +++ b/test/test_helper.bash @@ -0,0 +1,62 @@ +RBENV_TEST_DIR="${BATS_TMPDIR}/rbenv" +export RBENV_ROOT="${RBENV_TEST_DIR}/root" +export HOME="${RBENV_TEST_DIR}/home" + +unset RBENV_VERSION +unset RBENV_DIR + +export PATH="${RBENV_TEST_DIR}/bin:$PATH" +export PATH="${BATS_TEST_DIRNAME}/../libexec:$PATH" +export PATH="${BATS_TEST_DIRNAME}/libexec:$PATH" +export PATH="${RBENV_ROOT}/shims:$PATH" + +teardown() { + rm -rf "$RBENV_TEST_DIR" +} + +flunk() { + echo "$@" | sed "s:${RBENV_ROOT}:\$RBENV_ROOT:" >&2 + return 1 +} + +assert_success() { + if [ "$status" -ne 0 ]; then + flunk "command failed with exit status $status" + elif [ "$#" -gt 0 ]; then + assert_output "$1" + fi +} + +assert_failure() { + if [ "$status" -eq 0 ]; then + flunk "expected failed exit status" + elif [ "$#" -gt 0 ]; then + assert_output "$1" + fi +} + +assert_output() { + if [ "$output" != "$1" ]; then + flunk "expected: $1" || true + flunk "got: $output" + fi +} + +assert_line() { + for line in "${lines[@]}"; do + if [ "$line" = "$1" ]; then return 0; fi + done + flunk "expected line \`$1'" +} + +refute_line() { + for line in "${lines[@]}"; do + if [ "$line" = "$1" ]; then flunk "expected to not find line \`$line'"; fi + done +} + +assert() { + if ! "$@"; then + flunk "failed: $@" + fi +}