mirror of
https://github.com/astral-sh/uv
synced 2026-01-21 21:40:11 -05:00
Refactor pip scenario tests (#1212)
Mostly a mechanical refactor to use the `puffin_snapshot!` and `TestContext` infrastructure in the pip compile and pip install scenarios, in preparation for adding programmatic windows testing filters.
This commit is contained in:
@@ -10,13 +10,13 @@ use std::process::Command;
|
||||
|
||||
use anyhow::Result;
|
||||
use assert_fs::fixture::{FileWriteStr, PathChild};
|
||||
use common::{create_venv, BIN_NAME, INSTA_FILTERS};
|
||||
#[cfg(unix)]
|
||||
use fs_err::os::unix::fs::symlink as symlink_file;
|
||||
#[cfg(windows)]
|
||||
use fs_err::os::windows::fs::symlink_file;
|
||||
use insta_cmd::_macro_support::insta;
|
||||
use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
|
||||
use insta_cmd::get_cargo_bin;
|
||||
|
||||
use common::{puffin_snapshot, TestContext, BIN_NAME, INSTA_FILTERS};
|
||||
use puffin_interpreter::find_requested_python;
|
||||
|
||||
mod common;
|
||||
@@ -24,19 +24,40 @@ mod common;
|
||||
/// Create a directory with the requested Python binaries available.
|
||||
pub(crate) fn create_bin_with_executables(
|
||||
temp_dir: &assert_fs::TempDir,
|
||||
python: Vec<&str>,
|
||||
python_versions: &[&str],
|
||||
) -> Result<PathBuf> {
|
||||
let bin = temp_dir.child("bin");
|
||||
fs_err::create_dir(&bin)?;
|
||||
for request in python {
|
||||
for request in python_versions {
|
||||
let executable = find_requested_python(request)?;
|
||||
let name = executable
|
||||
.file_name()
|
||||
.expect("Discovered executable must have a filename");
|
||||
symlink(&executable, bin.child(name))?;
|
||||
symlink_file(&executable, bin.child(name))?;
|
||||
}
|
||||
Ok(bin.canonicalize()?)
|
||||
}
|
||||
|
||||
/// Provision python binaries and return a `pip compile` command with options shared across all scenarios.
|
||||
fn command(context: &TestContext, python_versions: &[&str]) -> Command {
|
||||
let bin = create_bin_with_executables(&context.temp_dir, python_versions)
|
||||
.expect("Failed to create bin dir");
|
||||
let mut command = Command::new(get_cargo_bin(BIN_NAME));
|
||||
command
|
||||
.arg("pip")
|
||||
.arg("compile")
|
||||
.arg("requirements.in")
|
||||
.arg("--extra-index-url")
|
||||
.arg("https://test.pypi.org/simple")
|
||||
.arg("--cache-dir")
|
||||
.arg(context.cache_dir.path())
|
||||
.env("VIRTUAL_ENV", context.venv.as_os_str())
|
||||
.env("PUFFIN_NO_WRAP", "1")
|
||||
.env("PUFFIN_PYTHON_PATH", bin)
|
||||
.current_dir(&context.temp_dir);
|
||||
command
|
||||
}
|
||||
|
||||
{{#scenarios}}
|
||||
|
||||
/// {{name}}
|
||||
@@ -53,11 +74,8 @@ pub(crate) fn create_bin_with_executables(
|
||||
/// ```
|
||||
#[test]
|
||||
fn {{module_name}}() -> Result<()> {
|
||||
let temp_dir = assert_fs::TempDir::new()?;
|
||||
let cache_dir = assert_fs::TempDir::new()?;
|
||||
let venv = create_venv(&temp_dir, &cache_dir, "{{environment.python}}");
|
||||
let python_versions = vec![{{#environment.additional_python}}"{{.}}", {{/environment.additional_python}}];
|
||||
let bin = create_bin_with_executables(&temp_dir, python_versions)?;
|
||||
let context = TestContext::new("{{environment.python}}");
|
||||
let python_versions = &[{{#environment.additional_python}}"{{.}}", {{/environment.additional_python}}];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
@@ -66,7 +84,7 @@ fn {{module_name}}() -> Result<()> {
|
||||
{{/packages}}
|
||||
filters.push((r"-{{version}}", ""));
|
||||
|
||||
let requirements_in = temp_dir.child("requirements.in");
|
||||
let requirements_in = context.temp_dir.child("requirements.in");
|
||||
{{#root.requires}}
|
||||
requirements_in.write_str("{{requirement}}")?;
|
||||
{{/root.requires}}
|
||||
@@ -74,29 +92,15 @@ fn {{module_name}}() -> Result<()> {
|
||||
{{#expected.explanation_lines}}
|
||||
// {{.}}
|
||||
{{/expected.explanation_lines}}
|
||||
insta::with_settings!({
|
||||
filters => filters
|
||||
}, {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.arg("pip")
|
||||
.arg("compile")
|
||||
.arg("requirements.in")
|
||||
{{#environment.prereleases}}
|
||||
.arg("--prerelease=allow")
|
||||
{{/environment.prereleases}}
|
||||
{{#resolver_options.python}}
|
||||
.arg("--python-version={{.}}")
|
||||
{{/resolver_options.python}}
|
||||
.arg("--extra-index-url")
|
||||
.arg("https://test.pypi.org/simple")
|
||||
.arg("--cache-dir")
|
||||
.arg(cache_dir.path())
|
||||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||||
.env("PUFFIN_NO_WRAP", "1")
|
||||
.env("PUFFIN_PYTHON_PATH", bin)
|
||||
.current_dir(&temp_dir), @r###"<snapshot>
|
||||
"###);
|
||||
});
|
||||
puffin_snapshot!(filters, command(&context, python_versions)
|
||||
{{#environment.prereleases}}
|
||||
.arg("--prerelease=allow")
|
||||
{{/environment.prereleases}}
|
||||
{{#resolver_options.python}}
|
||||
.arg("--python-version={{.}}")
|
||||
{{/resolver_options.python}}, @r###"<snapshot>
|
||||
"###
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use anyhow::Result;
|
||||
use assert_cmd::assert::Assert;
|
||||
use assert_cmd::prelude::*;
|
||||
use insta_cmd::_macro_support::insta;
|
||||
use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
|
||||
use insta_cmd::get_cargo_bin;
|
||||
|
||||
use common::{create_venv, BIN_NAME, INSTA_FILTERS, venv_to_interpreter};
|
||||
use common::{venv_to_interpreter, BIN_NAME, INSTA_FILTERS};
|
||||
|
||||
use crate::common::{puffin_snapshot, TestContext};
|
||||
|
||||
mod common;
|
||||
|
||||
@@ -39,6 +39,23 @@ fn assert_installed(venv: &Path, package: &'static str, version: &'static str, t
|
||||
fn assert_not_installed(venv: &Path, package: &'static str, temp_dir: &Path) {
|
||||
assert_command(venv, format!("import {package}").as_str(), temp_dir).failure();
|
||||
}
|
||||
|
||||
/// Create a `pip install` command with options shared across all scenarios.
|
||||
fn command(context: &TestContext) -> Command {
|
||||
let mut command = Command::new(get_cargo_bin(BIN_NAME));
|
||||
command
|
||||
.arg("pip")
|
||||
.arg("install")
|
||||
.arg("--extra-index-url")
|
||||
.arg("https://test.pypi.org/simple")
|
||||
.arg("--cache-dir")
|
||||
.arg(context.cache_dir.path())
|
||||
.env("VIRTUAL_ENV", context.venv.as_os_str())
|
||||
.env("PUFFIN_NO_WRAP", "1")
|
||||
.current_dir(&context.temp_dir);
|
||||
command
|
||||
}
|
||||
|
||||
{{#scenarios}}
|
||||
|
||||
/// {{name}}
|
||||
@@ -54,10 +71,8 @@ fn assert_not_installed(venv: &Path, package: &'static str, temp_dir: &Path) {
|
||||
{{/tree}}
|
||||
/// ```
|
||||
#[test]
|
||||
fn {{module_name}}() -> Result<()> {
|
||||
let temp_dir = assert_fs::TempDir::new()?;
|
||||
let cache_dir = assert_fs::TempDir::new()?;
|
||||
let venv = create_venv(&temp_dir, &cache_dir, "{{environment.python}}");
|
||||
fn {{module_name}}() {
|
||||
let context = TestContext::new("{{environment.python}}");
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
@@ -66,27 +81,14 @@ fn {{module_name}}() -> Result<()> {
|
||||
{{/packages}}
|
||||
filters.push((r"-{{version}}", ""));
|
||||
|
||||
insta::with_settings!({
|
||||
filters => filters
|
||||
}, {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.arg("pip")
|
||||
.arg("install")
|
||||
{{#root.requires}}
|
||||
.arg("{{requirement}}")
|
||||
{{/root.requires}}
|
||||
{{#environment.prereleases}}
|
||||
.arg("--prerelease=allow")
|
||||
{{/environment.prereleases}}
|
||||
.arg("--extra-index-url")
|
||||
.arg("https://test.pypi.org/simple")
|
||||
.arg("--cache-dir")
|
||||
.arg(cache_dir.path())
|
||||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||||
.env("PUFFIN_NO_WRAP", "1")
|
||||
.current_dir(&temp_dir), @r###"<snapshot>
|
||||
"###);
|
||||
});
|
||||
puffin_snapshot!(filters, command(&context)
|
||||
{{#environment.prereleases}}
|
||||
.arg("--prerelease=allow")
|
||||
{{/environment.prereleases}}
|
||||
{{#root.requires}}
|
||||
.arg("{{requirement}}")
|
||||
{{/root.requires}}, @r###"<snapshot>
|
||||
"###);
|
||||
|
||||
{{#expected.explanation_lines}}
|
||||
// {{.}}
|
||||
@@ -94,19 +96,17 @@ fn {{module_name}}() -> Result<()> {
|
||||
{{#expected.satisfiable}}
|
||||
{{#expected.packages}}
|
||||
assert_installed(
|
||||
&venv,
|
||||
&context.venv,
|
||||
"{{module_name}}",
|
||||
"{{version}}",
|
||||
&temp_dir
|
||||
&context.temp_dir
|
||||
);
|
||||
{{/expected.packages}}
|
||||
{{/expected.satisfiable}}
|
||||
{{^expected.satisfiable}}
|
||||
{{#root.requires}}
|
||||
assert_not_installed(&venv, "{{module_name}}", &temp_dir);
|
||||
assert_not_installed(&context.venv, "{{module_name}}", &context.temp_dir);
|
||||
{{/root.requires}}
|
||||
{{/expected.satisfiable}}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
{{/scenarios}}
|
||||
|
||||
Reference in New Issue
Block a user