From a6783f7a1061ebc87f33b9eac7938b73aa003ef3 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Mon, 8 Jul 2024 13:41:20 -0500 Subject: [PATCH] Add test cases for the CLI help menu --- crates/uv/tests/common/mod.rs | 15 + crates/uv/tests/help.rs | 809 ++++++++++++++++++++++++++++++++++ 2 files changed, 824 insertions(+) create mode 100644 crates/uv/tests/help.rs diff --git a/crates/uv/tests/common/mod.rs b/crates/uv/tests/common/mod.rs index 06661bf74661..250d3f5914fb 100644 --- a/crates/uv/tests/common/mod.rs +++ b/crates/uv/tests/common/mod.rs @@ -281,6 +281,13 @@ impl TestContext { } } + /// Create a `uv` command for testing. + pub fn command(&self) -> Command { + let mut command = Command::new(get_bin()); + self.add_shared_args(&mut command); + command + } + /// Shared behaviour for almost all test commands. /// /// * Use a temporary cache directory @@ -359,6 +366,14 @@ impl TestContext { command } + /// Create a `uv help` command with options shared across scenarios. + #[allow(clippy::unused_self)] + pub fn help(&self) -> Command { + let mut command = Command::new(get_bin()); + command.arg("help"); + command + } + /// Create a `uv sync` command with options shared across scenarios. pub fn sync(&self) -> Command { let mut command = Command::new(get_bin()); diff --git a/crates/uv/tests/help.rs b/crates/uv/tests/help.rs new file mode 100644 index 000000000000..7edc0ce2c271 --- /dev/null +++ b/crates/uv/tests/help.rs @@ -0,0 +1,809 @@ +use common::{uv_snapshot, TestContext}; + +mod common; + +#[test] +fn help() { + let context = TestContext::new_with_versions(&[]); + + // The `uv help` command should show the long help message + uv_snapshot!(context.filters(), context.help(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + An extremely fast Python package manager. + + Usage: uv [OPTIONS] + + Commands: + pip Resolve and install Python packages + tool Run and manage executable Python packages + python Manage Python installations + venv Create a virtual environment + cache Manage the cache + version Display uv's version + help Print this message or the help of the given subcommand(s) + + Options: + -q, --quiet + Do not print any output + + -v, --verbose... + Use verbose output. + + You can configure fine-grained logging using the `RUST_LOG` environment variable. + () + + --color + Control colors in output + + [default: auto] + + Possible values: + - auto: Enables colored output only when the output is going to a terminal or TTY with + support + - always: Enables colored output regardless of the detected environment + - never: Disables colored output + + --native-tls + Whether to load TLS certificates from the platform's native certificate store. + + By default, `uv` loads certificates from the bundled `webpki-roots` crate. The + `webpki-roots` are a reliable set of trust roots from Mozilla, and including them in `uv` + improves portability and performance (especially on macOS). + + However, in some cases, you may want to use the platform's native certificate store, + especially if you're relying on a corporate trust root (e.g., for a mandatory proxy) + that's included in your system's certificate store. + + [env: UV_NATIVE_TLS=] + + --offline + Disable network access, relying only on locally cached data and locally available files + + --python-preference + Whether to prefer using Python from uv or on the system + + Possible values: + - only-managed: Only use managed Python installations; never use system Python + installations + - installed: Prefer installed Python installations, only download managed Python + installations if no system Python installation is found + - managed: Prefer managed Python installations over system Python installations, even + if fetching is required + - system: Prefer system Python installations over managed Python installations + - only-system: Only use system Python installations; never use managed Python + installations + + --python-fetch + Whether to automatically download Python when required + + Possible values: + - automatic: Automatically fetch managed Python installations when needed + - manual: Do not automatically fetch managed Python installations; require explicit + installation + + -n, --no-cache + Avoid reading from or writing to the cache + + [env: UV_NO_CACHE=] + + --cache-dir [CACHE_DIR] + Path to the cache directory. + + Defaults to `$HOME/Library/Caches/uv` on macOS, `$XDG_CACHE_HOME/uv` or `$HOME/.cache/uv` + on Linux, and `{FOLDERID_LocalAppData}/uv/cache` on Windows. + + [env: UV_CACHE_DIR=] + + --config-file + The path to a `uv.toml` file to use for configuration + + [env: UV_CONFIG_FILE=] + + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version + + ----- stderr ----- + "###); +} + +#[test] +fn help_flag() { + let context = TestContext::new_with_versions(&[]); + uv_snapshot!(context.filters(), context.command().arg("--help"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + An extremely fast Python package manager. + + Usage: uv [OPTIONS] + + Commands: + pip Resolve and install Python packages + tool Run and manage executable Python packages + python Manage Python installations + venv Create a virtual environment + cache Manage the cache + version Display uv's version + help Print this message or the help of the given subcommand(s) + + Options: + -q, --quiet + Do not print any output + + -v, --verbose... + Use verbose output. + + You can configure fine-grained logging using the `RUST_LOG` environment variable. + () + + --color + Control colors in output + + [default: auto] + + Possible values: + - auto: Enables colored output only when the output is going to a terminal or TTY with + support + - always: Enables colored output regardless of the detected environment + - never: Disables colored output + + --native-tls + Whether to load TLS certificates from the platform's native certificate store. + + By default, `uv` loads certificates from the bundled `webpki-roots` crate. The + `webpki-roots` are a reliable set of trust roots from Mozilla, and including them in `uv` + improves portability and performance (especially on macOS). + + However, in some cases, you may want to use the platform's native certificate store, + especially if you're relying on a corporate trust root (e.g., for a mandatory proxy) + that's included in your system's certificate store. + + [env: UV_NATIVE_TLS=] + + --offline + Disable network access, relying only on locally cached data and locally available files + + --python-preference + Whether to prefer using Python from uv or on the system + + Possible values: + - only-managed: Only use managed Python installations; never use system Python + installations + - installed: Prefer installed Python installations, only download managed Python + installations if no system Python installation is found + - managed: Prefer managed Python installations over system Python installations, even + if fetching is required + - system: Prefer system Python installations over managed Python installations + - only-system: Only use system Python installations; never use managed Python + installations + + --python-fetch + Whether to automatically download Python when required + + Possible values: + - automatic: Automatically fetch managed Python installations when needed + - manual: Do not automatically fetch managed Python installations; require explicit + installation + + -n, --no-cache + Avoid reading from or writing to the cache + + [env: UV_NO_CACHE=] + + --cache-dir [CACHE_DIR] + Path to the cache directory. + + Defaults to `$HOME/Library/Caches/uv` on macOS, `$XDG_CACHE_HOME/uv` or `$HOME/.cache/uv` + on Linux, and `{FOLDERID_LocalAppData}/uv/cache` on Windows. + + [env: UV_CACHE_DIR=] + + --config-file + The path to a `uv.toml` file to use for configuration + + [env: UV_CONFIG_FILE=] + + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version + + ----- stderr ----- + "###); +} + +#[test] +fn help_short_flag() { + let context = TestContext::new_with_versions(&[]); + uv_snapshot!(context.filters(), context.command().arg("-h"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + An extremely fast Python package manager. + + Usage: uv [OPTIONS] + + Commands: + pip Resolve and install Python packages + tool Run and manage executable Python packages + python Manage Python installations + venv Create a virtual environment + cache Manage the cache + version Display uv's version + help Print this message or the help of the given subcommand(s) + + Options: + -q, --quiet + Do not print any output + -v, --verbose... + Use verbose output + --color + Control colors in output [default: auto] [possible values: auto, always, never] + --native-tls + Whether to load TLS certificates from the platform's native certificate store [env: + UV_NATIVE_TLS=] + --offline + Disable network access, relying only on locally cached data and locally available files + --python-preference + Whether to prefer using Python from uv or on the system [possible values: only-managed, + installed, managed, system, only-system] + --python-fetch + Whether to automatically download Python when required [possible values: automatic, + manual] + -n, --no-cache + Avoid reading from or writing to the cache [env: UV_NO_CACHE=] + --cache-dir [CACHE_DIR] + Path to the cache directory [env: UV_CACHE_DIR=] + --config-file + The path to a `uv.toml` file to use for configuration [env: UV_CONFIG_FILE=] + -h, --help + Print help (see more with '--help') + -V, --version + Print version + + ----- stderr ----- + "###); +} + +#[test] +fn help_subcommand() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.help().arg("python"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + Manage Python installations + + Usage: uv python [OPTIONS] + + Commands: + list List the available Python installations + install Download and install Python versions + find Search for a Python installation + dir Show the uv Python installation directory + uninstall Uninstall Python versions + help Print this message or the help of the given subcommand(s) + + Options: + -q, --quiet + Do not print any output + + -v, --verbose... + Use verbose output. + + You can configure fine-grained logging using the `RUST_LOG` environment variable. + () + + --color + Control colors in output + + [default: auto] + + Possible values: + - auto: Enables colored output only when the output is going to a terminal or TTY with + support + - always: Enables colored output regardless of the detected environment + - never: Disables colored output + + --native-tls + Whether to load TLS certificates from the platform's native certificate store. + + By default, `uv` loads certificates from the bundled `webpki-roots` crate. The + `webpki-roots` are a reliable set of trust roots from Mozilla, and including them in `uv` + improves portability and performance (especially on macOS). + + However, in some cases, you may want to use the platform's native certificate store, + especially if you're relying on a corporate trust root (e.g., for a mandatory proxy) + that's included in your system's certificate store. + + [env: UV_NATIVE_TLS=] + + --offline + Disable network access, relying only on locally cached data and locally available files + + --python-preference + Whether to prefer using Python from uv or on the system + + Possible values: + - only-managed: Only use managed Python installations; never use system Python + installations + - installed: Prefer installed Python installations, only download managed Python + installations if no system Python installation is found + - managed: Prefer managed Python installations over system Python installations, even + if fetching is required + - system: Prefer system Python installations over managed Python installations + - only-system: Only use system Python installations; never use managed Python + installations + + --python-fetch + Whether to automatically download Python when required + + Possible values: + - automatic: Automatically fetch managed Python installations when needed + - manual: Do not automatically fetch managed Python installations; require explicit + installation + + -n, --no-cache + Avoid reading from or writing to the cache + + [env: UV_NO_CACHE=] + + --cache-dir [CACHE_DIR] + Path to the cache directory. + + Defaults to `$HOME/Library/Caches/uv` on macOS, `$XDG_CACHE_HOME/uv` or `$HOME/.cache/uv` + on Linux, and `{FOLDERID_LocalAppData}/uv/cache` on Windows. + + [env: UV_CACHE_DIR=] + + --config-file + The path to a `uv.toml` file to use for configuration + + [env: UV_CONFIG_FILE=] + + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version + + ----- stderr ----- + "###); +} + +#[test] +fn help_subsubcommand() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.help().arg("python").arg("install"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + Download and install Python versions + + Usage: uv python install [OPTIONS] [TARGETS]... + + Arguments: + [TARGETS]... + The Python version(s) to install. + + If not provided, the requested Python version(s) will be read from the `.python-versions` + or `.python-version` files. If neither file is present, uv will check if it has installed + any Python versions. If not, it will install the latest stable version of Python. + + Options: + -f, --force + Force the installation of the requested Python, even if it is already installed + + -q, --quiet + Do not print any output + + -v, --verbose... + Use verbose output. + + You can configure fine-grained logging using the `RUST_LOG` environment variable. + () + + --color + Control colors in output + + [default: auto] + + Possible values: + - auto: Enables colored output only when the output is going to a terminal or TTY with + support + - always: Enables colored output regardless of the detected environment + - never: Disables colored output + + --native-tls + Whether to load TLS certificates from the platform's native certificate store. + + By default, `uv` loads certificates from the bundled `webpki-roots` crate. The + `webpki-roots` are a reliable set of trust roots from Mozilla, and including them in `uv` + improves portability and performance (especially on macOS). + + However, in some cases, you may want to use the platform's native certificate store, + especially if you're relying on a corporate trust root (e.g., for a mandatory proxy) + that's included in your system's certificate store. + + [env: UV_NATIVE_TLS=] + + --offline + Disable network access, relying only on locally cached data and locally available files + + --python-preference + Whether to prefer using Python from uv or on the system + + Possible values: + - only-managed: Only use managed Python installations; never use system Python + installations + - installed: Prefer installed Python installations, only download managed Python + installations if no system Python installation is found + - managed: Prefer managed Python installations over system Python installations, even + if fetching is required + - system: Prefer system Python installations over managed Python installations + - only-system: Only use system Python installations; never use managed Python + installations + + --python-fetch + Whether to automatically download Python when required + + Possible values: + - automatic: Automatically fetch managed Python installations when needed + - manual: Do not automatically fetch managed Python installations; require explicit + installation + + -n, --no-cache + Avoid reading from or writing to the cache + + [env: UV_NO_CACHE=] + + --cache-dir [CACHE_DIR] + Path to the cache directory. + + Defaults to `$HOME/Library/Caches/uv` on macOS, `$XDG_CACHE_HOME/uv` or `$HOME/.cache/uv` + on Linux, and `{FOLDERID_LocalAppData}/uv/cache` on Windows. + + [env: UV_CACHE_DIR=] + + --config-file + The path to a `uv.toml` file to use for configuration + + [env: UV_CONFIG_FILE=] + + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version + + ----- stderr ----- + "###); +} + +#[test] +fn help_flag_subcommand() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.command().arg("python").arg("--help"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + Manage Python installations + + Usage: uv python [OPTIONS] + + Commands: + list List the available Python installations + install Download and install Python versions + find Search for a Python installation + dir Show the uv Python installation directory + uninstall Uninstall Python versions + help Print this message or the help of the given subcommand(s) + + Options: + -q, --quiet + Do not print any output + + -v, --verbose... + Use verbose output. + + You can configure fine-grained logging using the `RUST_LOG` environment variable. + () + + --color + Control colors in output + + [default: auto] + + Possible values: + - auto: Enables colored output only when the output is going to a terminal or TTY with + support + - always: Enables colored output regardless of the detected environment + - never: Disables colored output + + --native-tls + Whether to load TLS certificates from the platform's native certificate store. + + By default, `uv` loads certificates from the bundled `webpki-roots` crate. The + `webpki-roots` are a reliable set of trust roots from Mozilla, and including them in `uv` + improves portability and performance (especially on macOS). + + However, in some cases, you may want to use the platform's native certificate store, + especially if you're relying on a corporate trust root (e.g., for a mandatory proxy) + that's included in your system's certificate store. + + [env: UV_NATIVE_TLS=] + + --offline + Disable network access, relying only on locally cached data and locally available files + + --python-preference + Whether to prefer using Python from uv or on the system + + Possible values: + - only-managed: Only use managed Python installations; never use system Python + installations + - installed: Prefer installed Python installations, only download managed Python + installations if no system Python installation is found + - managed: Prefer managed Python installations over system Python installations, even + if fetching is required + - system: Prefer system Python installations over managed Python installations + - only-system: Only use system Python installations; never use managed Python + installations + + --python-fetch + Whether to automatically download Python when required + + Possible values: + - automatic: Automatically fetch managed Python installations when needed + - manual: Do not automatically fetch managed Python installations; require explicit + installation + + -n, --no-cache + Avoid reading from or writing to the cache + + [env: UV_NO_CACHE=] + + --cache-dir [CACHE_DIR] + Path to the cache directory. + + Defaults to `$HOME/Library/Caches/uv` on macOS, `$XDG_CACHE_HOME/uv` or `$HOME/.cache/uv` + on Linux, and `{FOLDERID_LocalAppData}/uv/cache` on Windows. + + [env: UV_CACHE_DIR=] + + --config-file + The path to a `uv.toml` file to use for configuration + + [env: UV_CONFIG_FILE=] + + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version + + ----- stderr ----- + "###); +} + +#[test] +fn help_flag_subsubcommand() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.command().arg("python").arg("install").arg("--help"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + Download and install Python versions + + Usage: uv python install [OPTIONS] [TARGETS]... + + Arguments: + [TARGETS]... + The Python version(s) to install. + + If not provided, the requested Python version(s) will be read from the `.python-versions` + or `.python-version` files. If neither file is present, uv will check if it has installed + any Python versions. If not, it will install the latest stable version of Python. + + Options: + -f, --force + Force the installation of the requested Python, even if it is already installed + + -q, --quiet + Do not print any output + + -v, --verbose... + Use verbose output. + + You can configure fine-grained logging using the `RUST_LOG` environment variable. + () + + --color + Control colors in output + + [default: auto] + + Possible values: + - auto: Enables colored output only when the output is going to a terminal or TTY with + support + - always: Enables colored output regardless of the detected environment + - never: Disables colored output + + --native-tls + Whether to load TLS certificates from the platform's native certificate store. + + By default, `uv` loads certificates from the bundled `webpki-roots` crate. The + `webpki-roots` are a reliable set of trust roots from Mozilla, and including them in `uv` + improves portability and performance (especially on macOS). + + However, in some cases, you may want to use the platform's native certificate store, + especially if you're relying on a corporate trust root (e.g., for a mandatory proxy) + that's included in your system's certificate store. + + [env: UV_NATIVE_TLS=] + + --offline + Disable network access, relying only on locally cached data and locally available files + + --python-preference + Whether to prefer using Python from uv or on the system + + Possible values: + - only-managed: Only use managed Python installations; never use system Python + installations + - installed: Prefer installed Python installations, only download managed Python + installations if no system Python installation is found + - managed: Prefer managed Python installations over system Python installations, even + if fetching is required + - system: Prefer system Python installations over managed Python installations + - only-system: Only use system Python installations; never use managed Python + installations + + --python-fetch + Whether to automatically download Python when required + + Possible values: + - automatic: Automatically fetch managed Python installations when needed + - manual: Do not automatically fetch managed Python installations; require explicit + installation + + -n, --no-cache + Avoid reading from or writing to the cache + + [env: UV_NO_CACHE=] + + --cache-dir [CACHE_DIR] + Path to the cache directory. + + Defaults to `$HOME/Library/Caches/uv` on macOS, `$XDG_CACHE_HOME/uv` or `$HOME/.cache/uv` + on Linux, and `{FOLDERID_LocalAppData}/uv/cache` on Windows. + + [env: UV_CACHE_DIR=] + + --config-file + The path to a `uv.toml` file to use for configuration + + [env: UV_CONFIG_FILE=] + + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version + + ----- stderr ----- + "###); +} + +#[test] +fn help_unknown_subcommand() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.help().arg("foobar"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unrecognized subcommand 'foobar' + + Usage: uv [OPTIONS] + + For more information, try '--help'. + "###); + + uv_snapshot!(context.filters(), context.help().arg("foo").arg("bar"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unrecognized subcommand 'foo' + + Usage: uv [OPTIONS] + + For more information, try '--help'. + "###); +} + +#[test] +fn help_unknown_subsubcommand() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.help().arg("python").arg("foobar"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unrecognized subcommand 'foobar' + + Usage: uv python [OPTIONS] + + For more information, try '--help'. + "###); +} + +#[test] +fn help_with_global_option() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.help().arg("--cache-dir").arg("/dev/null"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unrecognized subcommand '--cache-dir' + + Usage: uv [OPTIONS] + + For more information, try '--help'. + "###); +} + +#[test] +fn help_with_help() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.help().arg("--help"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unrecognized subcommand '--help' + + Usage: uv [OPTIONS] + + For more information, try '--help'. + "###); +} + +#[test] +fn help_with_version() { + let context = TestContext::new_with_versions(&[]); + + uv_snapshot!(context.filters(), context.help().arg("--version"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unrecognized subcommand '--version' + + Usage: uv [OPTIONS] + + For more information, try '--help'. + "###); +}