Deduplicate test command creation (#4512)

This PR refactors the command creation in the test suite to remove the
duplication.

**1)** We add the same set of test stubbing args to almost any uv
invocation in the tests:

```rust
command
    .arg("--cache-dir")
    .arg(self.cache_dir.path())
    .env("VIRTUAL_ENV", self.venv.as_os_str())
    .env("UV_NO_WRAP", "1")
    .env("HOME", self.home_dir.as_os_str())
    .env("UV_TOOLCHAIN_DIR", "")
    .env("UV_TEST_PYTHON_PATH", &self.python_path())
    .current_dir(self.temp_dir.path());

if cfg!(all(windows, debug_assertions)) {
    // TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
    // default windows stack of 1MB
    command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
```

Centralizing these into a `TestContext::add_shared_args` method removes
them from everywhere.

**2)** Prefix all `TextContext` methods of the pip interface with
`pip_`. This is now necessary due to `uv sync` vs. `uv pip sync`.

**3)** Move command creation in the various test files into dedicated
functions or methods to avoid repeating the arguments. Except for error
message tests, there should be at most one `Command::new(get_bin())`
call per test file. `EXCLUDE_NEWER` is exclusively used in
`TestContext`.

---

I'm considering adding a `TestCommand` on top of these changes (in
another PR) that holds a reference to the `TextContext`, has
`add_shared_args` as a method and uses `Fn(Self) -> Self` instead of
`Fn(&mut Self) -> Self` for methods to improved chaining.
This commit is contained in:
konsti 2024-06-26 00:06:54 +02:00 committed by GitHub
parent e1708689a9
commit e6103dcab1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 1061 additions and 1846 deletions

View file

@ -15,42 +15,8 @@ mod common;
/// Create a `cache prune` command with options shared across scenarios.
fn prune_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("cache")
.arg("prune")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
command
}
/// Create a `pip sync` command with options shared across scenarios.
fn sync_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("sync")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
command.arg("cache").arg("prune");
context.add_shared_args(&mut command);
command
}
@ -63,7 +29,8 @@ fn prune_no_op() -> Result<()> {
requirements_txt.write_str("anyio")?;
// Install a requirement, to populate the cache.
sync_command(&context)
context
.pip_sync()
.arg("requirements.txt")
.assert()
.success();
@ -91,7 +58,8 @@ fn prune_stale_directory() -> Result<()> {
requirements_txt.write_str("anyio")?;
// Install a requirement, to populate the cache.
sync_command(&context)
context
.pip_sync()
.arg("requirements.txt")
.assert()
.success();
@ -124,7 +92,8 @@ fn prune_stale_symlink() -> Result<()> {
requirements_txt.write_str("anyio")?;
// Install a requirement, to populate the cache.
sync_command(&context)
context
.pip_sync()
.arg("requirements.txt")
.assert()
.success();

View file

@ -1,20 +1,20 @@
// The `unreachable_pub` is to silence false positives in RustRover.
#![allow(dead_code, unreachable_pub)]
use assert_cmd::assert::{Assert, OutputAssertExt};
use assert_cmd::Command;
use assert_fs::assert::PathAssert;
use assert_fs::fixture::{ChildPath, PathChild, PathCreateDir, SymlinkToFile};
use predicates::prelude::predicate;
use regex::Regex;
use std::borrow::BorrowMut;
use std::env;
use std::ffi::OsString;
use std::iter::Iterator;
use std::path::{Path, PathBuf};
use std::process::Output;
use std::process::{Command, Output};
use std::str::FromStr;
use assert_cmd::assert::{Assert, OutputAssertExt};
use assert_fs::assert::PathAssert;
use assert_fs::fixture::{ChildPath, PathChild, PathCreateDir, SymlinkToFile};
use predicates::prelude::predicate;
use regex::Regex;
use uv_cache::Cache;
use uv_fs::Simplified;
use uv_toolchain::managed::InstalledToolchains;
@ -23,7 +23,7 @@ use uv_toolchain::{
};
// Exclude any packages uploaded after this date.
pub static EXCLUDE_NEWER: &str = "2024-03-25T00:00:00Z";
static EXCLUDE_NEWER: &str = "2024-03-25T00:00:00Z";
/// Using a find links url allows using `--index-url` instead of `--extra-index-url` in tests
/// to prevent dependency confusion attacks against our test suite.
@ -55,7 +55,7 @@ pub const INSTA_FILTERS: &[(&str, &str)] = &[
),
];
/// Create a context for tests which simplfiies shared behavior across tests.
/// Create a context for tests which simplifies shared behavior across tests.
///
/// * Set the current directory to a temporary directory (`temp_dir`).
/// * Set the cache dir to a different temporary directory (`cache_dir`).
@ -247,23 +247,18 @@ impl TestContext {
}
}
/// Create a `pip compile` command for testing.
pub fn compile(&self) -> std::process::Command {
let mut command = self.compile_without_exclude_newer();
command.arg("--exclude-newer").arg(EXCLUDE_NEWER);
command
}
/// Create a `pip compile` command with no `--exclude-newer` option.
/// Shared behaviour for almost all test commands.
///
/// One should avoid using this in tests to the extent possible because
/// it can result in tests failing when the index state changes. Therefore,
/// if you use this, there should be some other kind of mitigation in place.
/// For example, pinning package versions.
pub fn compile_without_exclude_newer(&self) -> std::process::Command {
let mut cmd = std::process::Command::new(get_bin());
cmd.arg("pip")
.arg("compile")
/// * Use a temporary cache directory
/// * Use a temporary virtual environment with the Python version of [`Self`]
/// * Don't wrap text output based on the terminal we're in, the test output doesn't get printed
/// but snapshotted to a string.
/// * Use a fake `HOME` to avoid accidentally changing the developer's machine.
/// * Hide other Python toolchain with `UV_TOOLCHAIN_DIR` and installed interpreters with
/// `UV_TEST_PYTHON_PATH`.
/// * Increase the stack size to avoid stack overflows on windows due to large async functions.
pub fn add_shared_args(&self, command: &mut Command) {
command
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
@ -276,32 +271,65 @@ impl TestContext {
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
cmd.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
}
cmd
/// Create a `pip compile` command for testing.
pub fn pip_compile(&self) -> Command {
let mut command = self.pip_compile_without_exclude_newer();
command.arg("--exclude-newer").arg(EXCLUDE_NEWER);
command
}
/// Create a `pip compile` command with no `--exclude-newer` option.
///
/// One should avoid using this in tests to the extent possible because
/// it can result in tests failing when the index state changes. Therefore,
/// if you use this, there should be some other kind of mitigation in place.
/// For example, pinning package versions.
pub fn pip_compile_without_exclude_newer(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("pip").arg("compile");
self.add_shared_args(&mut command);
command
}
/// Create a `pip compile` command for testing.
pub fn pip_sync(&self) -> Command {
let mut command = self.pip_sync_without_exclude_newer();
command.arg("--exclude-newer").arg(EXCLUDE_NEWER);
command
}
/// Create a `pip sync` command with no `--exclude-newer` option.
///
/// One should avoid using this in tests to the extent possible because
/// it can result in tests failing when the index state changes. Therefore,
/// if you use this, there should be some other kind of mitigation in place.
/// For example, pinning package versions.
pub fn pip_sync_without_exclude_newer(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("pip").arg("sync");
self.add_shared_args(&mut command);
command
}
/// Create a `uv venv` command
pub fn venv(&self) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
pub fn venv(&self) -> Command {
let mut command = Command::new(get_bin());
command
.arg("venv")
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("UV_CACHE_DIR", self.cache_dir.path())
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_TEST_PYTHON_PATH", &self.python_path())
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string())
.current_dir(self.temp_dir.as_os_str());
.arg(EXCLUDE_NEWER);
self.add_shared_args(&mut command);
command.env_remove("VIRTUAL_ENV");
command
}
/// Create a `pip install` command with options shared across scenarios.
pub fn install(&self) -> std::process::Command {
let mut command = self.install_without_exclude_newer();
pub fn pip_install(&self) -> Command {
let mut command = self.pip_install_without_exclude_newer();
command.arg("--exclude-newer").arg(EXCLUDE_NEWER);
command
}
@ -312,60 +340,33 @@ impl TestContext {
/// it can result in tests failing when the index state changes. Therefore,
/// if you use this, there should be some other kind of mitigation in place.
/// For example, pinning package versions.
pub fn install_without_exclude_newer(&self) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
pub fn pip_install_without_exclude_newer(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("pip").arg("install");
self.add_shared_args(&mut command);
command
.arg("pip")
.arg("install")
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_TEST_PYTHON_PATH", &self.python_path())
.current_dir(&self.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
}
/// Create a `pip uninstall` command with options shared across scenarios.
pub fn pip_uninstall(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("pip").arg("uninstall");
self.add_shared_args(&mut command);
command
}
/// Create a `uv sync` command with options shared across scenarios.
pub fn sync(&self) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
command
.arg("sync")
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.env("UV_TEST_PYTHON_PATH", &self.python_path())
.current_dir(&self.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
pub fn sync(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("sync");
self.add_shared_args(&mut command);
command
}
/// Create a `uv lock` command with options shared across scenarios.
pub fn lock(&self) -> std::process::Command {
pub fn lock(&self) -> Command {
let mut command = self.lock_without_exclude_newer();
command
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_TEST_PYTHON_PATH", &self.python_path());
command.arg("--exclude-newer").arg(EXCLUDE_NEWER);
command
}
@ -375,56 +376,28 @@ impl TestContext {
/// it can result in tests failing when the index state changes. Therefore,
/// if you use this, there should be some other kind of mitigation in place.
/// For example, pinning package versions.
pub fn lock_without_exclude_newer(&self) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
command
.arg("lock")
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_TEST_PYTHON_PATH", &self.python_path())
.current_dir(&self.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
pub fn lock_without_exclude_newer(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("lock");
self.add_shared_args(&mut command);
command
}
/// Create a `uv toolchain find` command with options shared across scenarios.
pub fn toolchain_find(&self) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
pub fn toolchain_find(&self) -> Command {
let mut command = Command::new(get_bin());
command
.arg("toolchain")
.arg("find")
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_TEST_PYTHON_PATH", &self.python_path())
.env("UV_PREVIEW", "1")
.env("UV_TOOLCHAIN_DIR", "")
.current_dir(&self.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
self.add_shared_args(&mut command);
command
}
/// Create a `uv run` command with options shared across scenarios.
pub fn run(&self) -> std::process::Command {
pub fn run(&self) -> Command {
let mut command = self.run_without_exclude_newer();
command.arg("--exclude-newer").arg(EXCLUDE_NEWER);
command
@ -436,30 +409,15 @@ impl TestContext {
/// it can result in tests failing when the index state changes. Therefore,
/// if you use this, there should be some other kind of mitigation in place.
/// For example, pinning package versions.
pub fn run_without_exclude_newer(&self) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
command
.arg("run")
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_TEST_PYTHON_PATH", &self.python_path())
.current_dir(&self.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
pub fn run_without_exclude_newer(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("run");
self.add_shared_args(&mut command);
command
}
/// Create a `uv tool run` command with options shared across scenarios.
pub fn tool_run(&self) -> std::process::Command {
pub fn tool_run(&self) -> Command {
let mut command = self.tool_run_without_exclude_newer();
command.arg("--exclude-newer").arg(EXCLUDE_NEWER);
command
@ -471,70 +429,34 @@ impl TestContext {
/// it can result in tests failing when the index state changes. Therefore,
/// if you use this, there should be some other kind of mitigation in place.
/// For example, pinning package versions.
pub fn tool_run_without_exclude_newer(&self) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
command
.arg("tool")
.arg("run")
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_TEST_PYTHON_PATH", &self.python_path())
.current_dir(&self.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
pub fn tool_run_without_exclude_newer(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("tool").arg("run");
self.add_shared_args(&mut command);
command
}
/// Create a `uv add` command for the given requirements.
pub fn add(&self, reqs: &[&str]) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
command
.arg("add")
.args(reqs)
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.current_dir(&self.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
pub fn add(&self, reqs: &[&str]) -> Command {
let mut command = Command::new(get_bin());
command.arg("add").args(reqs);
self.add_shared_args(&mut command);
command
}
/// Create a `uv remove` command for the given requirements.
pub fn remove(&self, reqs: &[&str]) -> std::process::Command {
let mut command = std::process::Command::new(get_bin());
pub fn remove(&self, reqs: &[&str]) -> Command {
let mut command = Command::new(get_bin());
command.arg("remove").args(reqs);
self.add_shared_args(&mut command);
command
.arg("remove")
.args(reqs)
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("HOME", self.home_dir.as_os_str())
.current_dir(&self.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
}
/// Create a `uv clean` command.
pub fn clean(&self) -> Command {
let mut command = Command::new(get_bin());
command.arg("clean");
self.add_shared_args(&mut command);
command
}
@ -544,7 +466,7 @@ impl TestContext {
/// Run the given python code and check whether it succeeds.
pub fn assert_command(&self, command: &str) -> Assert {
std::process::Command::new(venv_to_interpreter(&self.venv))
Command::new(venv_to_interpreter(&self.venv))
// Our tests change files in <1s, so we must disable CPython bytecode caching or we'll get stale files
// https://github.com/python/cpython/issues/75953
.arg("-B")
@ -556,7 +478,7 @@ impl TestContext {
/// Run the given python file and check whether it succeeds.
pub fn assert_file(&self, file: impl AsRef<Path>) -> Assert {
std::process::Command::new(venv_to_interpreter(&self.venv))
Command::new(venv_to_interpreter(&self.venv))
// Our tests change files in <1s, so we must disable CPython bytecode caching or we'll get stale files
// https://github.com/python/cpython/issues/75953
.arg("-B")
@ -725,7 +647,7 @@ pub fn create_venv_from_executable<P: AsRef<std::path::Path>>(
cache_dir: &assert_fs::TempDir,
python: &Path,
) {
Command::new(get_bin())
assert_cmd::Command::new(get_bin())
.arg("venv")
.arg(path.as_ref().as_os_str())
.arg("--cache-dir")
@ -801,7 +723,7 @@ pub enum WindowsFilters {
///
/// This function is derived from `insta_cmd`s `spawn_with_info`.
pub fn run_and_format<T: AsRef<str>>(
mut command: impl BorrowMut<std::process::Command>,
mut command: impl BorrowMut<Command>,
filters: impl AsRef<[(T, T)]>,
function_name: &str,
windows_filters: Option<WindowsFilters>,

View file

@ -6,45 +6,15 @@ use assert_fs::fixture::PathChild;
use common::uv_snapshot;
use crate::common::{get_bin, TestContext, EXCLUDE_NEWER};
use crate::common::{get_bin, TestContext};
mod common;
/// Create a `pip install` command with options shared across scenarios.
fn install_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("install")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
command
}
/// Create a `pip check` command with options shared across scenarios.
fn check_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("check")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
command.arg("pip").arg("check");
context.add_shared_args(&mut command);
command
}
@ -55,7 +25,8 @@ fn check_compatible_packages() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("requests==2.31.0")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -98,7 +69,8 @@ fn check_incompatible_packages() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("requests==2.31.0")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -121,7 +93,8 @@ fn check_incompatible_packages() -> Result<()> {
let requirements_txt_idna = context.temp_dir.child("requirements_idna.txt");
requirements_txt_idna.write_str("idna==2.4")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements_idna.txt")
.arg("--strict"), @r###"
@ -165,7 +138,8 @@ fn check_multiple_incompatible_packages() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("requests==2.31.0")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -188,7 +162,8 @@ fn check_multiple_incompatible_packages() -> Result<()> {
let requirements_txt_two = context.temp_dir.child("requirements_two.txt");
requirements_txt_two.write_str("idna==2.4\nurllib3==1.20")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements_two.txt")
.arg("--strict"), @r###"

File diff suppressed because it is too large Load diff

View file

@ -29,19 +29,9 @@ fn command(context: &TestContext, python_versions: &[&str]) -> Command {
.arg("--index-url")
.arg("https://astral-sh.github.io/packse/0.3.29/simple-html/")
.arg("--find-links")
.arg("https://raw.githubusercontent.com/astral-sh/packse/0.3.29/vendor/links.html")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("UV_TEST_PYTHON_PATH", python_path)
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
.arg("https://raw.githubusercontent.com/astral-sh/packse/0.3.29/vendor/links.html");
context.add_shared_args(&mut command);
command.env("UV_TEST_PYTHON_PATH", python_path);
command
}

View file

@ -7,44 +7,15 @@ use assert_cmd::prelude::*;
use assert_fs::fixture::ChildPath;
use assert_fs::prelude::*;
use crate::common::{get_bin, uv_snapshot, TestContext, EXCLUDE_NEWER};
use crate::common::{get_bin, uv_snapshot, TestContext};
mod common;
/// Create a `pip freeze` command with options shared across scenarios.
fn command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("freeze")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
command
}
/// Create a `pip install` command with options shared across scenarios.
fn sync_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("sync")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
command.arg("pip").arg("freeze");
context.add_shared_args(&mut command);
command
}
@ -57,7 +28,8 @@ fn freeze_many() -> Result<()> {
requirements_txt.write_str("MarkupSafe==2.1.3\ntomli==2.0.1")?;
// Run `pip sync`.
sync_command(&context)
context
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -90,7 +62,8 @@ fn freeze_duplicate() -> Result<()> {
requirements_txt.write_str("pip==21.3.1")?;
// Run `pip sync`.
sync_command(&context1)
context1
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -101,7 +74,8 @@ fn freeze_duplicate() -> Result<()> {
requirements_txt.write_str("pip==22.1.1")?;
// Run `pip sync`.
sync_command(&context2)
context2
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -139,7 +113,8 @@ fn freeze_url() -> Result<()> {
requirements_txt.write_str("anyio\niniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl")?;
// Run `pip sync`.
sync_command(&context)
context
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -176,7 +151,8 @@ fn freeze_with_editable() -> Result<()> {
))?;
// Run `pip sync`.
sync_command(&context)
context
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();

File diff suppressed because it is too large Load diff

View file

@ -48,19 +48,8 @@ fn command(context: &TestContext) -> Command {
.arg("--index-url")
.arg("https://astral-sh.github.io/packse/0.3.29/simple-html/")
.arg("--find-links")
.arg("https://raw.githubusercontent.com/astral-sh/packse/0.3.29/vendor/links.html")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
.arg("https://raw.githubusercontent.com/astral-sh/packse/0.3.29/vendor/links.html");
context.add_shared_args(&mut command);
command
}

View file

@ -8,30 +8,14 @@ use assert_fs::prelude::*;
use common::uv_snapshot;
use crate::common::{get_bin, TestContext, EXCLUDE_NEWER};
use crate::common::{get_bin, TestContext};
mod common;
/// Create a `pip install` command with options shared across scenarios.
fn install_command(context: &TestContext) -> Command {
fn list_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("install")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
command.arg("pip").arg("list");
context.add_shared_args(&mut command);
command
}
@ -39,16 +23,9 @@ fn install_command(context: &TestContext) -> Command {
fn list_empty_columns() {
let context = TestContext::new("3.12");
uv_snapshot!(Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(list_command(&context)
.arg("--format")
.arg("columns")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("columns"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -62,16 +39,9 @@ fn list_empty_columns() {
fn list_empty_freeze() {
let context = TestContext::new("3.12");
uv_snapshot!(Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(list_command(&context)
.arg("--format")
.arg("freeze")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("freeze"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -85,16 +55,9 @@ fn list_empty_freeze() {
fn list_empty_json() {
let context = TestContext::new("3.12");
uv_snapshot!(Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(list_command(&context)
.arg("--format")
.arg("json")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("json"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -112,7 +75,7 @@ fn list_single_no_editable() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("MarkupSafe==2.1.3")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -130,14 +93,7 @@ fn list_single_no_editable() -> Result<()> {
context.assert_command("import markupsafe").success();
uv_snapshot!(Command::new(get_bin())
.arg("pip")
.arg("list")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(list_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -157,7 +113,7 @@ fn list_editable() {
let context = TestContext::new("3.12");
// Install the editable package.
uv_snapshot!(context.filters(), install_command(&context)
uv_snapshot!(context.filters(), context.pip_install()
.arg("-e")
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
@ -181,14 +137,7 @@ fn list_editable() {
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, list_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -209,7 +158,7 @@ fn list_editable_only() {
let context = TestContext::new("3.12");
// Install the editable package.
uv_snapshot!(context.filters(), install_command(&context)
uv_snapshot!(context.filters(), context.pip_install()
.arg("-e")
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
@ -233,15 +182,8 @@ fn list_editable_only() {
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
.arg("--editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, list_command(&context)
.arg("--editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -253,15 +195,8 @@ fn list_editable_only() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
.arg("--exclude-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, list_command(&context)
.arg("--exclude-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -275,16 +210,9 @@ fn list_editable_only() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--editable")
.arg("--exclude-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--exclude-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -299,7 +227,7 @@ fn list_exclude() {
let context = TestContext::new("3.12");
// Install the editable package.
uv_snapshot!(context.filters(), install_command(&context)
uv_snapshot!(context.filters(), context.pip_install()
.arg("-e")
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
@ -323,16 +251,9 @@ fn list_exclude() {
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--exclude")
.arg("numpy")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("numpy"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -347,16 +268,9 @@ fn list_exclude() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--exclude")
.arg("poetry-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("poetry-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -370,18 +284,11 @@ fn list_exclude() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--exclude")
.arg("numpy")
.arg("--exclude")
.arg("poetry-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("poetry-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -402,7 +309,7 @@ fn list_format_json() {
let context = TestContext::new("3.12");
// Install the editable package.
uv_snapshot!(context.filters(), install_command(&context)
uv_snapshot!(context.filters(), context.pip_install()
.arg("-e")
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
@ -426,15 +333,8 @@ fn list_format_json() {
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
.arg("--format=json")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, list_command(&context)
.arg("--format=json"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -444,16 +344,9 @@ fn list_format_json() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--format=json")
.arg("--editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -463,16 +356,9 @@ fn list_format_json() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--format=json")
.arg("--exclude-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--exclude-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -482,17 +368,10 @@ fn list_format_json() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--format=json")
.arg("--editable")
.arg("--exclude-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--exclude-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -508,7 +387,8 @@ fn list_format_freeze() {
let context = TestContext::new("3.12");
// Install the editable package.
uv_snapshot!(context.filters(), install_command(&context)
uv_snapshot!(context.filters(), context
.pip_install()
.arg("-e")
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
@ -532,15 +412,8 @@ fn list_format_freeze() {
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
.arg("--format=freeze")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, list_command(&context)
.arg("--format=freeze"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -553,16 +426,9 @@ fn list_format_freeze() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--format=freeze")
.arg("--editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -572,16 +438,9 @@ fn list_format_freeze() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--format=freeze")
.arg("--exclude-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--exclude-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -593,17 +452,10 @@ fn list_format_freeze() {
"###
);
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
uv_snapshot!(filters, list_command(&context)
.arg("--format=freeze")
.arg("--editable")
.arg("--exclude-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--exclude-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -649,15 +501,8 @@ Version: 0.22.0
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
.arg("--editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, list_command(&context)
.arg("--editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -699,15 +544,8 @@ Version: 0.1-bulbasaur
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("list")
.arg("--editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, list_command(&context)
.arg("--editable"), @r###"
success: false
exit_code: 2
----- stdout -----

View file

@ -9,30 +9,14 @@ use indoc::indoc;
use common::uv_snapshot;
use crate::common::{get_bin, TestContext, EXCLUDE_NEWER};
use crate::common::{get_bin, TestContext};
mod common;
/// Create a `pip install` command with options shared across scenarios.
fn install_command(context: &TestContext) -> Command {
fn show_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("install")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
command.arg("pip").arg("show");
context.add_shared_args(&mut command);
command
}
@ -40,14 +24,7 @@ fn install_command(context: &TestContext) -> Command {
fn show_empty() {
let context = TestContext::new("3.12");
uv_snapshot!(Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(show_command(&context), @r###"
success: false
exit_code: 1
----- stdout -----
@ -65,7 +42,8 @@ fn show_requires_multiple() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("requests==2.31.0")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -86,15 +64,8 @@ fn show_requires_multiple() -> Result<()> {
);
context.assert_command("import requests").success();
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("requests")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), show_command(&context)
.arg("requests"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -120,7 +91,8 @@ fn show_python_version_marker() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("click==8.1.7")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -143,15 +115,8 @@ fn show_python_version_marker() -> Result<()> {
filters.push(("Requires: colorama", "Requires:"));
}
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("click")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, show_command(&context)
.arg("click"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -175,7 +140,8 @@ fn show_found_single_package() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("MarkupSafe==2.1.3")?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -193,15 +159,8 @@ fn show_found_single_package() -> Result<()> {
context.assert_command("import markupsafe").success();
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("markupsafe")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), show_command(&context)
.arg("markupsafe"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -229,7 +188,8 @@ fn show_found_multiple_packages() -> Result<()> {
"
})?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -248,16 +208,9 @@ fn show_found_multiple_packages() -> Result<()> {
context.assert_command("import markupsafe").success();
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
uv_snapshot!(context.filters(), show_command(&context)
.arg("markupsafe")
.arg("pip")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("pip"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -291,7 +244,8 @@ fn show_found_one_out_of_three() -> Result<()> {
"
})?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -310,17 +264,10 @@ fn show_found_one_out_of_three() -> Result<()> {
context.assert_command("import markupsafe").success();
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
uv_snapshot!(context.filters(), show_command(&context)
.arg("markupsafe")
.arg("flask")
.arg("django")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("django"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -349,7 +296,8 @@ fn show_found_one_out_of_two_quiet() -> Result<()> {
"
})?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -369,17 +317,10 @@ fn show_found_one_out_of_two_quiet() -> Result<()> {
context.assert_command("import markupsafe").success();
// Flask isn't installed, but markupsafe is, so the command should succeed.
uv_snapshot!(Command::new(get_bin())
.arg("pip")
.arg("show")
uv_snapshot!(show_command(&context)
.arg("markupsafe")
.arg("flask")
.arg("--quiet")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--quiet"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -402,7 +343,8 @@ fn show_empty_quiet() -> Result<()> {
"
})?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -422,16 +364,9 @@ fn show_empty_quiet() -> Result<()> {
context.assert_command("import markupsafe").success();
// Flask isn't installed, so the command should fail.
uv_snapshot!(Command::new(get_bin())
.arg("pip")
.arg("show")
uv_snapshot!(show_command(&context)
.arg("flask")
.arg("--quiet")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
.arg("--quiet"), @r###"
success: false
exit_code: 1
----- stdout -----
@ -448,7 +383,8 @@ fn show_editable() -> Result<()> {
let context = TestContext::new("3.12");
// Install the editable package.
install_command(&context)
context
.pip_install()
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.current_dir(current_dir()?)
@ -459,15 +395,8 @@ fn show_editable() -> Result<()> {
.assert()
.success();
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("poetry-editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), show_command(&context)
.arg("poetry-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -496,7 +425,8 @@ fn show_required_by_multiple() -> Result<()> {
"
})?;
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -521,15 +451,8 @@ fn show_required_by_multiple() -> Result<()> {
context.assert_command("import requests").success();
// idna is required by anyio and requests
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("idna")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), show_command(&context)
.arg("idna"), @r###"
success: true
exit_code: 0
----- stdout -----

File diff suppressed because it is too large Load diff

View file

@ -5,30 +5,14 @@ use assert_fs::fixture::PathChild;
use common::uv_snapshot;
use crate::common::{get_bin, TestContext, EXCLUDE_NEWER};
use crate::common::{get_bin, TestContext};
mod common;
/// Create a `pip install` command with options shared across scenarios.
fn install_command(context: &TestContext) -> Command {
fn tree_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("install")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
command.arg("pip").arg("tree");
context.add_shared_args(&mut command);
command
}
@ -36,14 +20,7 @@ fn install_command(context: &TestContext) -> Command {
fn no_package() {
let context = TestContext::new("3.12");
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -61,7 +38,8 @@ fn single_package() {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("requests==2.31.0").unwrap();
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -82,14 +60,7 @@ fn single_package() {
);
context.assert_command("import requests").success();
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -113,7 +84,8 @@ fn nested_dependencies() {
.write_str("scikit-learn==1.4.1.post1")
.unwrap();
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -133,14 +105,7 @@ fn nested_dependencies() {
"###
);
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -165,7 +130,8 @@ fn nested_dependencies_more_complex() {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("packse").unwrap();
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -212,14 +178,7 @@ fn nested_dependencies_more_complex() {
"###
);
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -280,30 +239,18 @@ fn cyclic_dependency() {
.write_str("uv-cyclic-dependencies-c")
.unwrap();
let mut command = Command::new(get_bin());
let mut command = context.pip_install_without_exclude_newer();
command
.arg("pip")
.arg("install")
.arg("-r")
.arg("requirements.txt")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--index-url")
.arg("https://test.pypi.org/simple/")
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
.arg("https://test.pypi.org/simple/");
uv_snapshot!(context.filters(), command, @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 3 packages in [TIME]
Prepared 3 packages in [TIME]
@ -314,14 +261,7 @@ fn cyclic_dependency() {
"###
);
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -344,7 +284,8 @@ fn removed_dependency() {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("requests==2.31.0").unwrap();
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -364,15 +305,9 @@ fn removed_dependency() {
"###
);
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("uninstall")
.arg("requests")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), context
.pip_uninstall()
.arg("requests"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -383,14 +318,7 @@ fn removed_dependency() {
"###
);
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -418,7 +346,8 @@ fn multiple_packages() {
)
.unwrap();
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -444,14 +373,7 @@ fn multiple_packages() {
filters.push(("colorama v0.4.6\n", ""));
}
context.assert_command("import requests").success();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -483,7 +405,8 @@ fn multiple_packages_shared_descendant() {
)
.unwrap();
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -509,14 +432,7 @@ fn multiple_packages_shared_descendant() {
"###
);
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----
@ -558,7 +474,8 @@ fn no_dedupe_and_cycle() {
)
.unwrap();
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -584,23 +501,11 @@ fn no_dedupe_and_cycle() {
"###
);
let mut command = Command::new(get_bin());
let mut command = context.pip_install_without_exclude_newer();
command
.arg("pip")
.arg("install")
.arg("uv-cyclic-dependencies-c==0.1.0")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--index-url")
.arg("https://test.pypi.org/simple/")
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
.arg("https://test.pypi.org/simple/");
uv_snapshot!(context.filters(), command, @r###"
success: true
@ -617,15 +522,8 @@ fn no_dedupe_and_cycle() {
"###
);
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--no-dedupe")
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context)
.arg("--no-dedupe"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -674,7 +572,8 @@ fn no_dedupe() {
)
.unwrap();
uv_snapshot!(install_command(&context)
uv_snapshot!(context
.pip_install()
.arg("-r")
.arg("requirements.txt")
.arg("--strict"), @r###"
@ -700,15 +599,8 @@ fn no_dedupe() {
"###
);
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--no-dedupe")
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(context.filters(), tree_command(&context)
.arg("--no-dedupe"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -742,7 +634,8 @@ fn with_editable() {
let context = TestContext::new("3.12");
// Install the editable package.
uv_snapshot!(context.filters(), install_command(&context)
uv_snapshot!(context.filters(), context
.pip_install()
.arg("-e")
.arg(context.workspace_root.join("scripts/packages/hatchling_editable")), @r###"
success: true
@ -764,14 +657,7 @@ fn with_editable() {
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("tree")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir), @r###"
uv_snapshot!(filters, tree_command(&context), @r###"
success: true
exit_code: 0
----- stdout -----

View file

@ -11,48 +11,6 @@ use crate::common::{get_bin, venv_to_interpreter, TestContext};
mod common;
/// Create a `pip uninstall` command with options shared across scenarios.
fn uninstall_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("uninstall")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
command
}
/// Create a `pip sync` command with options shared across scenarios.
fn sync_command(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("sync")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
command
}
#[test]
fn no_arguments() -> Result<()> {
let temp_dir = assert_fs::TempDir::new()?;
@ -156,7 +114,8 @@ fn uninstall() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("MarkupSafe==2.1.3")?;
sync_command(&context)
context
.pip_sync()
.arg("requirements.txt")
.assert()
.success();
@ -168,7 +127,7 @@ fn uninstall() -> Result<()> {
.assert()
.success();
uv_snapshot!(uninstall_command(&context)
uv_snapshot!(context.pip_uninstall()
.arg("MarkupSafe"), @r###"
success: true
exit_code: 0
@ -197,7 +156,8 @@ fn missing_record() -> Result<()> {
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("MarkupSafe==2.1.3")?;
sync_command(&context)
context
.pip_sync()
.arg("requirements.txt")
.assert()
.success();
@ -213,7 +173,7 @@ fn missing_record() -> Result<()> {
let dist_info = context.site_packages().join("MarkupSafe-2.1.3.dist-info");
fs_err::remove_file(dist_info.join("RECORD"))?;
uv_snapshot!(context.filters(), uninstall_command(&context)
uv_snapshot!(context.filters(), context.pip_uninstall()
.arg("MarkupSafe"), @r###"
success: false
exit_code: 2
@ -241,7 +201,8 @@ fn uninstall_editable_by_name() -> Result<()> {
.to_str()
.expect("Path is valid unicode")
))?;
sync_command(&context)
context
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -253,7 +214,7 @@ fn uninstall_editable_by_name() -> Result<()> {
.success();
// Uninstall the editable by name.
uv_snapshot!(context.filters(), uninstall_command(&context)
uv_snapshot!(context.filters(), context.pip_uninstall()
.arg("poetry-editable"), @r###"
success: true
exit_code: 0
@ -288,7 +249,8 @@ fn uninstall_by_path() -> Result<()> {
.expect("Path is valid unicode"),
)?;
sync_command(&context)
context
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -300,7 +262,7 @@ fn uninstall_by_path() -> Result<()> {
.success();
// Uninstall the editable by path.
uv_snapshot!(context.filters(), uninstall_command(&context)
uv_snapshot!(context.filters(), context.pip_uninstall()
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
@ -335,7 +297,8 @@ fn uninstall_duplicate_by_path() -> Result<()> {
.expect("Path is valid unicode"),
)?;
sync_command(&context)
context
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -347,7 +310,7 @@ fn uninstall_duplicate_by_path() -> Result<()> {
.success();
// Uninstall the editable by both path and name.
uv_snapshot!(context.filters(), uninstall_command(&context)
uv_snapshot!(context.filters(), context.pip_uninstall()
.arg("poetry-editable")
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
@ -380,7 +343,8 @@ fn uninstall_duplicate() -> Result<()> {
requirements_txt.write_str("pip==21.3.1")?;
// Run `pip sync`.
sync_command(&context1)
context1
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -391,7 +355,8 @@ fn uninstall_duplicate() -> Result<()> {
requirements_txt.write_str("pip==22.1.1")?;
// Run `pip sync`.
sync_command(&context2)
context2
.pip_sync()
.arg(requirements_txt.path())
.assert()
.success();
@ -403,7 +368,7 @@ fn uninstall_duplicate() -> Result<()> {
)?;
// Run `pip uninstall`.
uv_snapshot!(uninstall_command(&context1)
uv_snapshot!(context1.pip_uninstall()
.arg("pip"), @r###"
success: true
exit_code: 0
@ -459,7 +424,7 @@ fn uninstall_egg_info() -> Result<()> {
.write_str("")?;
// Run `pip uninstall`.
uv_snapshot!(uninstall_command(&context)
uv_snapshot!(context.pip_uninstall()
.arg("zstandard"), @r###"
success: true
exit_code: 0
@ -513,7 +478,7 @@ Version: 0.22.0
))?;
// Run `pip uninstall`.
uv_snapshot!(uninstall_command(&context)
uv_snapshot!(context.pip_uninstall()
.arg("zstandard"), @r###"
success: true
exit_code: 0

View file

@ -1,11 +1,13 @@
#![cfg(feature = "self-update")]
use crate::common::get_bin;
use std::process::Command;
use axoupdater::{
test::helpers::{perform_runtest, RuntestArgs},
ReleaseSourceType,
};
use std::process::Command;
use crate::common::get_bin;
mod common;

View file

@ -11,7 +11,7 @@ mod common;
/// Create a `pip compile` command, overwriting defaults for any settings that vary based on machine
/// and operating system.
fn command(context: &TestContext) -> Command {
let mut command = context.compile();
let mut command = context.pip_compile();
command
.env("UV_LINK_MODE", "clone")
.env("UV_CONCURRENT_DOWNLOADS", "50")

View file

@ -637,8 +637,10 @@ fn path_with_trailing_space_gives_proper_error() {
let context = TestContext::new_with_versions(&["3.12"]);
// Set a custom cache directory with a trailing space
uv_snapshot!(context.filters(), context.venv()
.env("UV_CACHE_DIR", format!("{} ", context.cache_dir.path().display())), @r###"
let path_with_trailing_slash = format!("{} ", context.cache_dir.path().display());
uv_snapshot!(context.filters(), std::process::Command::new(crate::common::get_bin())
.arg("venv")
.env("UV_CACHE_DIR", path_with_trailing_slash), @r###"
success: false
exit_code: 2
----- stdout -----

View file

@ -1,84 +1,18 @@
use std::env;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::process::Command;
use anyhow::Result;
use assert_cmd::assert::OutputAssertExt;
use crate::common::{copy_dir_ignore, get_bin, uv_snapshot, TestContext, EXCLUDE_NEWER};
use crate::common::{copy_dir_ignore, uv_snapshot, TestContext};
mod common;
/// A `pip install` command for workspaces.
///
/// The goal of the workspace tests is to resolve local workspace packages correctly. We add some
/// non-workspace dependencies to ensure that transitive non-workspace dependencies are also
/// correctly resolved.
fn install_workspace(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("pip")
.arg("install")
.arg("--preview")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.arg("-e")
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
command
}
/// A `uv run` command.
fn run_workspace(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("run")
.arg("--preview")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--python")
.arg(context.interpreter())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("UV_NO_WRAP", "1");
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
command
}
/// A `uv lock` command.
fn lock_workspace(context: &TestContext) -> Command {
let mut command = Command::new(get_bin());
command
.arg("lock")
.arg("--preview")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--python")
.arg(context.interpreter())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("UV_NO_WRAP", "1");
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
/// `pip install --preview -e <current dir>`
fn install_workspace(context: &TestContext, current_dir: &Path) -> Command {
let mut command = context.pip_install();
command.arg("--preview").arg("-e").arg(current_dir);
command
}
@ -101,7 +35,7 @@ fn test_albatross_in_examples_bird_feeder() {
.join("examples")
.join("bird-feeder");
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -118,7 +52,7 @@ fn test_albatross_in_examples_bird_feeder() {
);
context.assert_file(current_dir.join("check_installed_bird_feeder.py"));
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -136,7 +70,7 @@ fn test_albatross_in_examples() {
let context = TestContext::new("3.12");
let current_dir = workspaces_dir().join("albatross-in-example");
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -151,7 +85,7 @@ fn test_albatross_in_examples() {
);
context.assert_file(current_dir.join("check_installed_albatross.py"));
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -169,7 +103,7 @@ fn test_albatross_just_project() {
let context = TestContext::new("3.12");
let current_dir = workspaces_dir().join("albatross-just-project");
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -184,7 +118,7 @@ fn test_albatross_just_project() {
);
context.assert_file(current_dir.join("check_installed_albatross.py"));
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -205,7 +139,7 @@ fn test_albatross_project_in_excluded() {
.join("excluded")
.join("bird-feeder");
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -222,7 +156,7 @@ fn test_albatross_project_in_excluded() {
);
context.assert_file(current_dir.join("check_installed_bird_feeder.py"));
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -240,7 +174,7 @@ fn test_albatross_root_workspace() {
let context = TestContext::new("3.12");
let current_dir = workspaces_dir().join("albatross-root-workspace");
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -260,7 +194,7 @@ fn test_albatross_root_workspace() {
);
context.assert_file(current_dir.join("check_installed_albatross.py"));
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -281,7 +215,7 @@ fn test_albatross_root_workspace_bird_feeder() {
.join("packages")
.join("bird-feeder");
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -299,7 +233,7 @@ fn test_albatross_root_workspace_bird_feeder() {
);
context.assert_file(current_dir.join("check_installed_bird_feeder.py"));
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -320,7 +254,7 @@ fn test_albatross_root_workspace_albatross() {
.join("packages")
.join("bird-feeder");
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -338,7 +272,7 @@ fn test_albatross_root_workspace_albatross() {
);
context.assert_file(current_dir.join("check_installed_albatross.py"));
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -359,7 +293,7 @@ fn test_albatross_virtual_workspace() {
.join("packages")
.join("bird-feeder");
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -377,7 +311,7 @@ fn test_albatross_virtual_workspace() {
);
context.assert_file(current_dir.join("check_installed_bird_feeder.py"));
uv_snapshot!(context.filters(), install_workspace(&context).arg(&current_dir), @r###"
uv_snapshot!(context.filters(), install_workspace(&context, &current_dir), @r###"
success: true
exit_code: 0
----- stdout -----
@ -407,7 +341,9 @@ fn test_uv_run_with_package_virtual_workspace() -> Result<()> {
"Using Python 3.12.[X] interpreter at: [PYTHON]",
));
uv_snapshot!(filters, run_workspace(&context)
uv_snapshot!(filters, context
.run()
.arg("--preview")
.arg("--package")
.arg("bird-feeder")
.arg("packages/bird-feeder/check_installed_bird_feeder.py")
@ -431,7 +367,9 @@ fn test_uv_run_with_package_virtual_workspace() -> Result<()> {
"###
);
uv_snapshot!(context.filters(), universal_windows_filters=true, run_workspace(&context)
uv_snapshot!(context.filters(), universal_windows_filters=true, context
.run()
.arg("--preview")
.arg("--package")
.arg("albatross")
.arg("packages/albatross/check_installed_albatross.py")
@ -467,7 +405,9 @@ fn test_uv_run_with_package_root_workspace() -> Result<()> {
"Using Python 3.12.[X] interpreter at: [PYTHON]",
));
uv_snapshot!(filters, run_workspace(&context)
uv_snapshot!(filters, context
.run()
.arg("--preview")
.arg("--package")
.arg("bird-feeder")
.arg("packages/bird-feeder/check_installed_bird_feeder.py")
@ -491,7 +431,9 @@ fn test_uv_run_with_package_root_workspace() -> Result<()> {
"###
);
uv_snapshot!(context.filters(), universal_windows_filters=true, run_workspace(&context)
uv_snapshot!(context.filters(), universal_windows_filters=true, context
.run()
.arg("--preview")
.arg("--package")
.arg("albatross")
.arg("check_installed_albatross.py")
@ -523,7 +465,9 @@ fn workspace_lock_idempotence(workspace: &str, subdirectories: &[&str]) -> Resul
copy_dir_ignore(workspaces_dir().join(workspace), &work_dir)?;
lock_workspace(&context)
context
.lock()
.arg("--preview")
.current_dir(&work_dir.join(dir))
.assert()
.success();

View file

@ -29,19 +29,9 @@ fn command(context: &TestContext, python_versions: &[&str]) -> Command {
.arg("--index-url")
.arg("{{index_url}}")
.arg("--find-links")
.arg("{{vendor_links}}")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("UV_TEST_PYTHON_PATH", python_path)
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
.arg("{{vendor_links}}");
context.add_shared_args(&mut command);
command.env("UV_TEST_PYTHON_PATH", python_path);
command
}

View file

@ -49,19 +49,8 @@ fn command(context: &TestContext) -> Command {
.arg("--index-url")
.arg("{{index_url}}")
.arg("--find-links")
.arg("{{vendor_links}}")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.current_dir(&context.temp_dir);
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
.arg("{{vendor_links}}");
context.add_shared_args(&mut command);
command
}