From 857b3cc777007c4dd2d647ee8f14f688616c04a2 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Thu, 27 Jun 2024 06:48:19 -0400 Subject: [PATCH] Add test context utility for standardized filtering of counts (#4568) There are cases where these counts simply don't matter and we're manually tweaking them to deal with Windows. --- crates/uv/tests/common/mod.rs | 41 ++++++++++---- crates/uv/tests/pip_install.rs | 79 +++++++++----------------- crates/uv/tests/tool_install.rs | 98 ++++++++++++++------------------- 3 files changed, 97 insertions(+), 121 deletions(-) diff --git a/crates/uv/tests/common/mod.rs b/crates/uv/tests/common/mod.rs index d0dda7bf0..bf97cc87e 100644 --- a/crates/uv/tests/common/mod.rs +++ b/crates/uv/tests/common/mod.rs @@ -90,6 +90,36 @@ impl TestContext { new } + /// Add extra standard filtering for messages like "Resolved 10 packages" which + /// can differ between platforms. + /// + /// In some cases, these counts are helpful for the snapshot and should not be filtered. + #[must_use] + pub fn with_filtered_counts(mut self) -> Self { + for verb in &[ + "Resolved", + "Prepared", + "Installed", + "Uninstalled", + "Audited", + ] { + self.filters.push(( + format!("{verb} \\d+ packages?"), + format!("{verb} [N] packages"), + )); + } + self + } + + /// Add extra standard filtering for executable suffixes on the current platform e.g. + /// drops `.exe` on Windows. + #[must_use] + pub fn with_filtered_exe_suffix(mut self) -> Self { + self.filters + .push((std::env::consts::EXE_SUFFIX.to_string(), String::new())); + self + } + /// Create a new test context with multiple Python versions. /// /// Does not create a virtual environment by default, but the first Python version @@ -661,7 +691,6 @@ pub fn python_toolchains_for_versions( #[derive(Debug, Copy, Clone)] pub enum WindowsFilters { - CachedPlatform, Platform, Universal, } @@ -742,10 +771,6 @@ pub fn run_and_format>( WindowsFilters::Platform => { ["Resolved", "Prepared", "Installed", "Uninstalled"].iter() } - // When cached, "Prepared" should not change. - WindowsFilters::CachedPlatform => { - ["Resolved", "Installed", "Uninstalled"].iter() - } WindowsFilters::Universal => { ["Prepared", "Installed", "Uninstalled"].iter() } @@ -839,12 +864,6 @@ macro_rules! uv_snapshot { ::insta::assert_snapshot!(snapshot, @$snapshot); output }}; - ($filters:expr, cached_windows_filters=true, $spawnable:expr, @$snapshot:literal) => {{ - // Take a reference for backwards compatibility with the vec-expecting insta filters. - let (snapshot, output) = $crate::common::run_and_format($spawnable, &$filters, function_name!(), Some($crate::common::WindowsFilters::CachedPlatform)); - ::insta::assert_snapshot!(snapshot, @$snapshot); - output - }}; } /// diff --git a/crates/uv/tests/pip_install.rs b/crates/uv/tests/pip_install.rs index 175b8aabe..b8002f119 100644 --- a/crates/uv/tests/pip_install.rs +++ b/crates/uv/tests/pip_install.rs @@ -526,17 +526,8 @@ fn respect_installed_and_reinstall() -> Result<()> { let requirements_txt = context.temp_dir.child("requirements.txt"); requirements_txt.write_str("Flask==2.3.3")?; - let filters = if cfg!(windows) { - // Remove the colorama count on windows - context - .filters() - .into_iter() - .chain([("Resolved 8 packages", "Resolved 7 packages")]) - .collect() - } else { - context.filters() - }; - uv_snapshot!(filters, context.pip_install() + let context = context.with_filtered_counts(); + uv_snapshot!(context.filters(), context.pip_install() .arg("-r") .arg("requirements.txt") .arg("--strict"), @r###" @@ -545,10 +536,10 @@ fn respect_installed_and_reinstall() -> Result<()> { ----- stdout ----- ----- stderr ----- - Resolved 7 packages in [TIME] - Prepared 1 package in [TIME] - Uninstalled 1 package in [TIME] - Installed 1 package in [TIME] + Resolved [N] packages in [TIME] + Prepared [N] packages in [TIME] + Uninstalled [N] packages in [TIME] + Installed [N] packages in [TIME] - flask==2.3.2 + flask==2.3.3 "### @@ -558,7 +549,7 @@ fn respect_installed_and_reinstall() -> Result<()> { let requirements_txt = context.temp_dir.child("requirements.txt"); requirements_txt.write_str("Flask")?; - uv_snapshot!(filters, context.pip_install() + uv_snapshot!(context.filters(), context.pip_install() .arg("-r") .arg("requirements.txt") .arg("--reinstall-package") @@ -569,10 +560,10 @@ fn respect_installed_and_reinstall() -> Result<()> { ----- stdout ----- ----- stderr ----- - Resolved 7 packages in [TIME] - Prepared 1 package in [TIME] - Uninstalled 1 package in [TIME] - Installed 1 package in [TIME] + Resolved [N] packages in [TIME] + Prepared [N] packages in [TIME] + Uninstalled [N] packages in [TIME] + Installed [N] packages in [TIME] - flask==2.3.3 + flask==3.0.2 "### @@ -582,7 +573,7 @@ fn respect_installed_and_reinstall() -> Result<()> { let requirements_txt = context.temp_dir.child("requirements.txt"); requirements_txt.write_str("Flask")?; - uv_snapshot!(filters, context.pip_install() + uv_snapshot!(context.filters(), context.pip_install() .arg("-r") .arg("requirements.txt") .arg("--reinstall-package") @@ -593,9 +584,9 @@ fn respect_installed_and_reinstall() -> Result<()> { ----- stdout ----- ----- stderr ----- - Resolved 7 packages in [TIME] - Uninstalled 1 package in [TIME] - Installed 1 package in [TIME] + Resolved [N] packages in [TIME] + Uninstalled [N] packages in [TIME] + Installed [N] packages in [TIME] - flask==3.0.2 + flask==3.0.2 "### @@ -895,27 +886,19 @@ fn install_editable_and_registry() { "### ); - let filters: Vec<_> = context - .filters() - .into_iter() - .chain([ - // Remove colorama - ("Resolved 7 packages", "Resolved 6 packages"), - ]) - .collect(); - + let context = context.with_filtered_counts(); // Re-install Black at a specific version. This should replace the editable version. - uv_snapshot!(filters, context.pip_install() + uv_snapshot!(context.filters(), context.pip_install() .arg("black==23.10.0"), @r###" success: true exit_code: 0 ----- stdout ----- ----- stderr ----- - Resolved 6 packages in [TIME] - Prepared 1 package in [TIME] - Uninstalled 1 package in [TIME] - Installed 1 package in [TIME] + Resolved [N] packages in [TIME] + Prepared [N] packages in [TIME] + Uninstalled [N] packages in [TIME] + Installed [N] packages in [TIME] - black==0.1.0 (from file://[WORKSPACE]/scripts/packages/black_editable) + black==23.10.0 "### @@ -1770,17 +1753,7 @@ fn reinstall_no_binary() { context.assert_command("import anyio").success(); // With `--reinstall`, `--no-binary` should have an affect - let filters = if cfg!(windows) { - // Remove the colorama count on windows - context - .filters() - .into_iter() - .chain([("Resolved 8 packages", "Resolved 7 packages")]) - .collect() - } else { - context.filters() - }; - + let context = context.with_filtered_counts(); let mut command = context.pip_install(); command .arg("anyio") @@ -1789,15 +1762,15 @@ fn reinstall_no_binary() { .arg("--reinstall-package") .arg("anyio") .arg("--strict"); - uv_snapshot!(filters, command, @r###" + uv_snapshot!(context.filters(), command, @r###" success: true exit_code: 0 ----- stdout ----- ----- stderr ----- - Resolved 3 packages in [TIME] - Uninstalled 1 package in [TIME] - Installed 1 package in [TIME] + Resolved [N] packages in [TIME] + Uninstalled [N] packages in [TIME] + Installed [N] packages in [TIME] - anyio==4.3.0 + anyio==4.3.0 "### diff --git a/crates/uv/tests/tool_install.rs b/crates/uv/tests/tool_install.rs index 0d4252788..9e32db9b1 100644 --- a/crates/uv/tests/tool_install.rs +++ b/crates/uv/tests/tool_install.rs @@ -15,7 +15,7 @@ mod common; /// Test installing a tool with `uv tool install` #[test] fn tool_install() { - let context = TestContext::new("3.12"); + let context = TestContext::new("3.12").with_filtered_counts(); let tool_dir = context.temp_dir.child("tools"); let bin_dir = context.temp_dir.child("bin"); @@ -31,9 +31,9 @@ fn tool_install() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved 6 packages in [TIME] - Prepared 6 packages in [TIME] - Installed 6 packages in [TIME] + Resolved [N] packages in [TIME] + Prepared [N] packages in [TIME] + Installed [N] packages in [TIME] + black==24.3.0 + click==8.1.7 + mypy-extensions==1.0.0 @@ -91,7 +91,7 @@ fn tool_install() { "###); // Install another tool - uv_snapshot!(context.filters(), cached_windows_filters=true, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("flask") .env("UV_TOOL_DIR", tool_dir.as_os_str()) .env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###" @@ -102,9 +102,9 @@ fn tool_install() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved 7 packages in [TIME] - Prepared 6 packages in [TIME] - Installed 7 packages in [TIME] + Resolved [N] packages in [TIME] + Prepared [N] packages in [TIME] + Installed [N] packages in [TIME] + blinker==1.7.0 + click==8.1.7 + flask==3.0.2 @@ -161,19 +161,12 @@ fn tool_install() { /// Test installing and reinstalling an already installed tool #[test] fn tool_install_already_installed() { - let context = TestContext::new("3.12"); + let context = TestContext::new("3.12").with_filtered_counts(); let tool_dir = context.temp_dir.child("tools"); let bin_dir = context.temp_dir.child("bin"); - // Drop resolved counts, they differ on Windows and are not relevant here - let filters = context - .filters() - .into_iter() - .chain([("Resolved [0-9] packages", "Resolved [COUNT] packages")]) - .collect::>(); - // Install `black` - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .env("UV_TOOL_DIR", tool_dir.as_os_str()) .env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###" @@ -184,9 +177,9 @@ fn tool_install_already_installed() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved [COUNT] packages in [TIME] - Prepared 6 packages in [TIME] - Installed 6 packages in [TIME] + Resolved [N] packages in [TIME] + Prepared [N] packages in [TIME] + Installed [N] packages in [TIME] + black==24.3.0 + click==8.1.7 + mypy-extensions==1.0.0 @@ -234,7 +227,7 @@ fn tool_install_already_installed() { }); // Install `black` again - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .env("UV_TOOL_DIR", tool_dir.as_os_str()) .env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###" @@ -264,7 +257,7 @@ fn tool_install_already_installed() { // Install `black` again with the `--reinstall` flag // We should recreate the entire environment and reinstall the entry points - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .arg("--reinstall") .env("UV_TOOL_DIR", tool_dir.as_os_str()) @@ -276,8 +269,8 @@ fn tool_install_already_installed() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved [COUNT] packages in [TIME] - Installed 6 packages in [TIME] + Resolved [N] packages in [TIME] + Installed [N] packages in [TIME] + black==24.3.0 + click==8.1.7 + mypy-extensions==1.0.0 @@ -288,7 +281,7 @@ fn tool_install_already_installed() { // Install `black` again with `--reinstall-package` for `black` // We should reinstall `black` in the environment and reinstall the entry points - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .arg("--reinstall-package") .arg("black") @@ -301,16 +294,16 @@ fn tool_install_already_installed() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved [COUNT] packages in [TIME] - Uninstalled 1 package in [TIME] - Installed 1 package in [TIME] + Resolved [N] packages in [TIME] + Uninstalled [N] packages in [TIME] + Installed [N] packages in [TIME] - black==24.3.0 + black==24.3.0 "###); // Install `black` again with `--reinstall-package` for a dependency // We should reinstall `click` in the environment but not reinstall the entry points - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .arg("--reinstall-package") .arg("click") @@ -322,9 +315,9 @@ fn tool_install_already_installed() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved [COUNT] packages in [TIME] - Uninstalled 1 package in [TIME] - Installed 1 package in [TIME] + Resolved [N] packages in [TIME] + Uninstalled [N] packages in [TIME] + Installed [N] packages in [TIME] - click==8.1.7 + click==8.1.7 Updated environment for tool `black` @@ -334,26 +327,17 @@ fn tool_install_already_installed() { /// Test installing a tool when its entry point already exists #[test] fn tool_install_entry_point_exists() { - let context = TestContext::new("3.12"); + let context = TestContext::new("3.12") + .with_filtered_counts() + .with_filtered_exe_suffix(); let tool_dir = context.temp_dir.child("tools"); let bin_dir = context.temp_dir.child("bin"); let executable = bin_dir.child(format!("black{}", std::env::consts::EXE_SUFFIX)); executable.touch().unwrap(); - // Drop executable suffixes for cross-platform snapshots - // Drop resolved counts, they differ on Windows and are not relevant here - let filters = context - .filters() - .into_iter() - .chain([ - (std::env::consts::EXE_SUFFIX, ""), - ("Resolved [0-9] packages", "Resolved [COUNT] packages"), - ]) - .collect::>(); - // Attempt to install `black` - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .env("UV_TOOL_DIR", tool_dir.as_os_str()) .env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###" @@ -363,9 +347,9 @@ fn tool_install_entry_point_exists() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved [COUNT] packages in [TIME] - Prepared 6 packages in [TIME] - Installed 6 packages in [TIME] + Resolved [N] packages in [TIME] + Prepared [N] packages in [TIME] + Installed [N] packages in [TIME] + black==24.3.0 + click==8.1.7 + mypy-extensions==1.0.0 @@ -391,7 +375,7 @@ fn tool_install_entry_point_exists() { // Attempt to install `black` with the `--reinstall` flag // Should have no effect - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .arg("--reinstall") .env("UV_TOOL_DIR", tool_dir.as_os_str()) @@ -402,8 +386,8 @@ fn tool_install_entry_point_exists() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved [COUNT] packages in [TIME] - Installed 6 packages in [TIME] + Resolved [N] packages in [TIME] + Installed [N] packages in [TIME] + black==24.3.0 + click==8.1.7 + mypy-extensions==1.0.0 @@ -432,7 +416,7 @@ fn tool_install_entry_point_exists() { .child(format!("blackd{}", std::env::consts::EXE_SUFFIX)) .touch() .unwrap(); - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .env("UV_TOOL_DIR", tool_dir.as_os_str()) .env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###" @@ -442,8 +426,8 @@ fn tool_install_entry_point_exists() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved [COUNT] packages in [TIME] - Installed 6 packages in [TIME] + Resolved [N] packages in [TIME] + Installed [N] packages in [TIME] + black==24.3.0 + click==8.1.7 + mypy-extensions==1.0.0 @@ -454,7 +438,7 @@ fn tool_install_entry_point_exists() { "###); // Install `black` with `--force` - uv_snapshot!(filters, context.tool_install() + uv_snapshot!(context.filters(), context.tool_install() .arg("black") .arg("--force") .env("UV_TOOL_DIR", tool_dir.as_os_str()) @@ -466,8 +450,8 @@ fn tool_install_entry_point_exists() { ----- stderr ----- warning: `uv tool install` is experimental and may change without warning. - Resolved [COUNT] packages in [TIME] - Installed 6 packages in [TIME] + Resolved [N] packages in [TIME] + Installed [N] packages in [TIME] + black==24.3.0 + click==8.1.7 + mypy-extensions==1.0.0