rbenv
The atago project wrote these specs on its own initiative and runs them in its own CI, to exercise atago against a real program. They are not rbenv’s official test suite, and the rbenv project is not affiliated with atago.
Summary #
2 suites · 16 scenarios
Contents #
- rbenv (which version this directory selects) — 9 scenarios
- the version, the usage text, and a command that does not exist
- an empty root has no versions but still answers with system
- installed versions are listed and the selected one is marked
- global writes one file in the root and nothing else
- local wins over global, and the environment wins over both
- unsetting the local version falls back to the global one
- a version that is not installed is refused and nothing is written
- a version file naming an uninstalled version says which file to fix
- which, prefix, version-name and version-origin agree on the selection
- rbenv (shims, exec, and shell integration) — 7 scenarios
- rehash generates one shim per executable across every version
- the shim answers to the directory, with PATH never changing
- a version added after the last rehash has no shim until the next one
- exec runs the selected version, and a command that is not there is 127
- a hook script runs before exec and sees the resolved version
- shell integration is printed on request and refused without it
- init edits the profile in the home it was given, once
rbenv (which version this directory selects) #
rbenv picks the Ruby version a command should run under. It keeps its own test suite in Bats; what those tests check is pinned here from outside, against a root the scenario builds itself.
No Ruby is installed and none is needed: a version is a directory under
versions/, so each scenario writes a couple of two-line executables and
exercises the real resolution rules against them. What is asserted is the
state machine — the file global writes, the file local writes, the
environment variable that beats both, the origin rbenv reports for its
choice, and the refusals that leave every one of those files untouched.
Source: test/e2e/thirdparty/rbenv/rbenv.atago.yaml
Scenario: the version, the usage text, and a command that does not exist #
only when rbenv --version succeeds · skipped on Windows
Given #
- Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
When #
rbenv --version
rbenv
rbenv nosuchcommand
Then #
- after
rbenv --version:- exit code is
0 - stdout matches
/^rbenv [0-9]+\.[0-9]+/
- exit code is
- after
rbenv:- exit code is
1 - stdout is empty
- stderr contains
Usage: rbenv <command> [<args>...],version Show the current Ruby version and its origin
- exit code is
- after
rbenv nosuchcommand:- exit code is
1 - stdout is empty
- stderr equals an exact value
- exit code is
Expected output #
expected stderr:
rbenv: no such command `nosuchcommand'
Scenario: an empty root has no versions but still answers with system #
only when rbenv --version succeeds · skipped on Windows
Given #
- Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
When #
rbenv root
rbenv versions --bare
rbenv version
Then #
- after
rbenv root:- exit code is
0 - stdout matches
//root\n$/
- exit code is
- after
rbenv versions --bare:- exit code is
0 - stdout is empty
- exit code is
- after
rbenv version:- exit code is
0 - stdout equals an exact value
- exit code is
Expected output #
expected stdout:
system
Scenario: installed versions are listed and the selected one is marked #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Fixture file
root/versions/3.3.1/bin/rubyis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture root/versions/3.3.1/bin/ruby:
#!/bin/sh
echo "ruby 3.3.1"
When #
rbenv versions --bare
rbenv global 3.3.1
rbenv versions
Then #
- after
rbenv versions --bare:- exit code is
0 - stdout equals an exact value
- exit code is
- after
rbenv global 3.3.1:- exit code is
0
- exit code is
- after
rbenv versions:- exit code is
0 - stdout matches
/(?m)^\* 3\.3\.1 \(set by .*/root/version\)$/ - stdout matches
/(?m)^ 3\.2\.0$/
- exit code is
Expected output #
expected stdout:
3.2.0
3.3.1
Scenario: global writes one file in the root and nothing else #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
When #
rbenv global 3.2.0
rbenv global
rbenv version
Then #
- after
rbenv global 3.2.0:- exit code is
0 - stdout is empty
- the step changed exactly created
root/version, modified nothing, deleted nothing - file
root/versionequals exact bytes
- exit code is
- after
rbenv global:- exit code is
0 - stdout equals an exact value
- exit code is
- after
rbenv version:- exit code is
0 - stdout matches
/^3\.2\.0 \(set by .*/root/version\)\n$/
- exit code is
Expected output #
expected stdout:
3.2.0
Scenario: local wins over global, and the environment wins over both #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Fixture file
root/versions/3.3.1/bin/rubyis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT, RBENV_VERSION.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture root/versions/3.3.1/bin/ruby:
#!/bin/sh
echo "ruby 3.3.1"
When #
rbenv global 3.2.0
rbenv local 3.3.1
rbenv version
rbenv version
Then #
- after
rbenv global 3.2.0:- exit code is
0
- exit code is
- after
rbenv local 3.3.1:- exit code is
0 - the step changed exactly created
.ruby-version, modified nothing, deleted nothing - file
.ruby-versionequals exact bytes
- exit code is
- after
rbenv version:- exit code is
0 - stdout matches
/^3\.3\.1 \(set by .*/\.ruby-version\)\n$/
- exit code is
- after
rbenv version:- exit code is
0 - stdout equals an exact value
- exit code is
Expected output #
expected stdout:
3.2.0 (set by RBENV_VERSION environment variable)
Scenario: unsetting the local version falls back to the global one #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Fixture file
root/versions/3.3.1/bin/rubyis created. - Fixture file
.ruby-versionis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture root/versions/3.3.1/bin/ruby:
#!/bin/sh
echo "ruby 3.3.1"
Fixture .ruby-version:
3.3.1
When #
rbenv global 3.2.0
rbenv local --unset
rbenv version
Then #
- after
rbenv global 3.2.0:- exit code is
0
- exit code is
- after
rbenv local --unset:- exit code is
0 - the step changed exactly created nothing, modified nothing, deleted
.ruby-version
- exit code is
- after
rbenv version:- exit code is
0 - stdout matches
/^3\.2\.0 \(set by .*/root/version\)\n$/
- exit code is
Scenario: a version that is not installed is refused and nothing is written #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Fixture file
.ruby-versionis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture .ruby-version:
3.2.0
When #
rbenv local 9.9.9
rbenv global 9.9.9
Then #
- after
rbenv local 9.9.9:- exit code is
1 - stdout is empty
- stderr equals an exact value
- the step changed exactly created nothing, modified nothing, deleted nothing
- file
.ruby-versionequals exact bytes
- exit code is
- after
rbenv global 9.9.9:- exit code is
1 - stderr equals an exact value
- the step changed exactly created nothing, modified nothing, deleted nothing
- exit code is
Expected output #
expected stderr:
rbenv: version `9.9.9' not installed
expected stderr:
rbenv: version `9.9.9' not installed
Scenario: a version file naming an uninstalled version says which file to fix #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Fixture file
.ruby-versionis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture .ruby-version:
9.9.9
When #
rbenv version
Then #
- exit code is
1 - stdout is empty
- stderr matches
/^rbenv: version `9\.9\.9' is not installed \(set by .*/\.ruby-version\)\n$/
Scenario: which, prefix, version-name and version-origin agree on the selection #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.3.1/bin/rubyis created. - Fixture file
.ruby-versionis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.3.1/bin/ruby:
#!/bin/sh
echo "ruby 3.3.1"
Fixture .ruby-version:
3.3.1
When #
rbenv version-name
rbenv version-origin
rbenv prefix
rbenv which ruby
Then #
- after
rbenv version-name:- exit code is
0 - stdout equals an exact value
- exit code is
- after
rbenv version-origin:- exit code is
0 - stdout matches
//\.ruby-version\n$/
- exit code is
- after
rbenv prefix:- exit code is
0 - stdout matches
//root/versions/3\.3\.1\n$/
- exit code is
- after
rbenv which ruby:- exit code is
0 - stdout matches
//root/versions/3\.3\.1/bin/ruby\n$/
- exit code is
Expected output #
expected stdout:
3.3.1
rbenv (shims, exec, and shell integration) #
The half of rbenv that actually runs
something: the shims it generates, the dispatch that makes ruby mean a
different program in a different directory without PATH ever changing,
rbenv exec, the hooks a plugin installs, and the shell integration
rbenv init writes into the user’s home.
The dispatch is the whole point of the tool, so it is asserted the way a
user meets it — by running ruby with the shim directory on PATH and
reading what came back, before and after the directory’s version changes.
rbenv init is asserted against a sandboxed home, which is what proves the
file it edits is the one it claims and that a second run edits nothing.
Source: test/e2e/thirdparty/rbenv/shims.atago.yaml
Scenario: rehash generates one shim per executable across every version #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Fixture file
root/versions/3.2.0/bin/gemis created. - Fixture file
root/versions/3.3.1/bin/rubyis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture root/versions/3.2.0/bin/gem:
#!/bin/sh
echo "gem 3.2.0"
Fixture root/versions/3.3.1/bin/ruby:
#!/bin/sh
echo "ruby 3.3.1"
When #
rbenv rehash
rbenv shims --short
Then #
- after
rbenv rehash:- exit code is
0 - the step changed exactly created
root/shims/ruby,root/shims/gem, modified nothing, deleted nothing - dir
root/shimshas 2 entries - file
root/shims/rubyis executable
- exit code is
- after
rbenv shims --short:- exit code is
0 - stdout equals an exact value
- exit code is
Expected output #
expected stdout:
gem
ruby
Scenario: the shim answers to the directory, with PATH never changing #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Fixture file
root/versions/3.3.1/bin/rubyis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT, RBENV_VERSION.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture root/versions/3.3.1/bin/ruby:
#!/bin/sh
echo "ruby 3.3.1"
When #
rbenv global 3.2.0
rbenv rehash
PATH="${workdir}/root/shims:$PATH" ruby
rbenv local 3.3.1
PATH="${workdir}/root/shims:$PATH" ruby
PATH="${workdir}/root/shims:$PATH" ruby
Then #
- after
rbenv global 3.2.0:- exit code is
0
- exit code is
- after
rbenv rehash:- exit code is
0
- exit code is
- after
PATH="${workdir}/root/shims:$PATH" ruby:- exit code is
0 - stdout equals an exact value
- exit code is
- after
rbenv local 3.3.1:- exit code is
0
- exit code is
- after
PATH="${workdir}/root/shims:$PATH" ruby:- exit code is
0 - stdout equals an exact value
- exit code is
- after
PATH="${workdir}/root/shims:$PATH" ruby:- exit code is
0 - stdout equals an exact value
- exit code is
Expected output #
expected stdout:
ruby 3.2.0
expected stdout:
ruby 3.3.1
expected stdout:
ruby 3.2.0
Scenario: a version added after the last rehash has no shim until the next one #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Fixture file
root/versions/3.3.1/bin/irbis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture root/versions/3.3.1/bin/irb:
#!/bin/sh
echo "irb 3.3.1"
When #
rbenv rehash
rbenv rehash
Then #
- after
rbenv rehash:- exit code is
0 - the step changed exactly created
root/shims/ruby, modified nothing, deleted nothing
- exit code is
- after
rbenv rehash:- exit code is
0 - the step changed exactly created
root/shims/irb, modified nothing, deleted nothing
- exit code is
Scenario: exec runs the selected version, and a command that is not there is 127 #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.3.1/bin/rubyis created. - Fixture file
.ruby-versionis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.3.1/bin/ruby:
#!/bin/sh
echo "ruby 3.3.1, argv: $*"
Fixture .ruby-version:
3.3.1
When #
rbenv exec ruby --flag argument
rbenv exec rake
rbenv which rake
Then #
- after
rbenv exec ruby --flag argument:- exit code is
0 - stdout equals an exact value
- exit code is
- after
rbenv exec rake:- exit code is
127 - stdout is empty
- stderr equals an exact value
- exit code is
- after
rbenv which rake:- exit code is
127 - stderr equals an exact value
- exit code is
Expected output #
expected stdout:
ruby 3.3.1, argv: --flag argument
expected stderr:
rbenv: rake: command not found
expected stderr:
rbenv: rake: command not found
Scenario: a hook script runs before exec and sees the resolved version #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Fixture file
.ruby-versionis created. - Fixture file
hooks/exec/record.bashis created. - Environment variables are set: RBENV_HOOK_PATH, RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_HOOK_PATH, RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
Fixture .ruby-version:
3.2.0
Fixture hooks/exec/record.bash:
echo "hook saw $RBENV_VERSION" >> "$RBENV_ROOT/hook.log"
When #
rbenv hooks exec
rbenv exec ruby
Then #
- after
rbenv hooks exec:- exit code is
0 - stdout matches
//hooks/exec/record\.bash/
- exit code is
- after
rbenv exec ruby:- exit code is
0 - stdout equals an exact value
- the step changed exactly created
root/hook.log, modified nothing, deleted nothing - file
root/hook.logequals exact bytes
- exit code is
Expected output #
expected stdout:
ruby 3.2.0
Scenario: shell integration is printed on request and refused without it #
only when rbenv --version succeeds · skipped on Windows
Given #
- Fixture file
root/versions/3.2.0/bin/rubyis created. - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
Inputs #
Fixture root/versions/3.2.0/bin/ruby:
#!/bin/sh
echo "ruby 3.2.0"
When #
rbenv shell 3.2.0
rbenv init - bash
Then #
- after
rbenv shell 3.2.0:- exit code is
1 - stdout is empty
- stderr equals an exact value
- exit code is
- after
rbenv init - bash:- exit code is
0 - stdout contains
export RBENV_SHELL=bash,command rbenv rehash 2>/dev/null,rbenv() {, matches/export PATH="[^"]*/root/shims:\$\{PATH\}"/
- exit code is
Expected output #
expected stderr:
rbenv: shell integration not enabled. Run `rbenv init' for instructions.
Scenario: init edits the profile in the home it was given, once #
only when rbenv --version succeeds · skipped on Windows
Given #
- Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected). - Environment variables are set: RBENV_ROOT.
- The command runs with an isolated home under
${workdir}/.atago-home(HOME/XDG or APPDATA redirected).
When #
rbenv init bash
rbenv init bash
Then #
- after
rbenv init bash:- exit code is
0 - stdout matches
/^writing ~/\.bash_profile: now configured for rbenv\.\n$/ - the step changed exactly created
.atago-home/.bash_profile, modified nothing, deleted nothing - file
.atago-home/.bash_profilecontainseval "$(rbenv init - --no-rehash bash)"
- exit code is
- after
rbenv init bash:- exit code is
0 - stdout matches
/^skipping ~/\.bash_profile: already configured for rbenv\.\n$/ - the step changed exactly created nothing, modified nothing, deleted nothing
- exit code is