pyenv verification source
Some checks are pending
macos_build / macos_build (3.10) (push) Waiting to run
macos_build / macos_build (3.11) (push) Waiting to run
macos_build / macos_build (3.12) (push) Waiting to run
macos_build / macos_build (3.13) (push) Waiting to run
macos_build / macos_build (3.14) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-14) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-15) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-15-intel) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-26) (push) Waiting to run
pyenv_tests / pyenv_tests (ubuntu-22.04) (push) Waiting to run
pyenv_tests / pyenv_tests (ubuntu-24.04) (push) Waiting to run
ubuntu_build / ubuntu_build (3.10) (push) Waiting to run
ubuntu_build / ubuntu_build (3.11) (push) Waiting to run
ubuntu_build / ubuntu_build (3.12) (push) Waiting to run
ubuntu_build / ubuntu_build (3.13) (push) Waiting to run
ubuntu_build / ubuntu_build (3.14) (push) Waiting to run
Some checks are pending
macos_build / macos_build (3.10) (push) Waiting to run
macos_build / macos_build (3.11) (push) Waiting to run
macos_build / macos_build (3.12) (push) Waiting to run
macos_build / macos_build (3.13) (push) Waiting to run
macos_build / macos_build (3.14) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-14) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-15) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-15-intel) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-26) (push) Waiting to run
pyenv_tests / pyenv_tests (ubuntu-22.04) (push) Waiting to run
pyenv_tests / pyenv_tests (ubuntu-24.04) (push) Waiting to run
ubuntu_build / ubuntu_build (3.10) (push) Waiting to run
ubuntu_build / ubuntu_build (3.11) (push) Waiting to run
ubuntu_build / ubuntu_build (3.12) (push) Waiting to run
ubuntu_build / ubuntu_build (3.13) (push) Waiting to run
ubuntu_build / ubuntu_build (3.14) (push) Waiting to run
This commit is contained in:
52
test/--version.bats
Normal file
52
test/--version.bats
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
_setup() {
|
||||
export GIT_DIR="${PYENV_TEST_DIR}"
|
||||
export GIT_WORK_TREE="$GIT_DIR"
|
||||
git init --quiet
|
||||
git config user.name "Tester"
|
||||
git config user.email "tester@test.local"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
git_commit() {
|
||||
git commit --quiet --allow-empty -m "empty"
|
||||
}
|
||||
|
||||
@test "default version" {
|
||||
assert [ ! -e "$PYENV_ROOT" ]
|
||||
run pyenv---version
|
||||
assert_success
|
||||
[[ $output == "pyenv "?.?.* ]]
|
||||
}
|
||||
|
||||
@test "doesn't read version from non-pyenv repo" {
|
||||
git remote add origin https://github.com/homebrew/homebrew.git
|
||||
git_commit
|
||||
git tag v1.0
|
||||
|
||||
run pyenv---version
|
||||
assert_success
|
||||
[[ $output == "pyenv "?.?.* ]]
|
||||
}
|
||||
|
||||
@test "reads version from git repo" {
|
||||
git remote add origin https://github.com/pyenv/pyenv.git
|
||||
git_commit
|
||||
git tag v0.4.1
|
||||
git_commit
|
||||
git_commit
|
||||
|
||||
run pyenv---version
|
||||
assert_success "pyenv 0.4.1-2-g$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
@test "prints default version if no tags in git repo" {
|
||||
git remote add origin https://github.com/pyenv/pyenv.git
|
||||
git_commit
|
||||
|
||||
run pyenv---version
|
||||
[[ $output == "pyenv "?.?.* ]]
|
||||
}
|
||||
25
test/Dockerfile
Normal file
25
test/Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
||||
ARG BASH
|
||||
|
||||
FROM alpine/git:v2.30.0 as bats
|
||||
ARG BATS_VERSION
|
||||
RUN git clone https://github.com/bats-core/bats-core.git /root/bats-core \
|
||||
&& cd /root/bats-core \
|
||||
&& git checkout "${BATS_VERSION}"
|
||||
|
||||
FROM bash:$BASH
|
||||
# Gnu tools
|
||||
RUN if [[ "${GNU:-}" == True ]];then \
|
||||
apk add sed coreutils findutils \
|
||||
;fi
|
||||
# Bats
|
||||
RUN apk add --update parallel ncurses git \
|
||||
&& mkdir -p ~/.parallel \
|
||||
&& touch ~/.parallel/will-cite
|
||||
COPY --from=bats /root/bats-core /root/bats-core
|
||||
RUN /root/bats-core/install.sh "/usr/local"
|
||||
# Clean
|
||||
RUN rm -rf /var/cache/apk/*
|
||||
# Setup
|
||||
RUN echo 'source /etc/profile' >> ~/.bashrc
|
||||
WORKDIR /code/
|
||||
CMD ["bash"]
|
||||
76
test/README.md
Normal file
76
test/README.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# TEST
|
||||
|
||||
---
|
||||
|
||||
## Running test suite
|
||||
|
||||
Test suite could be launch with `make` by providing the right target depending what you want to achieve.
|
||||
|
||||
Under the hood, `pyenv` test suites use `bats` as a test framework and are run on the host or docker depending of the target provided to make.
|
||||
|
||||
|
||||
|
||||
### Targets
|
||||
|
||||
- `test`
|
||||
- Run the whole test suite on the local host
|
||||
- `test-docker`
|
||||
- Run the whole test suite on docker
|
||||
- Some volumes are used in read-only mode
|
||||
- `test-unit`
|
||||
- Run the unit test
|
||||
- `test-plugin`
|
||||
- Run the plugin test
|
||||
- `test-unit-docker-[BASH_VERSION]`
|
||||
- Run the unit test under **official** bash docker container (alpine/busybox) with the specified bash version if present is in the `Makefile`
|
||||
- Some volumes are used in read-only mode
|
||||
- `test-unit-docker-gnu-[BASH_VERSION]`
|
||||
- Run the unit test under **official** bash docker container (alpine/busybox), completed by **GNU Tools**, with the specified bash version if present is in the `Makefile`
|
||||
- Some volumes are used in read-only mode
|
||||
- `test-plugin-docker-[BASH_VERSION]`
|
||||
- Run the plugin test under **official** bash docker container (alpine/busybox), completed by **GNU Tools**, with the specified bash version if present is in the `Makefile`
|
||||
- Some volumes are used in read-only mode
|
||||
- `test-plugin-docker-gnu-[BASH_VERSION]`
|
||||
- Run the plugin test under **official** bash docker container (alpine/busybox), completed by **GNU Tools**, with the specified bash version if present is in the `Makefile`
|
||||
- Some volumes are used in read-only mode
|
||||
|
||||
## Targeting specific test / test file
|
||||
|
||||
By setting some environment variables, it is possible to filtering which test and/or test file who will be tested with bats
|
||||
|
||||
- `BATS_FILE_FILTER`
|
||||
|
||||
- Run test only with the specified file
|
||||
|
||||
- `BATS_TEST_FILTER`
|
||||
- Run test only who corresponding to the filter provided
|
||||
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
$ BATS_TEST_FILTER=".*installed.*" BATS_FILE_FILTER="build.bats" make test-plugin-docker-gnu-3.2.57
|
||||
build.bats
|
||||
✓ yaml is installed for python
|
||||
✓ homebrew is used in Linux if Pyenv is installed with Homebrew
|
||||
✓ homebrew is not used in Linux if Pyenv is not installed with Homebrew
|
||||
|
||||
3 tests, 0 failures
|
||||
|
||||
$ BATS_TEST_FILTER=".*installed.*" BATS_FILE_FILTER="build.bats" make test-plugin
|
||||
build.bats
|
||||
✓ yaml is installed for python
|
||||
✓ homebrew is used in Linux if Pyenv is installed with Homebrew
|
||||
✓ homebrew is not used in Linux if Pyenv is not installed with Homebrew
|
||||
|
||||
3 tests, 0 failures
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Writing test
|
||||
|
||||
To be reproducible, each test use/should use its own `TMPDIR` .
|
||||
It's achieved by using the environment variable `BATS_TEST_TMPDIR` provided by bats that is automatically deleted at the end of each test. More info [here](https://bats-core.readthedocs.io/en/stable/writing-tests.html#special-variables)
|
||||
|
||||
Another variable who could be used to source some file who need to be tested is `BATS_TEST_DIRNAME` who point to the directory in which the bats test file is located.
|
||||
39
test/commands.bats
Normal file
39
test/commands.bats
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "commands" {
|
||||
run pyenv-commands
|
||||
assert_success
|
||||
assert_line "init"
|
||||
assert_line "rehash"
|
||||
assert_line "shell"
|
||||
refute_line "sh-shell"
|
||||
assert_line "echo"
|
||||
}
|
||||
|
||||
@test "commands --sh" {
|
||||
run pyenv-commands --sh
|
||||
assert_success
|
||||
refute_line "init"
|
||||
assert_line "shell"
|
||||
}
|
||||
|
||||
@test "commands in path with spaces" {
|
||||
path="${PYENV_TEST_DIR}/my commands"
|
||||
cmd="${path}/pyenv-sh-hello"
|
||||
mkdir -p "$path"
|
||||
touch "$cmd"
|
||||
chmod +x "$cmd"
|
||||
|
||||
PATH="${path}:$PATH" run pyenv-commands --sh
|
||||
assert_success
|
||||
assert_line "hello"
|
||||
}
|
||||
|
||||
@test "commands --no-sh" {
|
||||
run pyenv-commands --no-sh
|
||||
assert_success
|
||||
assert_line "init"
|
||||
refute_line "shell"
|
||||
}
|
||||
51
test/completions.bats
Normal file
51
test/completions.bats
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
create_command() {
|
||||
bin="${PYENV_TEST_DIR}/bin"
|
||||
mkdir -p "$bin"
|
||||
echo "$2" > "${bin}/$1"
|
||||
chmod +x "${bin}/$1"
|
||||
}
|
||||
|
||||
@test "command with no completion support" {
|
||||
create_command "pyenv-hello" "#!$BASH
|
||||
echo hello"
|
||||
run pyenv-completions hello
|
||||
assert_success "--help"
|
||||
}
|
||||
|
||||
@test "command with completion support" {
|
||||
create_command "pyenv-hello" "#!$BASH
|
||||
# Provide pyenv completions
|
||||
if [[ \$1 = --complete ]]; then
|
||||
echo hello
|
||||
else
|
||||
exit 1
|
||||
fi"
|
||||
run pyenv-completions hello
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
--help
|
||||
hello
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "forwards extra arguments" {
|
||||
create_command "pyenv-hello" "#!$BASH
|
||||
# provide pyenv completions
|
||||
if [[ \$1 = --complete ]]; then
|
||||
shift 1
|
||||
for arg; do echo \$arg; done
|
||||
else
|
||||
exit 1
|
||||
fi"
|
||||
run pyenv-completions hello happy world
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
--help
|
||||
happy
|
||||
world
|
||||
OUT
|
||||
}
|
||||
141
test/exec.bats
Normal file
141
test/exec.bats
Normal file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "fails with invalid version" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
export PYENV_VERSION="3.4"
|
||||
run -127 pyenv-exec nonexistent
|
||||
assert_failure <<EOF
|
||||
pyenv: version \`3.4' is not installed (set by PYENV_VERSION environment variable)
|
||||
pyenv: nonexistent: command not found
|
||||
EOF
|
||||
}
|
||||
|
||||
@test "fails with invalid version set from file" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
mkdir -p "$PYENV_TEST_DIR"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
echo 2.7 > .python-version
|
||||
run -127 pyenv-exec nonexistent
|
||||
assert_failure <<EOF
|
||||
pyenv: version \`2.7' is not installed (set by $PWD/.python-version)
|
||||
pyenv: nonexistent: command not found
|
||||
EOF
|
||||
}
|
||||
|
||||
@test "completes with names of executables" {
|
||||
export PYENV_VERSION="3.4"
|
||||
create_alt_executable "fab"
|
||||
create_alt_executable "python"
|
||||
|
||||
pyenv-rehash
|
||||
run pyenv-completions exec
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
--help
|
||||
fab
|
||||
python
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "carries original IFS within hooks" {
|
||||
create_hook exec hello.bash <<SH
|
||||
hellos=(\$(printf "hello\\tugly world\\nagain"))
|
||||
echo HELLO="\$(printf ":%s" "\${hellos[@]}")"
|
||||
SH
|
||||
|
||||
export PYENV_VERSION=system
|
||||
IFS=$' \t\n' run pyenv-exec env
|
||||
assert_success
|
||||
assert_line "HELLO=:hello:ugly:world:again"
|
||||
}
|
||||
|
||||
@test "forwards all arguments" {
|
||||
export PYENV_VERSION="3.4"
|
||||
create_alt_executable "python" <<SH
|
||||
#!$BASH
|
||||
echo \$0
|
||||
for arg; do
|
||||
# hack to avoid bash builtin echo which can't output '-e'
|
||||
printf " %s\\n" "\$arg"
|
||||
done
|
||||
SH
|
||||
|
||||
run pyenv-exec python -w "/path to/python script.rb" -- extra args
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
${PYENV_ROOT}/versions/3.4/bin/python
|
||||
-w
|
||||
/path to/python script.rb
|
||||
--
|
||||
extra
|
||||
args
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "sys.executable with system version (#98)" {
|
||||
create_path_executable "python3" "echo system"
|
||||
|
||||
system_python="$(python3 </dev/null)"
|
||||
assert_equal "${system_python}" "system"
|
||||
|
||||
export PYENV_VERSION="custom"
|
||||
create_alt_executable "python3" "echo custom"
|
||||
|
||||
pyenv-rehash
|
||||
|
||||
custom_python="$(pyenv-exec python3)"
|
||||
assert_equal "${custom_python}" "custom"
|
||||
}
|
||||
|
||||
@test 'PATH is not modified with system Python' {
|
||||
# Create a wrapper executable that verifies PATH.
|
||||
create_alt_executable_in_version "custom" "python3" <<!
|
||||
[[ \$PATH == "\${PYENV_ROOT}/versions/custom/bin:"* ]] \
|
||||
|| { echo "unexpected:\$PATH"; exit 2;}
|
||||
!
|
||||
pyenv-rehash
|
||||
|
||||
# Path is not modified with system Python.
|
||||
create_path_executable "python3" "echo \$PATH"
|
||||
|
||||
pyenv-rehash
|
||||
run pyenv-exec python3
|
||||
assert_success "$PATH"
|
||||
|
||||
# Path is modified with custom Python.
|
||||
PYENV_VERSION=custom run pyenv-exec python3
|
||||
assert_success
|
||||
|
||||
# Path is modified with custom:system Python.
|
||||
PYENV_VERSION=custom:system run pyenv-exec python3
|
||||
assert_success
|
||||
|
||||
# Path is not modified with system:custom Python.
|
||||
PYENV_VERSION=system:custom run pyenv-exec python3
|
||||
assert_success "$PATH"
|
||||
}
|
||||
|
||||
@test "sets/adds to _PYENV_SHIM_PATHS_{PROGRAM} when _PYENV_SHIM_PATH is set, unsets _PYENV_SHIM_PATH" {
|
||||
progname='123;wacky-prog.name ^%$#'
|
||||
envvarname="_PYENV_SHIM_PATHS_123_WACKY_PROG_NAME_____"
|
||||
create_path_executable "$progname" <<!
|
||||
echo $envvarname="\$$envvarname"
|
||||
echo _PYENV_SHIM_PATH="\$_PYENV_SHIM_PATH"
|
||||
!
|
||||
_PYENV_SHIM_PATH=/unusual/shim/location run pyenv-exec "$progname"
|
||||
assert_success
|
||||
assert_output <<!
|
||||
$envvarname=/unusual/shim/location
|
||||
_PYENV_SHIM_PATH=
|
||||
!
|
||||
|
||||
eval "export ${envvarname}=/another/shim/location"
|
||||
_PYENV_SHIM_PATH=/unusual/shim/location run pyenv-exec "$progname"
|
||||
assert_success
|
||||
assert_output <<!
|
||||
$envvarname=/unusual/shim/location:/another/shim/location
|
||||
_PYENV_SHIM_PATH=
|
||||
!
|
||||
}
|
||||
31
test/global.bats
Normal file
31
test/global.bats
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "default" {
|
||||
run pyenv-global
|
||||
assert_success
|
||||
assert_output "system"
|
||||
}
|
||||
|
||||
@test "read PYENV_ROOT/version" {
|
||||
mkdir -p "$PYENV_ROOT"
|
||||
echo "1.2.3" > "$PYENV_ROOT/version"
|
||||
run pyenv-global
|
||||
assert_success
|
||||
assert_output "1.2.3"
|
||||
}
|
||||
|
||||
@test "set PYENV_ROOT/version" {
|
||||
mkdir -p "$PYENV_ROOT/versions/1.2.3"
|
||||
run pyenv-global "1.2.3"
|
||||
assert_success
|
||||
run pyenv-global
|
||||
assert_success "1.2.3"
|
||||
}
|
||||
|
||||
@test "fail setting invalid PYENV_ROOT/version" {
|
||||
mkdir -p "$PYENV_ROOT"
|
||||
run pyenv-global "1.2.3"
|
||||
assert_failure "pyenv: version \`1.2.3' not installed"
|
||||
}
|
||||
115
test/help.bats
Normal file
115
test/help.bats
Normal file
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "without args shows summary of common commands" {
|
||||
run pyenv-help
|
||||
assert_success
|
||||
assert_line "Usage: pyenv <command> [<args>]"
|
||||
assert_line "Some useful pyenv commands are:"
|
||||
}
|
||||
|
||||
@test "invalid command" {
|
||||
run pyenv-help hello
|
||||
assert_failure "pyenv: no such command \`hello'"
|
||||
}
|
||||
|
||||
@test "shows help for a specific command" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/bin"
|
||||
cat > "${PYENV_TEST_DIR}/bin/pyenv-hello" <<SH
|
||||
#!shebang
|
||||
# Usage: pyenv hello <world>
|
||||
# Summary: Says "hello" to you, from pyenv
|
||||
# This command is useful for saying hello.
|
||||
echo hello
|
||||
SH
|
||||
|
||||
run pyenv-help hello
|
||||
assert_success
|
||||
assert_output <<SH
|
||||
Usage: pyenv hello <world>
|
||||
|
||||
This command is useful for saying hello.
|
||||
SH
|
||||
}
|
||||
|
||||
@test "replaces missing extended help with summary text" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/bin"
|
||||
cat > "${PYENV_TEST_DIR}/bin/pyenv-hello" <<SH
|
||||
#!shebang
|
||||
# Usage: pyenv hello <world>
|
||||
# Summary: Says "hello" to you, from pyenv
|
||||
echo hello
|
||||
SH
|
||||
|
||||
run pyenv-help hello
|
||||
assert_success
|
||||
assert_output <<SH
|
||||
Usage: pyenv hello <world>
|
||||
|
||||
Says "hello" to you, from pyenv
|
||||
SH
|
||||
}
|
||||
|
||||
@test "extracts only usage" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/bin"
|
||||
cat > "${PYENV_TEST_DIR}/bin/pyenv-hello" <<SH
|
||||
#!shebang
|
||||
# Usage: pyenv hello <world>
|
||||
# Summary: Says "hello" to you, from pyenv
|
||||
# This extended help won't be shown.
|
||||
echo hello
|
||||
SH
|
||||
|
||||
run pyenv-help --usage hello
|
||||
assert_success "Usage: pyenv hello <world>"
|
||||
}
|
||||
|
||||
@test "multiline usage section" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/bin"
|
||||
cat > "${PYENV_TEST_DIR}/bin/pyenv-hello" <<SH
|
||||
#!shebang
|
||||
# Usage: pyenv hello <world>
|
||||
# pyenv hi [everybody]
|
||||
# pyenv hola --translate
|
||||
# Summary: Says "hello" to you, from pyenv
|
||||
# Help text.
|
||||
echo hello
|
||||
SH
|
||||
|
||||
run pyenv-help hello
|
||||
assert_success
|
||||
assert_output <<SH
|
||||
Usage: pyenv hello <world>
|
||||
pyenv hi [everybody]
|
||||
pyenv hola --translate
|
||||
|
||||
Help text.
|
||||
SH
|
||||
}
|
||||
|
||||
@test "multiline extended help section" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/bin"
|
||||
cat > "${PYENV_TEST_DIR}/bin/pyenv-hello" <<SH
|
||||
#!shebang
|
||||
# Usage: pyenv hello <world>
|
||||
# Summary: Says "hello" to you, from pyenv
|
||||
# This is extended help text.
|
||||
# It can contain multiple lines.
|
||||
#
|
||||
# And paragraphs.
|
||||
|
||||
echo hello
|
||||
SH
|
||||
|
||||
run pyenv-help hello
|
||||
assert_success
|
||||
assert_output <<SH
|
||||
Usage: pyenv hello <world>
|
||||
|
||||
This is extended help text.
|
||||
It can contain multiple lines.
|
||||
|
||||
And paragraphs.
|
||||
SH
|
||||
}
|
||||
70
test/hooks.bats
Normal file
70
test/hooks.bats
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "prints usage help given no argument" {
|
||||
run pyenv-hooks
|
||||
assert_failure "Usage: pyenv hooks <command>"
|
||||
}
|
||||
|
||||
@test "prints list of hooks" {
|
||||
path1="${PYENV_TEST_DIR}/pyenv.d"
|
||||
path2="${PYENV_TEST_DIR}/etc/pyenv_hooks"
|
||||
PYENV_HOOK_PATH="$path1"
|
||||
create_hook exec "hello.bash"
|
||||
create_hook exec "ahoy.bash"
|
||||
create_hook exec "invalid.sh"
|
||||
create_hook which "boom.bash"
|
||||
PYENV_HOOK_PATH="$path2"
|
||||
create_hook exec "bueno.bash"
|
||||
|
||||
PYENV_HOOK_PATH="$path1:$path2" run pyenv-hooks exec
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
${PYENV_TEST_DIR}/pyenv.d/exec/ahoy.bash
|
||||
${PYENV_TEST_DIR}/pyenv.d/exec/hello.bash
|
||||
${PYENV_TEST_DIR}/etc/pyenv_hooks/exec/bueno.bash
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "supports hook paths with spaces" {
|
||||
path1="${PYENV_TEST_DIR}/my hooks/pyenv.d"
|
||||
path2="${PYENV_TEST_DIR}/etc/pyenv hooks"
|
||||
PYENV_HOOK_PATH="$path1"
|
||||
create_hook exec "hello.bash"
|
||||
PYENV_HOOK_PATH="$path2"
|
||||
create_hook exec "ahoy.bash"
|
||||
|
||||
PYENV_HOOK_PATH="$path1:$path2" run pyenv-hooks exec
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
${PYENV_TEST_DIR}/my hooks/pyenv.d/exec/hello.bash
|
||||
${PYENV_TEST_DIR}/etc/pyenv hooks/exec/ahoy.bash
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "resolves relative paths" {
|
||||
PYENV_HOOK_PATH="${PYENV_TEST_DIR}/pyenv.d"
|
||||
create_hook exec "hello.bash"
|
||||
mkdir -p "$HOME"
|
||||
|
||||
PYENV_HOOK_PATH="${HOME}/../pyenv.d" run pyenv-hooks exec
|
||||
assert_success "${PYENV_TEST_DIR}/pyenv.d/exec/hello.bash"
|
||||
}
|
||||
|
||||
@test "resolves symlinks" {
|
||||
path="${PYENV_TEST_DIR}/pyenv.d"
|
||||
mkdir -p "${path}/exec"
|
||||
mkdir -p "$HOME"
|
||||
touch "${HOME}/hola.bash"
|
||||
ln -s "../../home/hola.bash" "${path}/exec/hello.bash"
|
||||
touch "${path}/exec/bright.sh"
|
||||
ln -s "bright.sh" "${path}/exec/world.bash"
|
||||
|
||||
PYENV_HOOK_PATH="$path" run pyenv-hooks exec
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
${HOME}/hola.bash
|
||||
${PYENV_TEST_DIR}/pyenv.d/exec/bright.sh
|
||||
OUT
|
||||
}
|
||||
254
test/init.bats
Executable file
254
test/init.bats
Executable file
@@ -0,0 +1,254 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "creates shims and versions directories" {
|
||||
assert [ ! -d "${PYENV_ROOT}/shims" ]
|
||||
assert [ ! -d "${PYENV_ROOT}/versions" ]
|
||||
run pyenv-init -
|
||||
assert_success
|
||||
assert [ -d "${PYENV_ROOT}/shims" ]
|
||||
assert [ -d "${PYENV_ROOT}/versions" ]
|
||||
}
|
||||
|
||||
@test "auto rehash" {
|
||||
run pyenv-init -
|
||||
assert_success
|
||||
assert_line "command pyenv rehash"
|
||||
}
|
||||
|
||||
@test "auto rehash for --path" {
|
||||
run pyenv-init --path
|
||||
assert_success
|
||||
assert_line "command pyenv rehash"
|
||||
}
|
||||
|
||||
@test "setup shell completions" {
|
||||
run pyenv-init - bash
|
||||
assert_success
|
||||
assert_line "source '${_PYENV_INSTALL_PREFIX}/completions/pyenv.bash'"
|
||||
}
|
||||
|
||||
@test "detect parent shell" {
|
||||
SHELL=/bin/false run pyenv-init -
|
||||
assert_success
|
||||
assert_line "export PYENV_SHELL=bash"
|
||||
}
|
||||
|
||||
@test "detect parent shell from script" {
|
||||
mkdir -p "$PYENV_TEST_DIR"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
cat > myscript.sh <<OUT
|
||||
#!/bin/sh
|
||||
eval "\$(pyenv-init -)"
|
||||
echo \$PYENV_SHELL
|
||||
OUT
|
||||
chmod +x myscript.sh
|
||||
run ./myscript.sh
|
||||
assert_success "sh"
|
||||
}
|
||||
|
||||
@test "setup shell completions (fish)" {
|
||||
run pyenv-init - fish
|
||||
assert_success
|
||||
assert_line "source '${_PYENV_INSTALL_PREFIX}/completions/pyenv.fish'"
|
||||
}
|
||||
|
||||
@test "fish instructions" {
|
||||
run pyenv-init fish
|
||||
assert [ "$status" -eq 1 ]
|
||||
assert_line 'pyenv init - fish | source'
|
||||
}
|
||||
|
||||
@test "setup shell completions (pwsh)" {
|
||||
root="$(cd $BATS_TEST_DIRNAME/.. && pwd)"
|
||||
run pyenv-init - pwsh
|
||||
assert_success
|
||||
assert_line "iex (gc ${root}/completions/pyenv.pwsh -Raw)"
|
||||
}
|
||||
|
||||
@test "pwsh instructions" {
|
||||
run pyenv-init pwsh
|
||||
assert [ "$status" -eq 1 ]
|
||||
assert_line 'iex ((pyenv init -) -join "`n")'
|
||||
}
|
||||
|
||||
@test "shell detection for installer" {
|
||||
run pyenv-init --detect-shell
|
||||
assert_success
|
||||
assert_line "PYENV_SHELL_DETECT=bash"
|
||||
}
|
||||
|
||||
@test "option to skip rehash" {
|
||||
run pyenv-init - --no-rehash
|
||||
assert_success
|
||||
refute_line "pyenv rehash 2>/dev/null"
|
||||
}
|
||||
|
||||
@test "adds shims to PATH" {
|
||||
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
|
||||
run pyenv-init - bash
|
||||
assert_success
|
||||
assert_line 'export PATH="'${PYENV_ROOT}'/shims:${PATH}"'
|
||||
}
|
||||
|
||||
@test "adds shims to PATH (fish)" {
|
||||
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
|
||||
run pyenv-init - fish
|
||||
assert_success
|
||||
assert_line "set -gx PATH '${PYENV_ROOT}/shims' \$PATH"
|
||||
}
|
||||
|
||||
@test "adds shims to PATH (pwsh)" {
|
||||
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
|
||||
run pyenv-init - pwsh
|
||||
assert_success
|
||||
assert_line '$Env:PATH="'${PYENV_ROOT}'/shims:$Env:PATH"'
|
||||
}
|
||||
|
||||
@test "removes existing shims from PATH" {
|
||||
OLDPATH="$PATH"
|
||||
export PATH="${BATS_TEST_DIRNAME}/nonexistent:${PYENV_ROOT}/shims:$PATH"
|
||||
run bash -e <<!
|
||||
eval "\$(pyenv-init -)"
|
||||
echo "\$PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PYENV_ROOT}/shims:${BATS_TEST_DIRNAME}/nonexistent:${OLDPATH//${PYENV_ROOT}\/shims:/}"
|
||||
}
|
||||
|
||||
@test "removes existing shims from PATH (fish)" {
|
||||
command -v fish >/dev/null || skip "-- fish not installed"
|
||||
OLDPATH="$PATH"
|
||||
export PATH="${BATS_TEST_DIRNAME}/nonexistent:${PYENV_ROOT}/shims:$PATH"
|
||||
run fish <<!
|
||||
set -x PATH "$PATH"
|
||||
pyenv init - | source
|
||||
echo "\$PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PYENV_ROOT}/shims:${BATS_TEST_DIRNAME}/nonexistent:${OLDPATH//${PYENV_ROOT}\/shims:/}"
|
||||
}
|
||||
|
||||
@test "removes existing shims from PATH (pwsh)" {
|
||||
command -v pwsh >/dev/null || skip "-- pwsh not installed"
|
||||
OLDPATH="$PATH"
|
||||
export PATH="${BATS_TEST_DIRNAME}/nonexistent:${PYENV_ROOT}/shims:$PATH"
|
||||
run pwsh -noni -c - <<!
|
||||
\$Env:PATH="$PATH"
|
||||
iex ((pyenv init -) -join "\`n")
|
||||
echo "\$Env:PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PYENV_ROOT}/shims:${BATS_TEST_DIRNAME}/nonexistent:${OLDPATH//${PYENV_ROOT}\/shims:/}"
|
||||
}
|
||||
|
||||
@test "adds shims to PATH with --no-push-path if they're not on PATH" {
|
||||
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
|
||||
run bash -e <<!
|
||||
eval "\$(pyenv-init - --no-push-path)"
|
||||
echo "\$PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PYENV_ROOT}/shims:${PATH}"
|
||||
}
|
||||
|
||||
@test "adds shims to PATH with --no-push-path if they're not on PATH (fish)" {
|
||||
command -v fish >/dev/null || skip "-- fish not installed"
|
||||
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
|
||||
run fish <<!
|
||||
set -x PATH "$PATH"
|
||||
pyenv-init - --no-push-path| source
|
||||
echo "\$PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PYENV_ROOT}/shims:${PATH}"
|
||||
}
|
||||
|
||||
@test "adds shims to PATH with --no-push-path if they're not on PATH (pwsh)" {
|
||||
command -v pwsh >/dev/null || skip "-- pwsh not installed"
|
||||
PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
|
||||
run pwsh -nop -c - <<!
|
||||
#Powershell silently prepends its own PATH entry upon start
|
||||
\$Env:PATH="$PATH"
|
||||
iex ((pyenv init - --no-push-path) -join "\`n")
|
||||
echo "\$Env:PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PYENV_ROOT}/shims:${PATH}"
|
||||
}
|
||||
|
||||
@test "doesn't change PATH with --no-push-path if shims are already on PATH" {
|
||||
export PATH="${BATS_TEST_DIRNAME}/../libexec:${PYENV_ROOT}/shims:/usr/bin:/bin:/usr/local/bin"
|
||||
run bash -e <<!
|
||||
eval "\$(pyenv-init - --no-push-path)"
|
||||
echo "\$PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PATH}"
|
||||
}
|
||||
|
||||
@test "doesn't change PATH with --no-push-path if shims are already on PATH (fish)" {
|
||||
command -v fish >/dev/null || skip "-- fish not installed"
|
||||
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:${PYENV_ROOT}/shims:/bin:/usr/local/bin"
|
||||
run fish <<!
|
||||
set -x PATH "$PATH"
|
||||
pyenv-init - --no-push-path| source
|
||||
echo "\$PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PATH}"
|
||||
}
|
||||
|
||||
@test "doesn't change PATH with --no-push-path if shims are already on PATH (pwsh)" {
|
||||
command -v pwsh >/dev/null || skip "-- pwsh not installed"
|
||||
PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:${PYENV_ROOT}/shims:/bin:/usr/local/bin"
|
||||
run pwsh -nop -c - <<!
|
||||
#Powershell silently prepends its own PATH entry upon start
|
||||
\$Env:PATH="$PATH"
|
||||
iex ((pyenv init - --no-push-path) -join "\`n")
|
||||
echo "\$Env:PATH"
|
||||
!
|
||||
assert_success
|
||||
assert_output "${PATH}"
|
||||
}
|
||||
|
||||
@test "outputs sh-compatible syntax" {
|
||||
run pyenv-init - bash
|
||||
assert_success
|
||||
assert_line ' case "$command" in'
|
||||
|
||||
run pyenv-init - zsh
|
||||
assert_success
|
||||
assert_line ' case "$command" in'
|
||||
}
|
||||
|
||||
@test "outputs sh-compatible case syntax" {
|
||||
create_stub pyenv-commands <<!
|
||||
echo -e 'activate\ndeactivate\nrehash\nshell'
|
||||
!
|
||||
run pyenv-init - bash
|
||||
assert_success
|
||||
assert_line ' activate|deactivate|rehash|shell)'
|
||||
|
||||
create_stub pyenv-commands <<!
|
||||
echo
|
||||
!
|
||||
run pyenv-init - bash
|
||||
assert_success
|
||||
assert_line ' /)'
|
||||
}
|
||||
|
||||
@test "outputs fish-specific syntax (fish)" {
|
||||
run pyenv-init - fish
|
||||
assert_success
|
||||
assert_line ' switch "$command"'
|
||||
refute_line ' case "$command" in'
|
||||
}
|
||||
|
||||
@test "outputs pwsh-specific syntax (pwsh)" {
|
||||
run pyenv-init - pwsh
|
||||
assert_success
|
||||
refute_line ' switch "$command"'
|
||||
refute_line ' case "$command" in'
|
||||
}
|
||||
130
test/latest.bats
Normal file
130
test/latest.bats
Normal file
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "read from installed" {
|
||||
create_stub pyenv-versions <<!
|
||||
echo 4.5.6
|
||||
!
|
||||
run pyenv-latest 4
|
||||
assert_success
|
||||
assert_output <<!
|
||||
4.5.6
|
||||
!
|
||||
}
|
||||
|
||||
@test "read from known" {
|
||||
create_stub python-build <<!
|
||||
echo 4.5.6
|
||||
!
|
||||
run pyenv-latest -k 4
|
||||
assert_success
|
||||
assert_output <<!
|
||||
4.5.6
|
||||
!
|
||||
}
|
||||
|
||||
@test "installed version not found" {
|
||||
create_stub pyenv-versions <<!
|
||||
echo 3.5.6
|
||||
echo 3.10.8
|
||||
!
|
||||
run pyenv-latest 3.8
|
||||
assert_failure
|
||||
assert_output <<!
|
||||
pyenv: no installed versions match the prefix \`3.8'
|
||||
!
|
||||
}
|
||||
|
||||
@test "known version not found" {
|
||||
create_stub python-build <<!
|
||||
echo 3.5.6
|
||||
echo 3.10.8
|
||||
!
|
||||
run pyenv-latest -k 3.8
|
||||
assert_failure
|
||||
assert_output <<!
|
||||
pyenv: no known versions match the prefix \`3.8'
|
||||
!
|
||||
}
|
||||
|
||||
@test "complete name resolves to itself" {
|
||||
create_stub pyenv-versions <<!
|
||||
echo foo
|
||||
echo foo.bar
|
||||
!
|
||||
|
||||
run pyenv-latest foo
|
||||
assert_success
|
||||
assert_output <<!
|
||||
foo
|
||||
!
|
||||
|
||||
}
|
||||
|
||||
@test "sort CPython" {
|
||||
create_stub pyenv-versions <<!
|
||||
echo 2.7.18
|
||||
echo 3.5.6
|
||||
echo 3.10.8
|
||||
echo 3.10.6
|
||||
!
|
||||
run pyenv-latest 3
|
||||
assert_success
|
||||
assert_output <<!
|
||||
3.10.8
|
||||
!
|
||||
}
|
||||
|
||||
@test "ignores rolling releases, branch tips, alternative srcs, prereleases, virtualenvs; 't' versions if prefix without 't'" {
|
||||
create_stub pyenv-versions <<!
|
||||
echo 3.8.5-dev
|
||||
echo 3.8.5-src
|
||||
echo 3.8.5-latest
|
||||
echo 3.8.5a2
|
||||
echo 3.8.5b3
|
||||
echo 3.8.5rc2
|
||||
echo 3.8.5t
|
||||
echo 3.8.5b3t
|
||||
echo 3.8.5rc2t
|
||||
echo 3.8.1
|
||||
echo 3.8.1/envs/foo
|
||||
!
|
||||
run pyenv-latest 3.8
|
||||
assert_success
|
||||
assert_output <<!
|
||||
3.8.1
|
||||
!
|
||||
}
|
||||
|
||||
@test "resolves to a 't' version if prefix has 't'" {
|
||||
create_stub pyenv-versions <<!
|
||||
echo 3.13.2t
|
||||
echo 3.13.5
|
||||
echo 3.13.5t
|
||||
echo 3.14.6
|
||||
!
|
||||
run pyenv-latest 3t
|
||||
assert_success
|
||||
assert_output <<!
|
||||
3.13.5t
|
||||
!
|
||||
}
|
||||
|
||||
@test "falls back to argument with -b" {
|
||||
create_stub pyenv-versions
|
||||
run pyenv-latest -b nonexistent
|
||||
assert_failure
|
||||
assert_output <<!
|
||||
nonexistent
|
||||
!
|
||||
}
|
||||
|
||||
@test "falls back to argument and succeeds with -f" {
|
||||
create_stub pyenv-versions
|
||||
run pyenv-latest -f nonexistent
|
||||
assert_success
|
||||
assert_output <<!
|
||||
nonexistent
|
||||
!
|
||||
}
|
||||
9
test/libexec/pyenv-echo
Executable file
9
test/libexec/pyenv-echo
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
# Usage: pyenv echo [-F<char>] VAR
|
||||
|
||||
if [[ $1 == -F* ]]; then
|
||||
sep="${1:2}"
|
||||
echo "${!2}" | tr "${sep:-:}" $'\n'
|
||||
else
|
||||
echo "${!1}"
|
||||
fi
|
||||
71
test/local.bats
Normal file
71
test/local.bats
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
_setup() {
|
||||
mkdir -p "${PYENV_TEST_DIR}/myproject"
|
||||
cd "${PYENV_TEST_DIR}/myproject"
|
||||
}
|
||||
|
||||
@test "no version" {
|
||||
assert [ ! -e "${PWD}/.python-version" ]
|
||||
run pyenv-local
|
||||
assert_failure "pyenv: no local version configured for this directory"
|
||||
}
|
||||
|
||||
@test "local version" {
|
||||
echo "1.2.3" > .python-version
|
||||
run pyenv-local
|
||||
assert_success "1.2.3"
|
||||
}
|
||||
|
||||
@test "discovers version file in parent directory" {
|
||||
echo "1.2.3" > .python-version
|
||||
mkdir -p "subdir" && cd "subdir"
|
||||
run pyenv-local
|
||||
assert_success "1.2.3"
|
||||
}
|
||||
|
||||
@test "ignores PYENV_DIR" {
|
||||
echo "1.2.3" > .python-version
|
||||
mkdir -p "$HOME"
|
||||
echo "3.4-home" > "${HOME}/.python-version"
|
||||
PYENV_DIR="$HOME" run pyenv-local
|
||||
assert_success "1.2.3"
|
||||
}
|
||||
|
||||
@test "sets local version" {
|
||||
mkdir -p "${PYENV_ROOT}/versions/1.2.3"
|
||||
run pyenv-local 1.2.3
|
||||
assert_success ""
|
||||
assert [ "$(cat .python-version)" = "1.2.3" ]
|
||||
}
|
||||
|
||||
@test "fails to set a nonexistent local version" {
|
||||
run pyenv-local 1.2.3
|
||||
assert_failure "pyenv: version \`1.2.3' not installed"
|
||||
assert [ ! -e .python-version ]
|
||||
}
|
||||
|
||||
@test "sets a nonexistent local version with --force" {
|
||||
run pyenv-local -f 1.2.3
|
||||
assert_success ""
|
||||
assert [ "$(cat .python-version)" = "1.2.3" ]
|
||||
}
|
||||
|
||||
@test "changes local version" {
|
||||
echo "1.0-pre" > .python-version
|
||||
mkdir -p "${PYENV_ROOT}/versions/1.2.3"
|
||||
run pyenv-local
|
||||
assert_success "1.0-pre"
|
||||
run pyenv-local 1.2.3
|
||||
assert_success ""
|
||||
assert [ "$(cat .python-version)" = "1.2.3" ]
|
||||
}
|
||||
|
||||
@test "unsets local version" {
|
||||
touch .python-version
|
||||
run pyenv-local --unset
|
||||
assert_success ""
|
||||
assert [ ! -e .python-version ]
|
||||
}
|
||||
60
test/pip-rehash.bats
Executable file
60
test/pip-rehash.bats
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
copy_src_pyenvd() {
|
||||
mkdir -p "${PYENV_ROOT}"
|
||||
cp -r "${BATS_TEST_DIRNAME}/../pyenv.d" "${PYENV_ROOT}"
|
||||
}
|
||||
|
||||
@test "pip-rehash triggered when using 'pip'" {
|
||||
export PYENV_VERSION="3.7.14"
|
||||
create_alt_executable "example"
|
||||
create_alt_executable "pip"
|
||||
copy_src_pyenvd
|
||||
run command -v example 2> /dev/null
|
||||
assert_failure
|
||||
run pyenv-exec pip install example
|
||||
assert_success
|
||||
run command -v example 2> /dev/null
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "pip-rehash triggered when using 'pip3'" {
|
||||
export PYENV_VERSION="3.7.14"
|
||||
create_alt_executable "example"
|
||||
create_alt_executable "pip3"
|
||||
copy_src_pyenvd
|
||||
run command -v example 2> /dev/null
|
||||
assert_failure
|
||||
run pyenv-exec pip3 install example
|
||||
assert_success
|
||||
run command -v example 2> /dev/null
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "pip-rehash triggered when using 'pip3.x'" {
|
||||
export PYENV_VERSION="3.7.14"
|
||||
create_alt_executable "example"
|
||||
create_alt_executable "pip3.7"
|
||||
copy_src_pyenvd
|
||||
run command -v example 2> /dev/null
|
||||
assert_failure
|
||||
run pyenv-exec pip3.7 install example
|
||||
assert_success
|
||||
run command -v example 2> /dev/null
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "pip-rehash triggered when using 'python -m pip install'" {
|
||||
export PYENV_VERSION="3.7.14"
|
||||
create_alt_executable "example"
|
||||
create_alt_executable "python"
|
||||
copy_src_pyenvd
|
||||
run command -v example 2> /dev/null
|
||||
assert_failure
|
||||
run pyenv-exec python -m pip install example
|
||||
assert_success
|
||||
run command -v example 2> /dev/null
|
||||
assert_success
|
||||
}
|
||||
51
test/prefix.bats
Normal file
51
test/prefix.bats
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "prefix" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/myproject"
|
||||
cd "${PYENV_TEST_DIR}/myproject"
|
||||
echo "1.2.3" > .python-version
|
||||
mkdir -p "${PYENV_ROOT}/versions/1.2.3"
|
||||
run pyenv-prefix
|
||||
assert_success "${PYENV_ROOT}/versions/1.2.3"
|
||||
}
|
||||
|
||||
@test "prefix for invalid version" {
|
||||
PYENV_VERSION="1.2.3" run pyenv-prefix
|
||||
assert_failure "pyenv: version \`1.2.3' not installed"
|
||||
}
|
||||
|
||||
@test "prefix for system" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/bin"
|
||||
touch "${PYENV_TEST_DIR}/bin/python"
|
||||
chmod +x "${PYENV_TEST_DIR}/bin/python"
|
||||
PATH="${PYENV_TEST_DIR}/libexec:$PATH" PYENV_VERSION="system" run pyenv-prefix
|
||||
assert_success "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
#Arch has Python at sbin as well as bin
|
||||
@test "prefix for system in sbin" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/sbin"
|
||||
touch "${PYENV_TEST_DIR}/sbin/python"
|
||||
chmod +x "${PYENV_TEST_DIR}/sbin/python"
|
||||
PATH="${PYENV_TEST_DIR}/sbin:$PATH" PYENV_VERSION="system" run pyenv-prefix
|
||||
assert_success "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
@test "prefix for system in /" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/libexec"
|
||||
cat >"${PYENV_TEST_DIR}/libexec/pyenv-which" <<OUT
|
||||
#!/bin/sh
|
||||
echo /bin/python
|
||||
OUT
|
||||
chmod +x "${PYENV_TEST_DIR}/libexec/pyenv-which"
|
||||
PATH="${PYENV_TEST_DIR}/libexec:$PATH" PYENV_VERSION="system" run pyenv-prefix
|
||||
assert_success "/"
|
||||
rm -f "${PYENV_TEST_DIR}/libexec/pyenv-which"
|
||||
}
|
||||
|
||||
@test "prefix for invalid system" {
|
||||
PATH="$(path_without python python2 python3)" run pyenv-prefix system
|
||||
assert_failure "pyenv: system version not found in PATH"
|
||||
}
|
||||
72
test/pyenv.bats
Normal file
72
test/pyenv.bats
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "blank invocation" {
|
||||
run pyenv
|
||||
assert_failure
|
||||
assert_line 0 "$(pyenv---version)"
|
||||
}
|
||||
|
||||
@test "invalid command" {
|
||||
run pyenv does-not-exist
|
||||
assert_failure
|
||||
assert_output "pyenv: no such command \`does-not-exist'"
|
||||
}
|
||||
|
||||
@test "default PYENV_ROOT" {
|
||||
PYENV_ROOT="" HOME=/home/mislav run pyenv root
|
||||
assert_success
|
||||
assert_output "/home/mislav/.pyenv"
|
||||
}
|
||||
|
||||
@test "inherited PYENV_ROOT" {
|
||||
PYENV_ROOT=/opt/pyenv run pyenv root
|
||||
assert_success
|
||||
assert_output "/opt/pyenv"
|
||||
}
|
||||
|
||||
@test "default PYENV_DIR" {
|
||||
run pyenv echo PYENV_DIR
|
||||
assert_output "$(pwd)"
|
||||
}
|
||||
|
||||
@test "inherited PYENV_DIR" {
|
||||
dir="${BATS_TEST_TMPDIR}/myproject"
|
||||
mkdir -p "$dir"
|
||||
PYENV_DIR="$dir" run pyenv echo PYENV_DIR
|
||||
assert_output "$dir"
|
||||
}
|
||||
|
||||
@test "invalid PYENV_DIR" {
|
||||
dir="${BATS_TEST_TMPDIR}/does-not-exist"
|
||||
assert [ ! -d "$dir" ]
|
||||
PYENV_DIR="$dir" run pyenv echo PYENV_DIR
|
||||
assert_failure
|
||||
assert_output "pyenv: cannot change working directory to \`$dir'"
|
||||
}
|
||||
|
||||
@test "adds its own libexec and plugin bin dirs to PATH" {
|
||||
mkdir -p "$PYENV_ROOT"/plugins/python-build/bin
|
||||
mkdir -p "$PYENV_ROOT"/plugins/pyenv-each/bin
|
||||
run pyenv echo -F: "PATH"
|
||||
assert_success
|
||||
assert_line 0 "${BATS_TEST_DIRNAME%/*}/libexec"
|
||||
assert_line 1 "${PYENV_ROOT}/plugins/python-build/bin"
|
||||
assert_line 2 "${PYENV_ROOT}/plugins/pyenv-each/bin"
|
||||
assert_line 3 "${BATS_TEST_DIRNAME%/*}/plugins/python-build/bin"
|
||||
}
|
||||
|
||||
@test "PYENV_HOOK_PATH preserves value from environment" {
|
||||
PYENV_HOOK_PATH=/my/hook/path:/other/hooks run pyenv echo -F: "PYENV_HOOK_PATH"
|
||||
assert_success
|
||||
assert_line 0 "/my/hook/path"
|
||||
assert_line 1 "/other/hooks"
|
||||
assert_line 2 "${PYENV_ROOT}/pyenv.d"
|
||||
}
|
||||
|
||||
@test "PYENV_HOOK_PATH includes pyenv built-in plugins" {
|
||||
unset PYENV_HOOK_PATH
|
||||
run pyenv echo "PYENV_HOOK_PATH"
|
||||
assert_success "${PYENV_ROOT}/pyenv.d:${BATS_TEST_DIRNAME%/*}/pyenv.d:/usr/etc/pyenv.d:/usr/local/etc/pyenv.d:/etc/pyenv.d:/usr/lib/pyenv/hooks"
|
||||
}
|
||||
14
test/pyenv_ext.bats
Normal file
14
test/pyenv_ext.bats
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "prefixes" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/bin"
|
||||
touch "${PYENV_TEST_DIR}/bin/python"
|
||||
chmod +x "${PYENV_TEST_DIR}/bin/python"
|
||||
mkdir -p "${PYENV_ROOT}/versions/2.7.10"
|
||||
PYENV_VERSION="system:2.7.10" run pyenv-prefix
|
||||
assert_success "${PYENV_TEST_DIR}:${PYENV_ROOT}/versions/2.7.10"
|
||||
PYENV_VERSION="2.7.10:system" run pyenv-prefix
|
||||
assert_success "${PYENV_ROOT}/versions/2.7.10:${PYENV_TEST_DIR}"
|
||||
}
|
||||
178
test/rehash.bats
Executable file
178
test/rehash.bats
Executable file
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "empty rehash" {
|
||||
assert [ ! -d "${PYENV_ROOT}/shims" ]
|
||||
run pyenv-rehash
|
||||
assert_success ""
|
||||
assert [ -d "${PYENV_ROOT}/shims" ]
|
||||
rmdir "${PYENV_ROOT}/shims"
|
||||
}
|
||||
|
||||
@test "non-writable shims directory" {
|
||||
mkdir -p "${PYENV_ROOT}/shims"
|
||||
chmod -w "${PYENV_ROOT}/shims"
|
||||
run pyenv-rehash
|
||||
assert_failure "pyenv: cannot rehash: ${PYENV_ROOT}/shims isn't writable"
|
||||
}
|
||||
|
||||
@test "rehash in progress" {
|
||||
export PYENV_REHASH_TIMEOUT=1
|
||||
mkdir -p "${PYENV_ROOT}/shims"
|
||||
touch "${PYENV_ROOT}/shims/.pyenv-shim"
|
||||
#avoid failure due to a localized error message
|
||||
LANG=C run pyenv-rehash
|
||||
assert_failure <<!
|
||||
pyenv: cannot rehash: couldn't acquire lock ${PYENV_ROOT}/shims/.pyenv-shim for 1 seconds. Last error message:
|
||||
*/pyenv-rehash: line *: ${PYENV_ROOT}/shims/.pyenv-shim: cannot overwrite existing file
|
||||
!
|
||||
}
|
||||
|
||||
@test "wait until lock acquisition" {
|
||||
export PYENV_REHASH_TIMEOUT=5
|
||||
mkdir -p "${PYENV_ROOT}/shims"
|
||||
touch "${PYENV_ROOT}/shims/.pyenv-shim"
|
||||
bash -c "sleep 1 && rm -f ${PYENV_ROOT}/shims/.pyenv-shim" &
|
||||
run pyenv-rehash
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "creates shims" {
|
||||
create_alt_executable_in_version "2.7" "python"
|
||||
create_alt_executable_in_version "2.7" "fab"
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
create_alt_executable_in_version "3.4" "py.test"
|
||||
|
||||
assert [ ! -e "${PYENV_ROOT}/shims/fab" ]
|
||||
assert [ ! -e "${PYENV_ROOT}/shims/python" ]
|
||||
assert [ ! -e "${PYENV_ROOT}/shims/py.test" ]
|
||||
|
||||
run pyenv-rehash
|
||||
assert_success ""
|
||||
|
||||
run ls "${PYENV_ROOT}/shims"
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
fab
|
||||
py.test
|
||||
python
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "removes stale shims" {
|
||||
mkdir -p "${PYENV_ROOT}/shims"
|
||||
touch "${PYENV_ROOT}/shims/oldshim1"
|
||||
chmod +x "${PYENV_ROOT}/shims/oldshim1"
|
||||
|
||||
create_alt_executable_in_version "3.4" "fab"
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
|
||||
run pyenv-rehash
|
||||
assert_success ""
|
||||
|
||||
assert [ ! -e "${PYENV_ROOT}/shims/oldshim1" ]
|
||||
}
|
||||
|
||||
@test "binary install locations containing spaces" {
|
||||
create_alt_executable_in_version "dirname1 p247" "python"
|
||||
create_alt_executable_in_version "dirname2 preview1" "py.test"
|
||||
|
||||
assert [ ! -e "${PYENV_ROOT}/shims/python" ]
|
||||
assert [ ! -e "${PYENV_ROOT}/shims/py.test" ]
|
||||
|
||||
run pyenv-rehash
|
||||
assert_success ""
|
||||
|
||||
run ls "${PYENV_ROOT}/shims"
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
py.test
|
||||
python
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "carries original IFS within hooks" {
|
||||
create_hook rehash hello.bash <<SH
|
||||
hellos=(\$(printf "hello\\tugly world\\nagain"))
|
||||
echo HELLO="\$(printf ":%s" "\${hellos[@]}")"
|
||||
exit
|
||||
SH
|
||||
|
||||
IFS=$' \t\n' run pyenv-rehash
|
||||
assert_success
|
||||
assert_output "HELLO=:hello:ugly:world:again"
|
||||
}
|
||||
|
||||
@test "sh-rehash in bash" {
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
PYENV_SHELL=bash run pyenv-sh-rehash
|
||||
assert_success "command pyenv rehash
|
||||
hash -r 2>/dev/null || true"
|
||||
}
|
||||
|
||||
@test "sh-rehash in bash (integration)" {
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
PYENV_SHELL=bash run eval "$(pyenv-sh-rehash)"
|
||||
assert_success
|
||||
assert [ -x "${PYENV_ROOT}/shims/python" ]
|
||||
}
|
||||
|
||||
@test "sh-rehash in fish" {
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
PYENV_SHELL=fish run pyenv-sh-rehash
|
||||
assert_success "command pyenv rehash"
|
||||
}
|
||||
|
||||
@test "sh-rehash in fish (integration)" {
|
||||
command -v fish >/dev/null || skip "-- fish not installed"
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
PYENV_SHELL=fish fish -Nc "source (pyenv-sh-rehash | psub)"
|
||||
assert_success
|
||||
assert [ -x "${PYENV_ROOT}/shims/python" ]
|
||||
}
|
||||
|
||||
@test "sh-rehash in pwsh" {
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
PYENV_SHELL=pwsh run pyenv-sh-rehash
|
||||
assert_success "& (get-command pyenv -commandtype application) rehash"
|
||||
}
|
||||
|
||||
@test "sh-rehash in pwsh (integration)" {
|
||||
command -v pwsh >/dev/null || skip "-- pwsh not installed"
|
||||
assert [ ! -x "${PYENV_ROOT}/shims/python" ]
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
run pwsh -nop -c -<<'!'
|
||||
$ErrorActionPreference = "Stop"
|
||||
$PSNativeCommandUseErrorActionPreference = $true
|
||||
iex ((& pyenv init - pwsh) -join "`n")
|
||||
& pyenv rehash
|
||||
!
|
||||
assert_success ""
|
||||
assert [ -x "${PYENV_ROOT}/shims/python" ]
|
||||
}
|
||||
|
||||
@test "shim sets _PYENV_SHIM_PATH when linked from elsewhere" {
|
||||
export PYENV_VERSION="custom"
|
||||
create_alt_executable python3
|
||||
#must stub pyenv before rehash 'cuz the path is hardcoded into shims
|
||||
create_stub pyenv <<!
|
||||
[[ \$1 == 'exec' ]] && \
|
||||
echo _PYENV_SHIM_PATH="\$_PYENV_SHIM_PATH"
|
||||
!
|
||||
pyenv-rehash
|
||||
mkdir -p "${PYENV_TEST_DIR}/alt-shim"
|
||||
ln -s "${PYENV_ROOT}/shims/python3" "${PYENV_TEST_DIR}/alt-shim/python3"
|
||||
|
||||
run "${PYENV_TEST_DIR}/alt-shim/python3"
|
||||
assert_success
|
||||
assert_output <<!
|
||||
_PYENV_SHIM_PATH=${PYENV_TEST_DIR}/alt-shim
|
||||
!
|
||||
|
||||
run python3
|
||||
assert_success
|
||||
assert_output <<!
|
||||
_PYENV_SHIM_PATH=
|
||||
!
|
||||
}
|
||||
9
test/run
Executable file
9
test/run
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [ -n "$PYENV_NATIVE_EXT" ]; then
|
||||
src/configure
|
||||
make -C src
|
||||
fi
|
||||
|
||||
exec bats ${CI:+--tap} ${BATS_TEST_FILTER:+--filter "${BATS_TEST_FILTER}"} test/${BATS_FILE_FILTER}
|
||||
119
test/shell.bats
Normal file
119
test/shell.bats
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "shell integration disabled" {
|
||||
run pyenv shell
|
||||
assert_failure "pyenv: shell integration not enabled. Run \`pyenv init' for instructions."
|
||||
}
|
||||
|
||||
@test "shell integration enabled" {
|
||||
eval "$(pyenv init -)"
|
||||
run pyenv shell
|
||||
assert_success "pyenv: no shell-specific version configured"
|
||||
}
|
||||
|
||||
@test "no shell version" {
|
||||
mkdir -p "${PYENV_TEST_DIR}/myproject"
|
||||
cd "${PYENV_TEST_DIR}/myproject"
|
||||
echo "1.2.3" > .python-version
|
||||
PYENV_VERSION="" run pyenv-sh-shell
|
||||
assert_failure "pyenv: no shell-specific version configured"
|
||||
}
|
||||
|
||||
@test "shell version" {
|
||||
PYENV_SHELL=bash PYENV_VERSION="1.2.3" run pyenv-sh-shell
|
||||
assert_success 'echo "$PYENV_VERSION"'
|
||||
}
|
||||
|
||||
@test "shell version (fish)" {
|
||||
PYENV_SHELL=fish PYENV_VERSION="1.2.3" run pyenv-sh-shell
|
||||
assert_success 'echo "$PYENV_VERSION"'
|
||||
}
|
||||
|
||||
@test "shell version (pwsh)" {
|
||||
PYENV_SHELL=pwsh PYENV_VERSION="1.2.3" run pyenv-sh-shell
|
||||
assert_success 'echo "$PYENV_VERSION"'
|
||||
}
|
||||
|
||||
@test "shell revert" {
|
||||
PYENV_SHELL=bash run pyenv-sh-shell -
|
||||
assert_success
|
||||
assert_line 0 'if [ -n "${PYENV_VERSION_OLD+x}" ]; then'
|
||||
}
|
||||
|
||||
@test "shell revert (fish)" {
|
||||
PYENV_SHELL=fish run pyenv-sh-shell -
|
||||
assert_success
|
||||
assert_line 0 'if set -q PYENV_VERSION_OLD'
|
||||
}
|
||||
|
||||
@test "shell revert (pwsh)" {
|
||||
PYENV_SHELL=pwsh run pyenv-sh-shell -
|
||||
assert_success
|
||||
assert_line 0 'if ( Get-Item -Path Env:\PYENV_VERSION* ) {'
|
||||
}
|
||||
|
||||
@test "shell unset" {
|
||||
PYENV_SHELL=bash run pyenv-sh-shell --unset
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
PYENV_VERSION_OLD="\${PYENV_VERSION-}"
|
||||
unset PYENV_VERSION
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "shell unset (fish)" {
|
||||
PYENV_SHELL=fish run pyenv-sh-shell --unset
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
set -gu PYENV_VERSION_OLD "\$PYENV_VERSION"
|
||||
set -e PYENV_VERSION
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "shell unset (pwsh)" {
|
||||
PYENV_SHELL=pwsh run pyenv-sh-shell --unset
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
\$Env:PYENV_VERSION, \$Env:PYENV_VERSION_OLD = \$null, \$Env:PYENV_VERSION
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "shell change invalid version" {
|
||||
run pyenv-sh-shell 1.2.3
|
||||
assert_failure
|
||||
assert_output <<SH
|
||||
pyenv: version \`1.2.3' not installed
|
||||
false
|
||||
SH
|
||||
}
|
||||
|
||||
@test "shell change version" {
|
||||
mkdir -p "${PYENV_ROOT}/versions/1.2.3"
|
||||
PYENV_SHELL=bash run pyenv-sh-shell 1.2.3
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
PYENV_VERSION_OLD="\${PYENV_VERSION-}"
|
||||
export PYENV_VERSION="1.2.3"
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "shell change version (fish)" {
|
||||
mkdir -p "${PYENV_ROOT}/versions/1.2.3"
|
||||
PYENV_SHELL=fish run pyenv-sh-shell 1.2.3
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
set -gu PYENV_VERSION_OLD "\$PYENV_VERSION"
|
||||
set -gx PYENV_VERSION "1.2.3"
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "shell change version (pwsh)" {
|
||||
mkdir -p "${PYENV_ROOT}/versions/1.2.3"
|
||||
PYENV_SHELL=pwsh run pyenv-sh-shell 1.2.3
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
\$Env:PYENV_VERSION, \$Env:PYENV_VERSION_OLD = "1.2.3", \$Env:PYENV_VERSION
|
||||
OUT
|
||||
}
|
||||
39
test/shims-linked-from-elsewhere.bats
Normal file
39
test/shims-linked-from-elsewhere.bats
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "shims linked from elsewhere are chained, other programs at the same paths are unaffected (integration)" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
progname=shimmed_program
|
||||
called_progname=another_program
|
||||
create_alt_executable_in_version "custom" "$progname" <<!
|
||||
echo "called from \$0"
|
||||
pyenv-exec "$called_progname"
|
||||
!
|
||||
pyenv-rehash
|
||||
PATH="$(path_without "$progname" "$called_progname")"
|
||||
for disguised_shim_path in "$BATS_TEST_TMPDIR/"{weird-location,even/weirder/location}; do
|
||||
mkdir -p "$disguised_shim_path"
|
||||
ln -s "${PYENV_ROOT}/shims/$progname" "$disguised_shim_path/$progname"
|
||||
PATH="$PATH:$disguised_shim_path"
|
||||
done
|
||||
create_executable "$disguised_shim_path" "$called_progname" <<!
|
||||
echo "convoluted call success!"
|
||||
!
|
||||
real_path="$BATS_TEST_TMPDIR/real-location"
|
||||
mkdir -p "$real_path"
|
||||
ln -s "${PYENV_ROOT}/versions/custom/bin/$progname" "$real_path/$progname"
|
||||
PATH="$PATH:$real_path"
|
||||
|
||||
run "$progname"
|
||||
assert_success
|
||||
assert_output <<!
|
||||
called from $real_path/$progname
|
||||
convoluted call success!
|
||||
!
|
||||
|
||||
rm "$real_path/$progname"
|
||||
run -127 "$progname"
|
||||
assert_failure
|
||||
assert_line 0 "pyenv: shimmed_program: command not found"
|
||||
}
|
||||
29
test/shims.bats
Normal file
29
test/shims.bats
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "no shims" {
|
||||
run pyenv-shims
|
||||
assert_success
|
||||
assert [ -z "$output" ]
|
||||
}
|
||||
|
||||
@test "shims" {
|
||||
mkdir -p "${PYENV_ROOT}/shims"
|
||||
touch "${PYENV_ROOT}/shims/python"
|
||||
touch "${PYENV_ROOT}/shims/irb"
|
||||
run pyenv-shims
|
||||
assert_success
|
||||
assert_line "${PYENV_ROOT}/shims/python"
|
||||
assert_line "${PYENV_ROOT}/shims/irb"
|
||||
}
|
||||
|
||||
@test "shims --short" {
|
||||
mkdir -p "${PYENV_ROOT}/shims"
|
||||
touch "${PYENV_ROOT}/shims/python"
|
||||
touch "${PYENV_ROOT}/shims/irb"
|
||||
run pyenv-shims --short
|
||||
assert_success
|
||||
assert_line "irb"
|
||||
assert_line "python"
|
||||
}
|
||||
195
test/test_helper.bash
Normal file
195
test/test_helper.bash
Normal file
@@ -0,0 +1,195 @@
|
||||
unset PYENV_VERSION
|
||||
unset PYENV_DIR
|
||||
|
||||
setup() {
|
||||
export _PYENV_INSTALL_PREFIX="${BATS_TEST_DIRNAME%/*}"
|
||||
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||
if ! enable -f "${_PYENV_INSTALL_PREFIX}"/libexec/pyenv-realpath.dylib realpath 2>/dev/null; then
|
||||
if [ -n "$PYENV_NATIVE_EXT" ]; then
|
||||
echo "pyenv: failed to load \`realpath' builtin" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
local bats_test_tmpdir="$(realpath "${BATS_TEST_TMPDIR}")"
|
||||
if [ -z "${bats_test_tmpdir}" ];then
|
||||
# Use readlink if running in a container instead of realpath lib
|
||||
bats_test_tmpdir="$(readlink -f "${BATS_TEST_TMPDIR}")"
|
||||
fi
|
||||
|
||||
# update BATS_TEST_TMPDIR discover by realpath/readlink to avoid "//"
|
||||
export BATS_TEST_TMPDIR="${bats_test_tmpdir}"
|
||||
export PYENV_TEST_DIR="${BATS_TEST_TMPDIR}/pyenv"
|
||||
export PYENV_ROOT="${PYENV_TEST_DIR}/root"
|
||||
export HOME="${PYENV_TEST_DIR}/home"
|
||||
export PYENV_HOOK_PATH="${PYENV_ROOT}/pyenv.d"
|
||||
|
||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
|
||||
PATH="${PYENV_TEST_DIR}/bin:$PATH"
|
||||
PATH="${_PYENV_INSTALL_PREFIX}/libexec:$PATH"
|
||||
PATH="${BATS_TEST_DIRNAME}/libexec:$PATH"
|
||||
PATH="${PYENV_ROOT}/shims:$PATH"
|
||||
PATH="${BATS_TEST_TMPDIR}/stubs:$PATH"
|
||||
|
||||
for xdg_var in `env 2>/dev/null | grep ^XDG_ | cut -d= -f1`; do unset "$xdg_var"; done
|
||||
unset xdg_var
|
||||
|
||||
# Workaround for Powershell. When tests are run from a terminal,
|
||||
# and running a script fron a here-document,
|
||||
# Powershell 7.5.4 erroneously prints ANSI escape sequences
|
||||
# even if its output is redirected, breaking the comparison logic
|
||||
export NO_COLOR=1
|
||||
|
||||
# If test specific setup exist, run it
|
||||
if [[ $(type -t _setup) == function ]];then
|
||||
_setup
|
||||
fi
|
||||
}
|
||||
|
||||
flunk() {
|
||||
{ if [ "$#" -eq 0 ]; then cat -
|
||||
else echo "$@"
|
||||
fi
|
||||
} | sed "s:${PYENV_TEST_DIR}:TEST_DIR:g" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
assert_success() {
|
||||
if [ "$status" -ne 0 ]; then
|
||||
flunk "command failed with exit status $status" $'\n'\
|
||||
"output: $output"
|
||||
elif [ "$#" -gt 0 ]; then
|
||||
assert_output "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_failure() {
|
||||
if [ "$status" -eq 0 ]; then
|
||||
flunk "expected failed exit status" $'\n'\
|
||||
"output: $output"
|
||||
elif [ "$#" -gt 0 ]; then
|
||||
assert_output "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_equal() {
|
||||
if [ "$1" != "$2" ]; then
|
||||
{ echo "expected: \`$1'"
|
||||
echo "actual: \`$2'"
|
||||
} | flunk
|
||||
fi
|
||||
}
|
||||
|
||||
assert_output() {
|
||||
local expected
|
||||
if [ $# -eq 0 ]; then expected="$(cat -)"
|
||||
else expected="$1"
|
||||
fi
|
||||
assert_equal "$expected" "$output"
|
||||
}
|
||||
|
||||
assert_line() {
|
||||
if [ "$1" -ge 0 ] 2>/dev/null; then
|
||||
assert_equal "$2" "${lines[$1]}"
|
||||
else
|
||||
local line
|
||||
for line in "${lines[@]}"; do
|
||||
if [ "$line" = "$1" ]; then return 0; fi
|
||||
done
|
||||
flunk "expected line \`$1'" $'\n'\
|
||||
"output: $output"
|
||||
fi
|
||||
}
|
||||
|
||||
refute_line() {
|
||||
if [ "$1" -ge 0 ] 2>/dev/null; then
|
||||
local num_lines="${#lines[@]}"
|
||||
if [ "$1" -lt "$num_lines" ]; then
|
||||
flunk "output has $num_lines lines"
|
||||
fi
|
||||
else
|
||||
local line
|
||||
for line in "${lines[@]}"; do
|
||||
if [ "$line" = "$1" ]; then
|
||||
flunk "expected to not find line \`$line'" $'\n'\
|
||||
"output: $output"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
assert() {
|
||||
if ! "$@"; then
|
||||
flunk "failed: $@"
|
||||
fi
|
||||
}
|
||||
|
||||
# Output a modified PATH that ensures that the given executable is not present,
|
||||
# but in which system utils necessary for pyenv operation are still available.
|
||||
path_without() {
|
||||
local path=":${PATH}:"
|
||||
for exe; do
|
||||
local found alt util
|
||||
for found in $(PATH="$path" type -aP "$exe"); do
|
||||
found="${found%/*}"
|
||||
if [ "$found" != "${PYENV_ROOT}/shims" ]; then
|
||||
alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')"
|
||||
mkdir -p "$alt"
|
||||
for util in bash head cut readlink greadlink tr sed xargs basename sort; do
|
||||
if [ -x "${found}/$util" ]; then
|
||||
ln -s "${found}/$util" "${alt}/$util"
|
||||
fi
|
||||
done
|
||||
path="${path/:${found}:/:${alt}:}"
|
||||
fi
|
||||
done
|
||||
done
|
||||
path="${path#:}"
|
||||
path="${path%:}"
|
||||
echo "$path"
|
||||
}
|
||||
|
||||
create_path_executable() {
|
||||
create_executable "${PYENV_TEST_DIR}/bin" "$@"
|
||||
}
|
||||
|
||||
create_alt_executable() {
|
||||
create_alt_executable_in_version "${PYENV_VERSION}" "$@"
|
||||
}
|
||||
|
||||
create_alt_executable_in_version() {
|
||||
local version="${1:?}"
|
||||
shift 1
|
||||
create_executable "${PYENV_ROOT}/versions/$version/bin" "$@"
|
||||
}
|
||||
|
||||
create_stub() {
|
||||
create_executable "${BATS_TEST_TMPDIR}/stubs" "$@"
|
||||
}
|
||||
|
||||
create_executable() {
|
||||
local bin="${1:?}"
|
||||
local name="${2:?}"
|
||||
shift 2
|
||||
mkdir -p "$bin"
|
||||
local payload
|
||||
# Bats doesn't redirect stdin
|
||||
if [[ $# -eq 0 && ! -t 0 ]]; then
|
||||
payload="$(cat -)"
|
||||
else
|
||||
payload="$(printf '%s\n' "$@")"
|
||||
fi
|
||||
if [[ $payload != "#!/"* ]]; then
|
||||
payload="#!$BASH"$'\n'"$payload"
|
||||
fi
|
||||
echo "$payload" > "${bin}/$name"
|
||||
chmod +x "${bin}/$name"
|
||||
}
|
||||
|
||||
create_hook() {
|
||||
mkdir -p "${PYENV_HOOK_PATH}/$1"
|
||||
touch "${PYENV_HOOK_PATH}/$1/$2"
|
||||
if [ ! -t 0 ]; then
|
||||
cat > "${PYENV_HOOK_PATH}/$1/$2"
|
||||
fi
|
||||
}
|
||||
118
test/version-file-read.bats
Normal file
118
test/version-file-read.bats
Normal file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
_setup() {
|
||||
mkdir -p "${PYENV_TEST_DIR}/myproject"
|
||||
cd "${PYENV_TEST_DIR}/myproject"
|
||||
}
|
||||
|
||||
@test "fails without arguments" {
|
||||
run pyenv-version-file-read
|
||||
assert_failure ""
|
||||
}
|
||||
|
||||
@test "fails for invalid file" {
|
||||
run pyenv-version-file-read "non-existent"
|
||||
assert_failure ""
|
||||
}
|
||||
|
||||
@test "fails for blank file" {
|
||||
echo > my-version
|
||||
run pyenv-version-file-read my-version
|
||||
assert_failure ""
|
||||
}
|
||||
|
||||
@test "reads simple version file" {
|
||||
cat > my-version <<<"3.3.5"
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "3.3.5"
|
||||
}
|
||||
|
||||
@test "ignores leading spaces" {
|
||||
cat > my-version <<<" 3.3.5"
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "3.3.5"
|
||||
}
|
||||
|
||||
@test "reads only the first word from file" {
|
||||
cat > my-version <<<"3.3.5 2.7.6 hi"
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "3.3.5"
|
||||
}
|
||||
|
||||
@test "loads *not* only the first line in file" {
|
||||
cat > my-version <<IN
|
||||
2.7.6 one
|
||||
3.3.5 two
|
||||
IN
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "2.7.6:3.3.5"
|
||||
}
|
||||
|
||||
@test "ignores leading blank lines" {
|
||||
cat > my-version <<IN
|
||||
|
||||
3.3.5
|
||||
IN
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "3.3.5"
|
||||
}
|
||||
|
||||
@test "handles the file with no trailing newline" {
|
||||
echo -n "2.7.6" > my-version
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "2.7.6"
|
||||
}
|
||||
|
||||
@test "ignores carriage returns" {
|
||||
cat > my-version <<< $'3.3.5\r'
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "3.3.5"
|
||||
}
|
||||
|
||||
@test "skips comment lines" {
|
||||
cat > my-version <<IN
|
||||
3.9.3
|
||||
3.8.9
|
||||
# 3.4.0
|
||||
#3.3.7
|
||||
2.7.16
|
||||
IN
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "3.9.3:3.8.9:2.7.16"
|
||||
}
|
||||
|
||||
@test "skips \`..' relative path traversal" {
|
||||
echo '..' > my-version
|
||||
run pyenv-version-file-read my-version
|
||||
assert_failure "pyenv: invalid version \`..' ignored in \`my-version'"
|
||||
}
|
||||
|
||||
@test "skips glob path traversal" {
|
||||
cat > my-version <<IN
|
||||
../*
|
||||
3.9.3
|
||||
IN
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success <<OUT
|
||||
pyenv: invalid version \`../\*' ignored in \`my-version'
|
||||
3.9.3
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "allows relative paths that exist and stay within versions" {
|
||||
venv=3.10.3/envs/../test
|
||||
mkdir -p "${PYENV_ROOT}/versions/${venv}"
|
||||
echo -n "${venv}" > my-version
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success "${venv}"
|
||||
}
|
||||
|
||||
@test "skips relative paths that lead outside of versions" {
|
||||
venv=../3.10.3/envs/test
|
||||
mkdir -p "${PYENV_ROOT}/versions/${venv}"
|
||||
echo -n "${venv}" > my-version
|
||||
run pyenv-version-file-read my-version
|
||||
assert_failure
|
||||
}
|
||||
37
test/version-file-write.bats
Normal file
37
test/version-file-write.bats
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
_setup() {
|
||||
mkdir -p "${PYENV_TEST_DIR}"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
@test "invocation without 2 arguments prints usage" {
|
||||
run pyenv-version-file-write
|
||||
assert_failure "Usage: pyenv version-file-write [-f|--force] <file> <version> [...]"
|
||||
run pyenv-version-file-write "one" ""
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "setting nonexistent version fails" {
|
||||
assert [ ! -e ".python-version" ]
|
||||
run pyenv-version-file-write ".python-version" "2.7.6"
|
||||
assert_failure "pyenv: version \`2.7.6' not installed"
|
||||
assert [ ! -e ".python-version" ]
|
||||
}
|
||||
|
||||
@test "setting nonexistent version succeeds with force" {
|
||||
assert [ ! -e ".python-version" ]
|
||||
run pyenv-version-file-write --force ".python-version" "2.7.6"
|
||||
assert_success
|
||||
assert [ -e ".python-version" ]
|
||||
}
|
||||
|
||||
@test "writes value to arbitrary file" {
|
||||
mkdir -p "${PYENV_ROOT}/versions/2.7.6"
|
||||
assert [ ! -e "my-version" ]
|
||||
run pyenv-version-file-write "${PWD}/my-version" "2.7.6"
|
||||
assert_success ""
|
||||
assert [ "$(cat my-version)" = "2.7.6" ]
|
||||
}
|
||||
75
test/version-file.bats
Normal file
75
test/version-file.bats
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
_setup() {
|
||||
mkdir -p "${PYENV_TEST_DIR}"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
create_file() {
|
||||
mkdir -p "$(dirname "$1")"
|
||||
echo "system" > "$1"
|
||||
}
|
||||
|
||||
@test "detects global 'version' file" {
|
||||
create_file "${PYENV_ROOT}/version"
|
||||
run pyenv-version-file
|
||||
assert_success "${PYENV_ROOT}/version"
|
||||
}
|
||||
|
||||
@test "prints global file if no version files exist" {
|
||||
assert [ ! -e "${PYENV_ROOT}/version" ]
|
||||
assert [ ! -e ".python-version" ]
|
||||
run pyenv-version-file
|
||||
assert_success "${PYENV_ROOT}/version"
|
||||
}
|
||||
|
||||
@test "in current directory" {
|
||||
create_file ".python-version"
|
||||
run pyenv-version-file
|
||||
assert_success "${PYENV_TEST_DIR}/.python-version"
|
||||
}
|
||||
|
||||
@test "in parent directory" {
|
||||
create_file ".python-version"
|
||||
mkdir -p project
|
||||
cd project
|
||||
run pyenv-version-file
|
||||
assert_success "${PYENV_TEST_DIR}/.python-version"
|
||||
}
|
||||
|
||||
@test "topmost file has precedence" {
|
||||
create_file ".python-version"
|
||||
create_file "project/.python-version"
|
||||
cd project
|
||||
run pyenv-version-file
|
||||
assert_success "${PYENV_TEST_DIR}/project/.python-version"
|
||||
}
|
||||
|
||||
@test "PYENV_DIR has precedence over PWD" {
|
||||
create_file "widget/.python-version"
|
||||
create_file "project/.python-version"
|
||||
cd project
|
||||
PYENV_DIR="${PYENV_TEST_DIR}/widget" run pyenv-version-file
|
||||
assert_success "${PYENV_TEST_DIR}/widget/.python-version"
|
||||
}
|
||||
|
||||
@test "PWD is searched if PYENV_DIR yields no results" {
|
||||
mkdir -p "widget/blank"
|
||||
create_file "project/.python-version"
|
||||
cd project
|
||||
PYENV_DIR="${PYENV_TEST_DIR}/widget/blank" run pyenv-version-file
|
||||
assert_success "${PYENV_TEST_DIR}/project/.python-version"
|
||||
}
|
||||
|
||||
@test "finds version file in target directory" {
|
||||
create_file "project/.python-version"
|
||||
run pyenv-version-file "${PWD}/project"
|
||||
assert_success "${PYENV_TEST_DIR}/project/.python-version"
|
||||
}
|
||||
|
||||
@test "fails when no version file in target directory" {
|
||||
run pyenv-version-file "$PWD"
|
||||
assert_failure ""
|
||||
}
|
||||
141
test/version-name.bats
Normal file
141
test/version-name.bats
Normal file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
create_version() {
|
||||
mkdir -p "${PYENV_ROOT}/versions/$1"
|
||||
}
|
||||
|
||||
_setup() {
|
||||
mkdir -p "${PYENV_TEST_DIR}"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
@test "no version selected" {
|
||||
assert [ ! -d "${PYENV_ROOT}/versions" ]
|
||||
run pyenv-version-name
|
||||
assert_success "system"
|
||||
}
|
||||
|
||||
@test "system version is not checked for existence" {
|
||||
PYENV_VERSION=system run pyenv-version-name
|
||||
assert_success "system"
|
||||
}
|
||||
|
||||
@test "PYENV_VERSION can be overridden by hook" {
|
||||
create_version "2.7.11"
|
||||
create_version "3.5.1"
|
||||
create_hook version-name test.bash <<<"PYENV_VERSION=3.5.1"
|
||||
|
||||
PYENV_VERSION=2.7.11 run pyenv-version-name
|
||||
assert_success "3.5.1"
|
||||
}
|
||||
|
||||
@test "carries original IFS within hooks" {
|
||||
create_hook version-name hello.bash <<SH
|
||||
hellos=(\$(printf "hello\\tugly world\\nagain"))
|
||||
echo HELLO="\$(printf ":%s" "\${hellos[@]}")"
|
||||
SH
|
||||
|
||||
export PYENV_VERSION=system
|
||||
IFS=$' \t\n' run pyenv-version-name env
|
||||
assert_success
|
||||
assert_line "HELLO=:hello:ugly:world:again"
|
||||
}
|
||||
|
||||
@test "PYENV_VERSION has precedence over local" {
|
||||
create_version "2.7.11"
|
||||
create_version "3.5.1"
|
||||
|
||||
cat > ".python-version" <<<"2.7.11"
|
||||
run pyenv-version-name
|
||||
assert_success "2.7.11"
|
||||
|
||||
PYENV_VERSION=3.5.1 run pyenv-version-name
|
||||
assert_success "3.5.1"
|
||||
}
|
||||
|
||||
@test "local file has precedence over global" {
|
||||
create_version "2.7.11"
|
||||
create_version "3.5.1"
|
||||
|
||||
cat > "${PYENV_ROOT}/version" <<<"2.7.11"
|
||||
run pyenv-version-name
|
||||
assert_success "2.7.11"
|
||||
|
||||
cat > ".python-version" <<<"3.5.1"
|
||||
run pyenv-version-name
|
||||
assert_success "3.5.1"
|
||||
}
|
||||
|
||||
@test "missing version" {
|
||||
PYENV_VERSION=1.2 run pyenv-version-name
|
||||
assert_failure "pyenv: version \`1.2' is not installed (set by PYENV_VERSION environment variable)"
|
||||
}
|
||||
|
||||
@test "missing version with --force" {
|
||||
PYENV_VERSION=1.2 run pyenv-version-name -f
|
||||
assert_success "1.2"
|
||||
}
|
||||
|
||||
@test "one missing version (second missing)" {
|
||||
create_version "3.5.1"
|
||||
PYENV_VERSION="3.5.1:1.2" run pyenv-version-name
|
||||
assert_failure
|
||||
assert_output <<OUT
|
||||
pyenv: version \`1.2' is not installed (set by PYENV_VERSION environment variable)
|
||||
3.5.1
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "one missing version (first missing)" {
|
||||
create_version "3.5.1"
|
||||
PYENV_VERSION="1.2:3.5.1" run pyenv-version-name
|
||||
assert_failure
|
||||
assert_output <<OUT
|
||||
pyenv: version \`1.2' is not installed (set by PYENV_VERSION environment variable)
|
||||
3.5.1
|
||||
OUT
|
||||
}
|
||||
|
||||
pyenv-version-name-without-stderr() {
|
||||
pyenv-version-name 2>/dev/null
|
||||
}
|
||||
|
||||
@test "one missing version (without stderr)" {
|
||||
create_version "3.5.1"
|
||||
PYENV_VERSION="1.2:3.5.1" run pyenv-version-name-without-stderr
|
||||
assert_failure
|
||||
assert_output <<OUT
|
||||
3.5.1
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "version with prefix in name" {
|
||||
create_version "2.7.11"
|
||||
cat > ".python-version" <<<"python-2.7.11"
|
||||
run pyenv-version-name
|
||||
assert_success
|
||||
assert_output "2.7.11"
|
||||
}
|
||||
|
||||
@test "falls back to pyenv-latest" {
|
||||
create_version "2.7.11"
|
||||
PYENV_VERSION="2.7" run pyenv-version-name
|
||||
assert_success
|
||||
assert_output "2.7.11"
|
||||
}
|
||||
|
||||
@test "pyenv-latest fallback with prefix in name" {
|
||||
create_version "3.12.6"
|
||||
PYENV_VERSION="python-3.12" run pyenv-version-name
|
||||
assert_success
|
||||
assert_output "3.12.6"
|
||||
}
|
||||
|
||||
@test "pyenv version started by python-" {
|
||||
create_version "python-3.12.6"
|
||||
PYENV_VERSION="python-3.12.6" run pyenv-version-name
|
||||
assert_success
|
||||
assert_output "python-3.12.6"
|
||||
}
|
||||
56
test/version-origin.bats
Normal file
56
test/version-origin.bats
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
_setup() {
|
||||
mkdir -p "${PYENV_TEST_DIR}"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
@test "reports global file even if it doesn't exist" {
|
||||
assert [ ! -e "${PYENV_ROOT}/version" ]
|
||||
run pyenv-version-origin
|
||||
assert_success "${PYENV_ROOT}/version"
|
||||
}
|
||||
|
||||
@test "detects global file" {
|
||||
mkdir -p "$PYENV_ROOT"
|
||||
touch "${PYENV_ROOT}/version"
|
||||
run pyenv-version-origin
|
||||
assert_success "${PYENV_ROOT}/version"
|
||||
}
|
||||
|
||||
@test "detects PYENV_VERSION" {
|
||||
PYENV_VERSION=1 run pyenv-version-origin
|
||||
assert_success "PYENV_VERSION environment variable"
|
||||
}
|
||||
|
||||
@test "detects local file" {
|
||||
echo "system" > .python-version
|
||||
run pyenv-version-origin
|
||||
assert_success "${PWD}/.python-version"
|
||||
}
|
||||
|
||||
@test "reports from hook" {
|
||||
create_hook version-origin test.bash <<<"PYENV_VERSION_ORIGIN=plugin"
|
||||
|
||||
PYENV_VERSION=1 run pyenv-version-origin
|
||||
assert_success "plugin"
|
||||
}
|
||||
|
||||
@test "carries original IFS within hooks" {
|
||||
create_hook version-origin hello.bash <<SH
|
||||
hellos=(\$(printf "hello\\tugly world\\nagain"))
|
||||
echo HELLO="\$(printf ":%s" "\${hellos[@]}")"
|
||||
SH
|
||||
|
||||
export PYENV_VERSION=system
|
||||
IFS=$' \t\n' run pyenv-version-origin env
|
||||
assert_success
|
||||
assert_line "HELLO=:hello:ugly:world:again"
|
||||
}
|
||||
|
||||
@test "doesn't inherit PYENV_VERSION_ORIGIN from environment" {
|
||||
PYENV_VERSION_ORIGIN=ignored run pyenv-version-origin
|
||||
assert_success "${PYENV_ROOT}/version"
|
||||
}
|
||||
81
test/version.bats
Normal file
81
test/version.bats
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
create_version() {
|
||||
mkdir -p "${PYENV_ROOT}/versions/$1"
|
||||
}
|
||||
|
||||
_setup() {
|
||||
mkdir -p "${PYENV_ROOT}"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
@test "no version selected" {
|
||||
assert [ ! -d "${PYENV_ROOT}/versions" ]
|
||||
run pyenv-version
|
||||
assert_success "system (set by ${PYENV_ROOT}/version)"
|
||||
}
|
||||
|
||||
@test "set by PYENV_VERSION" {
|
||||
create_version "3.3.3"
|
||||
PYENV_VERSION=3.3.3 run pyenv-version
|
||||
assert_success "3.3.3 (set by PYENV_VERSION environment variable)"
|
||||
}
|
||||
|
||||
@test "set by local file" {
|
||||
create_version "3.3.3"
|
||||
cat > ".python-version" <<<"3.3.3"
|
||||
run pyenv-version
|
||||
assert_success "3.3.3 (set by ${PWD}/.python-version)"
|
||||
}
|
||||
|
||||
@test "set by global file" {
|
||||
create_version "3.3.3"
|
||||
cat > "${PYENV_ROOT}/version" <<<"3.3.3"
|
||||
run pyenv-version
|
||||
assert_success "3.3.3 (set by ${PYENV_ROOT}/version)"
|
||||
}
|
||||
|
||||
@test "set by PYENV_VERSION, one missing" {
|
||||
create_version "3.3.3"
|
||||
PYENV_VERSION=3.3.3:1.2 run pyenv-version
|
||||
assert_failure
|
||||
assert_output <<OUT
|
||||
pyenv: version \`1.2' is not installed (set by PYENV_VERSION environment variable)
|
||||
3.3.3 (set by PYENV_VERSION environment variable)
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "set by PYENV_VERSION, two missing" {
|
||||
create_version "3.3.3"
|
||||
PYENV_VERSION=3.4.2:3.3.3:1.2 run pyenv-version
|
||||
assert_failure
|
||||
assert_output <<OUT
|
||||
pyenv: version \`3.4.2' is not installed (set by PYENV_VERSION environment variable)
|
||||
pyenv: version \`1.2' is not installed (set by PYENV_VERSION environment variable)
|
||||
3.3.3 (set by PYENV_VERSION environment variable)
|
||||
OUT
|
||||
}
|
||||
|
||||
pyenv-version-without-stderr() {
|
||||
pyenv-version 2>/dev/null
|
||||
}
|
||||
|
||||
@test "set by PYENV_VERSION, one missing (stderr filtered)" {
|
||||
create_version "3.3.3"
|
||||
PYENV_VERSION=3.4.2:3.3.3 run pyenv-version-without-stderr
|
||||
assert_failure
|
||||
assert_output <<OUT
|
||||
3.3.3 (set by PYENV_VERSION environment variable)
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "--bare prints just the name" {
|
||||
create_version "3.3.3"
|
||||
PYENV_VERSION=3.3.3 run pyenv-version --bare
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
3.3.3
|
||||
OUT
|
||||
}
|
||||
273
test/versions.bats
Normal file
273
test/versions.bats
Normal file
@@ -0,0 +1,273 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
create_version() {
|
||||
mkdir -p "${PYENV_ROOT}/versions/$1"
|
||||
}
|
||||
|
||||
create_alias() {
|
||||
mkdir -p "${PYENV_ROOT}/versions"
|
||||
ln -s "$2" "${PYENV_ROOT}/versions/$1"
|
||||
}
|
||||
|
||||
create_external_version() {
|
||||
mkdir -p "$PYENV_TEST_DIR/${1:?}"
|
||||
create_alias "${1:?}" "$PYENV_TEST_DIR/${1:?}"
|
||||
}
|
||||
|
||||
_setup() {
|
||||
mkdir -p "$PYENV_TEST_DIR"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
}
|
||||
|
||||
stub_system_python() {
|
||||
local stub="${PYENV_TEST_DIR}/bin/python"
|
||||
mkdir -p "$(dirname "$stub")"
|
||||
touch "$stub" && chmod +x "$stub"
|
||||
}
|
||||
|
||||
@test "no versions installed" {
|
||||
stub_system_python
|
||||
assert [ ! -d "${PYENV_ROOT}/versions" ]
|
||||
run pyenv-versions
|
||||
assert_success "* system (set by ${PYENV_ROOT}/version)"
|
||||
}
|
||||
|
||||
@test "not even system python available" {
|
||||
PATH="$(path_without python python2 python3)" run pyenv-versions
|
||||
assert_failure
|
||||
assert_output "Warning: no Python detected on the system"
|
||||
}
|
||||
|
||||
@test "bare output no versions installed" {
|
||||
assert [ ! -d "${PYENV_ROOT}/versions" ]
|
||||
run pyenv-versions --bare
|
||||
assert_success ""
|
||||
}
|
||||
|
||||
@test "single version installed" {
|
||||
stub_system_python
|
||||
create_version "3.3"
|
||||
run pyenv-versions
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
* system (set by ${PYENV_ROOT}/version)
|
||||
3.3
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "single version bare" {
|
||||
create_version "3.3"
|
||||
run pyenv-versions --bare
|
||||
assert_success "3.3"
|
||||
}
|
||||
|
||||
@test "multiple versions and envs" {
|
||||
stub_system_python
|
||||
create_version "2.7.6"
|
||||
create_version "3.4.0"
|
||||
create_version "3.4.0/envs/foo"
|
||||
create_version "3.4.0/envs/bar"
|
||||
create_version "3.5.2"
|
||||
run pyenv-versions
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
* system (set by ${PYENV_ROOT}/version)
|
||||
2.7.6
|
||||
3.4.0
|
||||
3.4.0/envs/bar
|
||||
3.4.0/envs/foo
|
||||
3.5.2
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "skips envs with --skip-envs" {
|
||||
create_version "3.3.3"
|
||||
create_version "3.4.0"
|
||||
create_version "3.4.0/envs/foo"
|
||||
create_version "3.4.0/envs/bar"
|
||||
create_version "3.5.0"
|
||||
|
||||
run pyenv-versions --skip-envs
|
||||
assert_success <<OUT
|
||||
* system (set by ${PYENV_ROOT}/version)
|
||||
3.3.3
|
||||
3.4.0
|
||||
3.5.0
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "indicates current version" {
|
||||
stub_system_python
|
||||
create_version "3.3.3"
|
||||
create_version "3.4.0"
|
||||
PYENV_VERSION=3.3.3 run pyenv-versions
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
system
|
||||
* 3.3.3 (set by PYENV_VERSION environment variable)
|
||||
3.4.0
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "bare doesn't indicate current version" {
|
||||
create_version "3.3.3"
|
||||
create_version "3.4.0"
|
||||
PYENV_VERSION=3.3.3 run pyenv-versions --bare
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
3.3.3
|
||||
3.4.0
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "globally selected version" {
|
||||
stub_system_python
|
||||
create_version "3.3.3"
|
||||
create_version "3.4.0"
|
||||
cat > "${PYENV_ROOT}/version" <<<"3.3.3"
|
||||
run pyenv-versions
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
system
|
||||
* 3.3.3 (set by ${PYENV_ROOT}/version)
|
||||
3.4.0
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "per-project version" {
|
||||
stub_system_python
|
||||
create_version "3.3.3"
|
||||
create_version "3.4.0"
|
||||
cat > ".python-version" <<<"3.3.3"
|
||||
run pyenv-versions
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
system
|
||||
* 3.3.3 (set by ${PYENV_TEST_DIR}/.python-version)
|
||||
3.4.0
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "ignores non-directories under versions" {
|
||||
create_version "3.3"
|
||||
touch "${PYENV_ROOT}/versions/hello"
|
||||
|
||||
run pyenv-versions --bare
|
||||
assert_success "3.3"
|
||||
}
|
||||
|
||||
@test "lists symlinks under versions" {
|
||||
create_version "2.7.8"
|
||||
create_alias "2.7" "2.7.8"
|
||||
|
||||
run pyenv-versions --bare
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
2.7
|
||||
2.7.8
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "doesn't list symlink aliases when --skip-aliases" {
|
||||
create_version "1.8.7"
|
||||
create_alias "1.8" "1.8.7"
|
||||
create_external_version "moo"
|
||||
|
||||
run pyenv-versions --bare --skip-aliases
|
||||
assert_success
|
||||
|
||||
assert_output <<OUT
|
||||
1.8.7
|
||||
moo
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "--executables lists executables everywhere and overrides other switches" {
|
||||
create_alt_executable_in_version "3.5.0" "python"
|
||||
create_alt_executable_in_version "3.5.0" "python1"
|
||||
create_alt_executable_in_version "3.6.0" "python"
|
||||
create_alt_executable_in_version "3.5.0/envs/foo" "python_foo"
|
||||
create_alt_executable_in_version "3.6.0/envs/bar" "python_bar"
|
||||
create_alias "bar" "3.6.0/envs/bar"
|
||||
create_external_version "moo"
|
||||
create_alt_executable_in_version "moo" "moopython"
|
||||
|
||||
run pyenv-versions --skip-aliases --skip-envs --executables
|
||||
assert_success
|
||||
#The sort order does not matter for this functionality. However,
|
||||
#MacOS 15 `sort` sorts differently that Linux's due to a different LC_COLLATE definition for en-US:
|
||||
#https://unix.stackexchange.com/questions/362728/why-does-gnu-sort-sort-differently-on-my-osx-machine-and-linux-machine
|
||||
#So to get a match, we have to check against the same order that the local `sort` produces
|
||||
sort <<OUT | assert_output
|
||||
moopython
|
||||
python
|
||||
python1
|
||||
python_bar
|
||||
python_foo
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "lists dot directories under versions" {
|
||||
create_version ".venv"
|
||||
|
||||
run pyenv-versions --bare
|
||||
assert_success ".venv"
|
||||
}
|
||||
|
||||
@test "sort supports version sorting" {
|
||||
create_version "1.9.0"
|
||||
create_version "1.53.0"
|
||||
create_version "1.218.0"
|
||||
create_path_executable sort <<SH
|
||||
#!$BASH
|
||||
cat >/dev/null
|
||||
if [ "\$1" == "--version-sort" ]; then
|
||||
echo "${PYENV_ROOT}/versions/1.9.0"
|
||||
echo "${PYENV_ROOT}/versions/1.53.0"
|
||||
echo "${PYENV_ROOT}/versions/1.218.0"
|
||||
else exit 1
|
||||
fi
|
||||
SH
|
||||
|
||||
run pyenv-versions --bare
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
1.9.0
|
||||
1.53.0
|
||||
1.218.0
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "sort doesn't support version sorting" {
|
||||
create_version "1.9.0"
|
||||
create_version "1.53.0"
|
||||
create_version "1.218.0"
|
||||
create_path_executable sort <<SH
|
||||
#!$BASH
|
||||
exit 1
|
||||
SH
|
||||
|
||||
run pyenv-versions --bare
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
1.218.0
|
||||
1.53.0
|
||||
1.9.0
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "non-bare output shows symlink contents" {
|
||||
stub_system_python
|
||||
create_version "1.9.0"
|
||||
create_alias "link" "1.9.0"
|
||||
|
||||
run pyenv-versions
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
* system (set by ${PYENV_ROOT}/version)
|
||||
1.9.0
|
||||
link --> 1.9.0
|
||||
OUT
|
||||
}
|
||||
23
test/whence.bats
Normal file
23
test/whence.bats
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "finds versions where present" {
|
||||
create_alt_executable_in_version "2.7" "python"
|
||||
create_alt_executable_in_version "2.7" "fab"
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
create_alt_executable_in_version "3.4" "py.test"
|
||||
|
||||
run pyenv-whence python
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
2.7
|
||||
3.4
|
||||
OUT
|
||||
|
||||
run pyenv-whence fab
|
||||
assert_success "2.7"
|
||||
|
||||
run pyenv-whence py.test
|
||||
assert_success "3.4"
|
||||
}
|
||||
221
test/which.bats
Normal file
221
test/which.bats
Normal file
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "outputs path to executable" {
|
||||
create_alt_executable_in_version "2.7" "python"
|
||||
create_alt_executable_in_version "3.4" "py.test"
|
||||
|
||||
PYENV_VERSION=2.7 run pyenv-which python
|
||||
assert_success "${PYENV_ROOT}/versions/2.7/bin/python"
|
||||
|
||||
PYENV_VERSION=3.4 run pyenv-which py.test
|
||||
assert_success "${PYENV_ROOT}/versions/3.4/bin/py.test"
|
||||
|
||||
PYENV_VERSION=3.4:2.7 run pyenv-which py.test
|
||||
assert_success "${PYENV_ROOT}/versions/3.4/bin/py.test"
|
||||
}
|
||||
|
||||
@test "searches PATH for system version" {
|
||||
create_path_executable "kill-all-humans"
|
||||
create_executable "${PYENV_ROOT}/shims" "kill-all-humans"
|
||||
|
||||
PYENV_VERSION=system run pyenv-which kill-all-humans
|
||||
assert_success "${PYENV_TEST_DIR}/bin/kill-all-humans"
|
||||
}
|
||||
|
||||
@test "searches PATH for system version (shims prepended)" {
|
||||
create_path_executable "kill-all-humans"
|
||||
create_executable "${PYENV_ROOT}/shims" "kill-all-humans"
|
||||
|
||||
PATH="${PYENV_ROOT}/shims:$PATH" PYENV_VERSION=system run pyenv-which kill-all-humans
|
||||
assert_success "${PYENV_TEST_DIR}/bin/kill-all-humans"
|
||||
}
|
||||
|
||||
@test "searches PATH for system version (shims appended)" {
|
||||
create_path_executable "kill-all-humans"
|
||||
create_executable "${PYENV_ROOT}/shims" "kill-all-humans"
|
||||
|
||||
PATH="$PATH:${PYENV_ROOT}/shims" PYENV_VERSION=system run pyenv-which kill-all-humans
|
||||
assert_success "${PYENV_TEST_DIR}/bin/kill-all-humans"
|
||||
}
|
||||
|
||||
@test "searches PATH for system version (shims spread)" {
|
||||
create_path_executable "kill-all-humans"
|
||||
create_executable "${PYENV_ROOT}/shims" "kill-all-humans"
|
||||
|
||||
PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/shims:/tmp/non-existent:$PATH:${PYENV_ROOT}/shims" \
|
||||
PYENV_VERSION=system run pyenv-which kill-all-humans
|
||||
assert_success "${PYENV_TEST_DIR}/bin/kill-all-humans"
|
||||
}
|
||||
|
||||
@test "doesn't include current directory in PATH search" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
create_executable "$PYENV_TEST_DIR" kill-all-humans
|
||||
cd "$PYENV_TEST_DIR"
|
||||
PATH="$(path_without "kill-all-humans")" PYENV_VERSION=system run -127 pyenv-which kill-all-humans
|
||||
assert_failure "pyenv: kill-all-humans: command not found"
|
||||
}
|
||||
|
||||
@test "version not installed" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
create_alt_executable_in_version "3.4" "py.test"
|
||||
PYENV_VERSION=3.3 run -127 pyenv-which py.test
|
||||
assert_failure <<OUT
|
||||
pyenv: version \`3.3' is not installed (set by PYENV_VERSION environment variable)
|
||||
pyenv: py.test: command not found
|
||||
|
||||
The \`py.test' command exists in these Python versions:
|
||||
3.4
|
||||
|
||||
Note: See 'pyenv help global' for tips on allowing multiple
|
||||
Python versions to be found at the same time.
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "versions not installed" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
create_alt_executable_in_version "3.4" "py.test"
|
||||
PYENV_VERSION=2.7:3.3 run -127 pyenv-which py.test
|
||||
assert_failure <<OUT
|
||||
pyenv: version \`2.7' is not installed (set by PYENV_VERSION environment variable)
|
||||
pyenv: version \`3.3' is not installed (set by PYENV_VERSION environment variable)
|
||||
pyenv: py.test: command not found
|
||||
|
||||
The \`py.test' command exists in these Python versions:
|
||||
3.4
|
||||
|
||||
Note: See 'pyenv help global' for tips on allowing multiple
|
||||
Python versions to be found at the same time.
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "no executable found" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
create_alt_executable_in_version "2.7" "py.test"
|
||||
PYENV_VERSION=2.7 run -127 pyenv-which fab
|
||||
assert_failure "pyenv: fab: command not found"
|
||||
}
|
||||
|
||||
@test "no executable found for system version" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
PATH="$(path_without "rake")" PYENV_VERSION=system run -127 pyenv-which rake
|
||||
assert_failure "pyenv: rake: command not found"
|
||||
}
|
||||
|
||||
@test "executable found in other versions" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
create_alt_executable_in_version "2.7" "python"
|
||||
create_alt_executable_in_version "3.3" "py.test"
|
||||
create_alt_executable_in_version "3.4" "py.test"
|
||||
|
||||
PYENV_VERSION=2.7 run -127 pyenv-which py.test
|
||||
assert_failure
|
||||
assert_output <<OUT
|
||||
pyenv: py.test: command not found
|
||||
|
||||
The \`py.test' command exists in these Python versions:
|
||||
3.3
|
||||
3.4
|
||||
|
||||
Note: See 'pyenv help global' for tips on allowing multiple
|
||||
Python versions to be found at the same time.
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "carries original IFS within hooks" {
|
||||
create_hook which hello.bash <<SH
|
||||
hellos=(\$(printf "hello\\tugly world\\nagain"))
|
||||
echo HELLO="\$(printf ":%s" "\${hellos[@]}")"
|
||||
exit
|
||||
SH
|
||||
|
||||
IFS=$' \t\n' PYENV_VERSION=system run pyenv-which anything
|
||||
assert_success
|
||||
assert_output "HELLO=:hello:ugly:world:again"
|
||||
}
|
||||
|
||||
@test "discovers version from pyenv-version-name" {
|
||||
mkdir -p "$PYENV_ROOT"
|
||||
cat > "${PYENV_ROOT}/version" <<<"3.4"
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
|
||||
mkdir -p "$PYENV_TEST_DIR"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
|
||||
PYENV_VERSION= run pyenv-which python
|
||||
assert_success "${PYENV_ROOT}/versions/3.4/bin/python"
|
||||
}
|
||||
|
||||
@test "tolerates nonexistent versions from pyenv-version-name" {
|
||||
mkdir -p "$PYENV_ROOT"
|
||||
cat > "${PYENV_ROOT}/version" <<EOF
|
||||
2.7
|
||||
3.4
|
||||
EOF
|
||||
create_alt_executable_in_version "3.4" "python"
|
||||
|
||||
mkdir -p "$PYENV_TEST_DIR"
|
||||
cd "$PYENV_TEST_DIR"
|
||||
|
||||
PYENV_VERSION= run pyenv-which python
|
||||
assert_success "${PYENV_ROOT}/versions/3.4/bin/python"
|
||||
}
|
||||
|
||||
@test "resolves pyenv-latest prefixes" {
|
||||
create_alt_executable_in_version "3.4.2" "python"
|
||||
|
||||
PYENV_VERSION=3.4 run pyenv-which python
|
||||
assert_success "${PYENV_ROOT}/versions/3.4.2/bin/python"
|
||||
}
|
||||
|
||||
@test "hooks get resolved version name" {
|
||||
create_hook which echo.bash <<!
|
||||
echo version=\$version
|
||||
exit
|
||||
!
|
||||
|
||||
create_alt_executable_in_version "3.4.2" "python"
|
||||
|
||||
PYENV_VERSION=3.4 run pyenv-which python
|
||||
assert_success "version=3.4.2"
|
||||
}
|
||||
|
||||
@test "skip advice supresses error messages" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
create_alt_executable_in_version "2.7" "python"
|
||||
create_alt_executable_in_version "3.3" "py.test"
|
||||
create_alt_executable_in_version "3.4" "py.test"
|
||||
|
||||
PYENV_VERSION=2.7 run -127 pyenv-which py.test --skip-advice
|
||||
assert_failure
|
||||
assert_output <<OUT
|
||||
pyenv: py.test: command not found
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "excludes paths in _PYENV_SHIM_PATHS_{PROGRAM} from search only for PROGRAM" {
|
||||
progname='123;wacky-prog.name ^%$#'
|
||||
envvarname="_PYENV_SHIM_PATHS_123_WACKY_PROG_NAME_____"
|
||||
create_path_executable "$progname"
|
||||
|
||||
for dir_ in "$BATS_TEST_TMPDIR/alt-path"{1,2}; do
|
||||
mkdir -p "$dir_"
|
||||
ln -s "${PYENV_TEST_DIR}/bin/$progname" "$dir_/$progname"
|
||||
eval 'export '"$envvarname"'="$dir_${'"$envvarname"':+:$'"$envvarname"'}"'
|
||||
PATH="$dir_:$PATH"
|
||||
done
|
||||
create_executable "$dir_" "normal_program"
|
||||
|
||||
run pyenv-which "$progname"
|
||||
assert_success
|
||||
assert_output <<!
|
||||
$PYENV_TEST_DIR/bin/$progname
|
||||
!
|
||||
|
||||
run pyenv-which "normal_program"
|
||||
assert_success
|
||||
assert_output <<!
|
||||
$dir_/normal_program
|
||||
!
|
||||
}
|
||||
Reference in New Issue
Block a user