diff --git a/Cargo.lock b/Cargo.lock index 5ad0f4e0515..07f76e8ecd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3209,9 +3209,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snapbox" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad8c7be18cc9ec7f4d7948ad6b9df0e04fc649663e3c0ed59f304ed17ca69e9" +checksum = "94204b12a4d3550420babdb4148c6639692e4e3e61060866929c5107f208aeb6" dependencies = [ "anstream", "anstyle", diff --git a/Cargo.toml b/Cargo.toml index 36dbed8218a..b88e0b3fd9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,7 @@ sha1 = "0.10.6" sha2 = "0.10.8" shell-escape = "0.1.5" supports-hyperlinks = "3.0.0" -snapbox = { version = "0.6.5", features = ["diff", "dir", "term-svg", "regex"] } +snapbox = { version = "0.6.7", features = ["diff", "dir", "term-svg", "regex"] } tar = { version = "0.4.40", default-features = false } tempfile = "3.10.1" thiserror = "1.0.59" diff --git a/crates/cargo-test-support/src/compare.rs b/crates/cargo-test-support/src/compare.rs index 2d33c61109c..53b752621de 100644 --- a/crates/cargo-test-support/src/compare.rs +++ b/crates/cargo-test-support/src/compare.rs @@ -40,13 +40,14 @@ use crate::diff; use crate::paths; use anyhow::{bail, Context, Result}; use serde_json::Value; -use std::env; use std::fmt; use std::path::Path; use std::str; use url::Url; -/// Default `snapbox` Assertions +/// Assertion policy for UI tests +/// +/// This emphasizes showing as much content as possible at the cost of more brittleness /// /// # Snapshots /// @@ -82,7 +83,7 @@ pub fn assert_ui() -> snapbox::Assert { let root_url = url::Url::from_file_path(&root).unwrap().to_string(); let mut subs = snapbox::Redactions::new(); - subs.extend([("[EXE]", std::env::consts::EXE_SUFFIX)]) + subs.extend(MIN_LITERAL_REDACTIONS.into_iter().cloned()) .unwrap(); subs.insert("[ROOT]", root).unwrap(); subs.insert("[ROOTURL]", root_url).unwrap(); @@ -96,6 +97,121 @@ pub fn assert_ui() -> snapbox::Assert { .redact_with(subs) } +/// Assertion policy for functional end-to-end tests +/// +/// This emphasizes showing as much content as possible at the cost of more brittleness +/// +/// # Snapshots +/// +/// Updating of snapshots is controlled with the `SNAPSHOTS` environment variable: +/// +/// - `skip`: do not run the tests +/// - `ignore`: run the tests but ignore their failure +/// - `verify`: run the tests +/// - `overwrite`: update the snapshots based on the output of the tests +/// +/// # Patterns +/// +/// - `[..]` is a character wildcard, stopping at line breaks +/// - `\n...\n` is a multi-line wildcard +/// - `[EXE]` matches the exe suffix for the current platform +/// - `[ROOT]` matches [`paths::root()`][crate::paths::root] +/// - `[ROOTURL]` matches [`paths::root()`][crate::paths::root] as a URL +/// +/// # Normalization +/// +/// In addition to the patterns described above, text is normalized +/// in such a way to avoid unwanted differences. The normalizations are: +/// +/// - Backslashes are converted to forward slashes to deal with Windows paths. +/// This helps so that all tests can be written assuming forward slashes. +/// Other heuristics are applied to try to ensure Windows-style paths aren't +/// a problem. +/// - Carriage returns are removed, which can help when running on Windows. +pub fn assert_e2e() -> snapbox::Assert { + let root = paths::root(); + // Use `from_file_path` instead of `from_dir_path` so the trailing slash is + // put in the users output, rather than hidden in the variable + let root_url = url::Url::from_file_path(&root).unwrap().to_string(); + + let mut subs = snapbox::Redactions::new(); + subs.extend(MIN_LITERAL_REDACTIONS.into_iter().cloned()) + .unwrap(); + subs.extend(E2E_LITERAL_REDACTIONS.into_iter().cloned()) + .unwrap(); + subs.insert("[ROOT]", root).unwrap(); + subs.insert("[ROOTURL]", root_url).unwrap(); + subs.insert( + "[ELAPSED]", + regex::Regex::new("[FINISHED].*in (?[0-9]+(\\.[0-9]+))s").unwrap(), + ) + .unwrap(); + snapbox::Assert::new() + .action_env(snapbox::assert::DEFAULT_ACTION_ENV) + .redact_with(subs) +} + +static MIN_LITERAL_REDACTIONS: &[(&str, &str)] = &[ + ("[EXE]", std::env::consts::EXE_SUFFIX), + ("[BROKEN_PIPE]", "Broken pipe (os error 32)"), + ("[BROKEN_PIPE]", "The pipe is being closed. (os error 232)"), +]; +static E2E_LITERAL_REDACTIONS: &[(&str, &str)] = &[ + ("[RUNNING]", " Running"), + ("[COMPILING]", " Compiling"), + ("[CHECKING]", " Checking"), + ("[COMPLETED]", " Completed"), + ("[CREATED]", " Created"), + ("[CREATING]", " Creating"), + ("[CREDENTIAL]", " Credential"), + ("[DOWNGRADING]", " Downgrading"), + ("[FINISHED]", " Finished"), + ("[ERROR]", "error:"), + ("[WARNING]", "warning:"), + ("[NOTE]", "note:"), + ("[HELP]", "help:"), + ("[DOCUMENTING]", " Documenting"), + ("[SCRAPING]", " Scraping"), + ("[FRESH]", " Fresh"), + ("[DIRTY]", " Dirty"), + ("[LOCKING]", " Locking"), + ("[UPDATING]", " Updating"), + ("[ADDING]", " Adding"), + ("[REMOVING]", " Removing"), + ("[REMOVED]", " Removed"), + ("[UNCHANGED]", " Unchanged"), + ("[DOCTEST]", " Doc-tests"), + ("[PACKAGING]", " Packaging"), + ("[PACKAGED]", " Packaged"), + ("[DOWNLOADING]", " Downloading"), + ("[DOWNLOADED]", " Downloaded"), + ("[UPLOADING]", " Uploading"), + ("[UPLOADED]", " Uploaded"), + ("[VERIFYING]", " Verifying"), + ("[ARCHIVING]", " Archiving"), + ("[INSTALLING]", " Installing"), + ("[REPLACING]", " Replacing"), + ("[UNPACKING]", " Unpacking"), + ("[SUMMARY]", " Summary"), + ("[FIXED]", " Fixed"), + ("[FIXING]", " Fixing"), + ("[IGNORED]", " Ignored"), + ("[INSTALLED]", " Installed"), + ("[REPLACED]", " Replaced"), + ("[BUILDING]", " Building"), + ("[LOGIN]", " Login"), + ("[LOGOUT]", " Logout"), + ("[YANK]", " Yank"), + ("[OWNER]", " Owner"), + ("[MIGRATING]", " Migrating"), + ("[EXECUTABLE]", " Executable"), + ("[SKIPPING]", " Skipping"), + ("[WAITING]", " Waiting"), + ("[PUBLISHED]", " Published"), + ("[BLOCKING]", " Blocking"), + ("[GENERATED]", " Generated"), +]; + /// Normalizes the output so that it can be compared against the expected value. fn normalize_actual(actual: &str, cwd: Option<&Path>) -> String { // It's easier to read tabs in outputs if they don't show up as literal @@ -185,64 +301,11 @@ fn normalize_windows(text: &str, cwd: Option<&Path>) -> String { } fn substitute_macros(input: &str) -> String { - let macros = [ - ("[RUNNING]", " Running"), - ("[COMPILING]", " Compiling"), - ("[CHECKING]", " Checking"), - ("[COMPLETED]", " Completed"), - ("[CREATED]", " Created"), - ("[CREATING]", " Creating"), - ("[CREDENTIAL]", " Credential"), - ("[DOWNGRADING]", " Downgrading"), - ("[FINISHED]", " Finished"), - ("[ERROR]", "error:"), - ("[WARNING]", "warning:"), - ("[NOTE]", "note:"), - ("[HELP]", "help:"), - ("[DOCUMENTING]", " Documenting"), - ("[SCRAPING]", " Scraping"), - ("[FRESH]", " Fresh"), - ("[DIRTY]", " Dirty"), - ("[LOCKING]", " Locking"), - ("[UPDATING]", " Updating"), - ("[ADDING]", " Adding"), - ("[REMOVING]", " Removing"), - ("[REMOVED]", " Removed"), - ("[UNCHANGED]", " Unchanged"), - ("[DOCTEST]", " Doc-tests"), - ("[PACKAGING]", " Packaging"), - ("[PACKAGED]", " Packaged"), - ("[DOWNLOADING]", " Downloading"), - ("[DOWNLOADED]", " Downloaded"), - ("[UPLOADING]", " Uploading"), - ("[UPLOADED]", " Uploaded"), - ("[VERIFYING]", " Verifying"), - ("[ARCHIVING]", " Archiving"), - ("[INSTALLING]", " Installing"), - ("[REPLACING]", " Replacing"), - ("[UNPACKING]", " Unpacking"), - ("[SUMMARY]", " Summary"), - ("[FIXED]", " Fixed"), - ("[FIXING]", " Fixing"), - ("[EXE]", env::consts::EXE_SUFFIX), - ("[IGNORED]", " Ignored"), - ("[INSTALLED]", " Installed"), - ("[REPLACED]", " Replaced"), - ("[BUILDING]", " Building"), - ("[LOGIN]", " Login"), - ("[LOGOUT]", " Logout"), - ("[YANK]", " Yank"), - ("[OWNER]", " Owner"), - ("[MIGRATING]", " Migrating"), - ("[EXECUTABLE]", " Executable"), - ("[SKIPPING]", " Skipping"), - ("[WAITING]", " Waiting"), - ("[PUBLISHED]", " Published"), - ("[BLOCKING]", " Blocking"), - ("[GENERATED]", " Generated"), - ]; let mut result = input.to_owned(); - for &(pat, subst) in ¯os { + for &(pat, subst) in MIN_LITERAL_REDACTIONS { + result = result.replace(pat, subst) + } + for &(pat, subst) in E2E_LITERAL_REDACTIONS { result = result.replace(pat, subst) } result @@ -254,7 +317,7 @@ fn substitute_macros(input: &str) -> String { /// /// - `description` explains where the output is from (usually "stdout" or "stderr"). /// - `other_output` is other output to display in the error (usually stdout or stderr). -pub fn match_exact( +pub(crate) fn match_exact( expected: &str, actual: &str, description: &str, @@ -282,7 +345,7 @@ pub fn match_exact( /// Convenience wrapper around [`match_exact`] which will panic on error. #[track_caller] -pub fn assert_match_exact(expected: &str, actual: &str) { +pub(crate) fn assert_match_exact(expected: &str, actual: &str) { if let Err(e) = match_exact(expected, actual, "", "", None) { crate::panic_error("", e); } @@ -292,7 +355,7 @@ pub fn assert_match_exact(expected: &str, actual: &str) { /// of the lines. /// /// See [Patterns](index.html#patterns) for more information on pattern matching. -pub fn match_unordered(expected: &str, actual: &str, cwd: Option<&Path>) -> Result<()> { +pub(crate) fn match_unordered(expected: &str, actual: &str, cwd: Option<&Path>) -> Result<()> { let expected = normalize_expected(expected, cwd); let actual = normalize_actual(actual, cwd); let e: Vec<_> = expected.lines().map(|line| WildStr::new(line)).collect(); @@ -342,7 +405,7 @@ pub fn match_unordered(expected: &str, actual: &str, cwd: Option<&Path>) -> Resu /// somewhere. /// /// See [Patterns](index.html#patterns) for more information on pattern matching. -pub fn match_contains(expected: &str, actual: &str, cwd: Option<&Path>) -> Result<()> { +pub(crate) fn match_contains(expected: &str, actual: &str, cwd: Option<&Path>) -> Result<()> { let expected = normalize_expected(expected, cwd); let actual = normalize_actual(actual, cwd); let e: Vec<_> = expected.lines().map(|line| WildStr::new(line)).collect(); @@ -369,7 +432,11 @@ pub fn match_contains(expected: &str, actual: &str, cwd: Option<&Path>) -> Resul /// anywhere. /// /// See [Patterns](index.html#patterns) for more information on pattern matching. -pub fn match_does_not_contain(expected: &str, actual: &str, cwd: Option<&Path>) -> Result<()> { +pub(crate) fn match_does_not_contain( + expected: &str, + actual: &str, + cwd: Option<&Path>, +) -> Result<()> { if match_contains(expected, actual, cwd).is_ok() { bail!( "expected not to find:\n\ @@ -388,7 +455,7 @@ pub fn match_does_not_contain(expected: &str, actual: &str, cwd: Option<&Path>) /// somewhere, and should be repeated `number` times. /// /// See [Patterns](index.html#patterns) for more information on pattern matching. -pub fn match_contains_n( +pub(crate) fn match_contains_n( expected: &str, number: usize, actual: &str, @@ -425,7 +492,7 @@ pub fn match_contains_n( /// /// See [`crate::Execs::with_stderr_line_without`] for an example and cautions /// against using. -pub fn match_with_without( +pub(crate) fn match_with_without( actual: &str, with: &[String], without: &[String], @@ -473,7 +540,7 @@ pub fn match_with_without( /// expected JSON objects. /// /// See [`crate::Execs::with_json`] for more details. -pub fn match_json(expected: &str, actual: &str, cwd: Option<&Path>) -> Result<()> { +pub(crate) fn match_json(expected: &str, actual: &str, cwd: Option<&Path>) -> Result<()> { let (exp_objs, act_objs) = collect_json_objects(expected, actual)?; if exp_objs.len() != act_objs.len() { bail!( @@ -494,7 +561,7 @@ pub fn match_json(expected: &str, actual: &str, cwd: Option<&Path>) -> Result<() /// /// See [`crate::Execs::with_json_contains_unordered`] for more details and /// cautions when using. -pub fn match_json_contains_unordered( +pub(crate) fn match_json_contains_unordered( expected: &str, actual: &str, cwd: Option<&Path>, @@ -552,7 +619,11 @@ fn collect_json_objects( /// as paths). You can use a `"{...}"` string literal as a wildcard for /// arbitrary nested JSON (useful for parts of object emitted by other programs /// (e.g., rustc) rather than Cargo itself). -pub fn find_json_mismatch(expected: &Value, actual: &Value, cwd: Option<&Path>) -> Result<()> { +pub(crate) fn find_json_mismatch( + expected: &Value, + actual: &Value, + cwd: Option<&Path>, +) -> Result<()> { match find_json_mismatch_r(expected, actual, cwd) { Some((expected_part, actual_part)) => bail!( "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n", @@ -619,7 +690,7 @@ fn find_json_mismatch_r<'a>( } /// A single line string that supports `[..]` wildcard matching. -pub struct WildStr<'a> { +pub(crate) struct WildStr<'a> { has_meta: bool, line: &'a str, } diff --git a/crates/cargo-test-support/src/lib.rs b/crates/cargo-test-support/src/lib.rs index 48391b400a8..5db67b8ea90 100644 --- a/crates/cargo-test-support/src/lib.rs +++ b/crates/cargo-test-support/src/lib.rs @@ -76,6 +76,7 @@ pub mod prelude { pub use crate::CargoCommand; pub use crate::ChannelChanger; pub use crate::TestEnv; + pub use snapbox::IntoData; } /* diff --git a/tests/testsuite/alt_registry.rs b/tests/testsuite/alt_registry.rs index 1fef04e3ae4..68466d0d005 100644 --- a/tests/testsuite/alt_registry.rs +++ b/tests/testsuite/alt_registry.rs @@ -1,8 +1,9 @@ //! Tests for alternative registries. -use cargo_test_support::compare::assert_match_exact; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::publish::validate_alt_upload; use cargo_test_support::registry::{self, Package, RegistryBuilder}; +use cargo_test_support::str; use cargo_test_support::{basic_manifest, paths, project}; use std::fs; @@ -1476,9 +1477,10 @@ fn sparse_lockfile() { .build(); p.cargo("generate-lockfile").run(); - assert_match_exact( + assert_e2e().eq( &p.read_lockfile(), - r#"# This file is automatically @generated by Cargo. + str![[r##" +# This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 @@ -1492,8 +1494,10 @@ dependencies = [ [[package]] name = "foo" version = "0.1.0" -source = "sparse+http://[..]/" -checksum = "458c1addb23fde7dfbca0410afdbcc0086f96197281ec304d9e0e10def3cb899""#, +source = "sparse+http://127.0.0.1:[..]/index/" +checksum = "458c1addb23fde7dfbca0410afdbcc0086f96197281ec304d9e0e10def3cb899" + +"##]], ); } diff --git a/tests/testsuite/artifact_dep.rs b/tests/testsuite/artifact_dep.rs index 7194b4a61f6..b8234140f7f 100644 --- a/tests/testsuite/artifact_dep.rs +++ b/tests/testsuite/artifact_dep.rs @@ -1,8 +1,9 @@ //! Tests specific to artifact dependencies, designated using //! the new `dep = { artifact = "bin", … }` syntax in manifests. -use cargo_test_support::compare; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::registry::{Package, RegistryBuilder}; +use cargo_test_support::str; use cargo_test_support::{ basic_bin_manifest, basic_manifest, cross_compile, project, publish, registry, rustc_host, Project, @@ -595,25 +596,31 @@ fn build_script_with_bin_artifacts() { let build_script_output = build_script_output_string(&p, "foo"); // we need the binary directory for this artifact along with all binary paths if cfg!(target_env = "msvc") { - compare::assert_match_exact( - "[..]/artifact/bar-[..]/bin/baz.exe\n\ - [..]/artifact/bar-[..]/staticlib/bar-[..].lib\n\ - [..]/artifact/bar-[..]/cdylib/bar.dll\n\ - [..]/artifact/bar-[..]/bin\n\ - [..]/artifact/bar-[..]/bin/bar.exe\n\ - [..]/artifact/bar-[..]/bin/bar.exe", + assert_e2e().eq( &build_script_output, - ) + str![[r#" +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/bin/baz[EXE] +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/staticlib/bar-[..].lib +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/cdylib/bar.dll +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/bin +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/bin/bar[EXE] +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/bin/bar[EXE] + +"#]], + ); } else { - compare::assert_match_exact( - "[..]/artifact/bar-[..]/bin/baz-[..]\n\ - [..]/artifact/bar-[..]/staticlib/libbar-[..].a\n\ - [..]/artifact/bar-[..]/cdylib/[..]bar.[..]\n\ - [..]/artifact/bar-[..]/bin\n\ - [..]/artifact/bar-[..]/bin/bar-[..]\n\ - [..]/artifact/bar-[..]/bin/bar-[..]", + assert_e2e().eq( &build_script_output, - ) + str![[r#" +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/bin/baz-[..] +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/staticlib/libbar-[..].a +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/cdylib/[..]bar.[..] +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/bin +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/bin/bar-[..] +[ROOT]/foo/target/debug/deps/artifact/bar-[..]/bin/bar-[..] + +"#]], + ); } assert!( @@ -777,19 +784,22 @@ fn build_script_with_selected_dashed_bin_artifact_and_lib_true() { let build_script_output = build_script_output_string(&p, "foo"); // we need the binary directory for this artifact and the binary itself if cfg!(target_env = "msvc") { - compare::assert_match_exact( - &format!( - "[..]/artifact/bar-baz-[..]/bin\n\ - [..]/artifact/bar-baz-[..]/bin/baz_suffix{}", - std::env::consts::EXE_SUFFIX, - ), + assert_e2e().eq( &build_script_output, + str![[r#" +[ROOT]/foo/target/debug/deps/artifact/bar-baz-[..]/bin +[ROOT]/foo/target/debug/deps/artifact/bar-baz-[..]/bin/baz_suffix[EXE] + +"#]], ); } else { - compare::assert_match_exact( - "[..]/artifact/bar-baz-[..]/bin\n\ - [..]/artifact/bar-baz-[..]/bin/baz_suffix-[..]", + assert_e2e().eq( &build_script_output, + str![[r#" +[ROOT]/foo/target/debug/deps/artifact/bar-baz-[..]/bin +[ROOT]/foo/target/debug/deps/artifact/bar-baz-[..]/bin/baz_suffix-[..] + +"#]], ); } @@ -1740,7 +1750,14 @@ fn allow_dep_renames_with_multiple_versions() { .with_stderr_contains("[COMPILING] foo [..]") .run(); let build_script_output = build_script_output_string(&p, "foo"); - compare::assert_match_exact("0.5.0\n1.0.0", &build_script_output); + assert_e2e().eq( + &build_script_output, + str![[r#" +0.5.0 +1.0.0 + +"#]], + ); } #[cargo_test] @@ -3216,9 +3233,13 @@ fn build_only_specified_artifact_library() { .cargo("build -Z bindeps") .masquerade_as_nightly_cargo(&["bindeps"]) .run(); - compare::assert_match_exact( - "cdylib present: true\nstaticlib present: false", + assert_e2e().eq( &build_script_output_string(&cdylib, "foo"), + str![[r#" +cdylib present: true +staticlib present: false + +"#]], ); let staticlib = create_project("staticlib"); @@ -3226,8 +3247,12 @@ fn build_only_specified_artifact_library() { .cargo("build -Z bindeps") .masquerade_as_nightly_cargo(&["bindeps"]) .run(); - compare::assert_match_exact( - "cdylib present: false\nstaticlib present: true", + assert_e2e().eq( &build_script_output_string(&staticlib, "foo"), + str![[r#" +cdylib present: false +staticlib present: true + +"#]], ); } diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 32b5048d160..6fb2d416c75 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -6,10 +6,13 @@ use cargo::{ ops::CompileOptions, GlobalContext, }; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::paths::{root, CargoPathExt}; +use cargo_test_support::prelude::*; use cargo_test_support::registry::Package; +use cargo_test_support::str; use cargo_test_support::{ - basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, cargo_process, compare, git, + basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, cargo_process, git, is_nightly, main_file, paths, process, project, rustc_host, sleep_ms, symlink_supported, t, tools, Execs, ProjectBuilder, }; @@ -6448,17 +6451,17 @@ fn close_output() { }; let stderr = spawn(false); - compare::match_unordered( - "\ -[COMPILING] foo [..] + assert_e2e().eq( + &stderr, + str![[r#" +[COMPILING] foo v0.1.0 ([ROOT]/foo) hello stderr! -[ERROR] [..] +[ERROR] [BROKEN_PIPE] [WARNING] build failed, waiting for other jobs to finish... -", - &stderr, - None, - ) - .unwrap(); + +"#]] + .unordered(), + ); // Try again with stderr. p.build_dir().rm_rf(); diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index ef76309233b..1b770cdf1fa 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -1,9 +1,10 @@ //! Tests for build.rs scripts. -use cargo_test_support::compare::assert_match_exact; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::install::cargo_home; use cargo_test_support::paths::CargoPathExt; use cargo_test_support::registry::Package; +use cargo_test_support::str; use cargo_test_support::tools; use cargo_test_support::{ basic_manifest, cargo_exe, cross_compile, is_coarse_mtime, project, project_in, @@ -3398,9 +3399,12 @@ fn generate_good_d_files() { println!("*.d file content*: {}", &dot_d); - assert_match_exact( - "[..]/target/debug/meow[EXE]: [..]/awoo/barkbarkbark [..]/awoo/build.rs[..]", + assert_e2e().eq( &dot_d, + str![[r#" +[ROOT]/foo/target/debug/meow[EXE]: [ROOT]/foo/awoo/barkbarkbark [ROOT]/foo/awoo/build.rs [ROOT]/foo/awoo/src/lib.rs [ROOT]/foo/src/main.rs + +"#]], ); // paths relative to dependency roots should not be allowed @@ -3421,9 +3425,12 @@ fn generate_good_d_files() { println!("*.d file content with dep-info-basedir*: {}", &dot_d); - assert_match_exact( - "target/debug/meow[EXE]: awoo/barkbarkbark awoo/build.rs[..]", + assert_e2e().eq( &dot_d, + str![[r#" +target/debug/meow[EXE]: awoo/barkbarkbark awoo/build.rs awoo/src/lib.rs src/main.rs + +"#]], ); // paths relative to dependency roots should not be allowed @@ -3485,16 +3492,10 @@ fn generate_good_d_files_for_external_tools() { println!("*.d file content with dep-info-basedir*: {}", &dot_d); - assert_match_exact( - concat!( - "rust_things/foo/target/debug/meow[EXE]:", - " rust_things/foo/awoo/barkbarkbark", - " rust_things/foo/awoo/build.rs", - " rust_things/foo/awoo/src/lib.rs", - " rust_things/foo/src/main.rs", - ), - &dot_d, - ); + assert_e2e().eq(&dot_d, str![[r#" +rust_things/foo/target/debug/meow[EXE]: rust_things/foo/awoo/barkbarkbark rust_things/foo/awoo/build.rs rust_things/foo/awoo/src/lib.rs rust_things/foo/src/main.rs + +"#]]); } #[cargo_test] diff --git a/tests/testsuite/check.rs b/tests/testsuite/check.rs index da8239fd748..2bae136ac71 100644 --- a/tests/testsuite/check.rs +++ b/tests/testsuite/check.rs @@ -3,10 +3,11 @@ use std::fmt::{self, Write}; use crate::messages::raw_rustc_output; -use cargo_test_support::compare; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::install::exe; use cargo_test_support::paths::CargoPathExt; use cargo_test_support::registry::Package; +use cargo_test_support::str; use cargo_test_support::tools; use cargo_test_support::{basic_bin_manifest, basic_manifest, git, project}; @@ -1553,7 +1554,10 @@ fn pkgid_querystring_works() { let output = p.cargo("pkgid").arg("gitdep").exec_with_output().unwrap(); let gitdep_pkgid = String::from_utf8(output.stdout).unwrap(); let gitdep_pkgid = gitdep_pkgid.trim(); - compare::assert_match_exact("git+file://[..]/gitdep?branch=master#1.0.0", &gitdep_pkgid); + assert_e2e().eq( + gitdep_pkgid, + str!["git+[ROOTURL]/gitdep?branch=master#1.0.0"], + ); p.cargo("build -p") .arg(gitdep_pkgid) diff --git a/tests/testsuite/config.rs b/tests/testsuite/config.rs index e962a42efc6..63bd6358a62 100644 --- a/tests/testsuite/config.rs +++ b/tests/testsuite/config.rs @@ -5,7 +5,9 @@ use cargo::util::context::{ self, Definition, GlobalContext, JobsConfig, SslVersionConfig, StringList, }; use cargo::CargoResult; -use cargo_test_support::compare; +use cargo_test_support::compare::assert_e2e; +use cargo_test_support::prelude::*; +use cargo_test_support::str; use cargo_test_support::{paths, project, symlink_supported, t}; use cargo_util_schemas::manifest::TomlTrimPaths; use cargo_util_schemas::manifest::TomlTrimPathsValue; @@ -208,7 +210,7 @@ fn rename_config_toml_to_config_replacing_with_symlink() { } #[track_caller] -pub fn assert_error>(error: E, msgs: &str) { +pub fn assert_error>(error: E, msgs: impl IntoData) { let causes = error .borrow() .chain() @@ -222,7 +224,7 @@ pub fn assert_error>(error: E, msgs: &str) { }) .collect::>() .join("\n\n"); - compare::assert_match_exact(msgs, &causes); + assert_e2e().eq(&causes, msgs); } #[cargo_test] @@ -287,10 +289,12 @@ f1 = 1 // It should NOT have warned for the symlink. let output = read_output(gctx); - let expected = "\ + let expected = str![[r#" [WARNING] `[ROOT]/.cargo/config` is deprecated in favor of `config.toml` -[NOTE] if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml`"; - compare::assert_match_exact(expected, &output); +[NOTE] if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` + +"#]]; + assert_e2e().eq(&output, expected); } #[cargo_test] @@ -316,7 +320,7 @@ f1 = 1 // It should NOT have warned for the symlink. let output = read_output(gctx); - compare::assert_match_exact("", &output); + assert_e2e().eq(&output, str![[""]]); } #[cargo_test] @@ -342,7 +346,7 @@ f1 = 1 // It should NOT have warned for the symlink. let output = read_output(gctx); - compare::assert_match_exact("", &output); + assert_e2e().eq(&output, str![[""]]); } #[cargo_test] @@ -368,7 +372,7 @@ f1 = 1 // It should NOT have warned for this situation. let output = read_output(gctx); - compare::assert_match_exact("", &output); + assert_e2e().eq(&output, str![[""]]); } #[cargo_test] @@ -395,10 +399,11 @@ f1 = 2 // But it also should have warned. let output = read_output(gctx); - let expected = "\ -[WARNING] both `[..]/.cargo/config` and `[..]/.cargo/config.toml` exist. Using `[..]/.cargo/config` -"; - compare::assert_match_exact(expected, &output); + let expected = str![[r#" +[WARNING] both `[ROOT]/.cargo/config` and `[ROOT]/.cargo/config.toml` exist. Using `[ROOT]/.cargo/config` + +"#]]; + assert_e2e().eq(&output, expected); } #[cargo_test] @@ -429,10 +434,11 @@ unused = 456 // Verify the warnings. let output = read_output(gctx); - let expected = "\ -warning: unused config key `S.unused` in `[..]/.cargo/config.toml` -"; - compare::assert_match_exact(expected, &output); + let expected = str![[r#" +[WARNING] unused config key `S.unused` in `[ROOT]/.cargo/config.toml` + +"#]]; + assert_e2e().eq(&output, expected); } #[cargo_test] @@ -824,7 +830,8 @@ Caused by: | 1 | asdf | ^ -expected `.`, `=`", +expected `.`, `=` +", ); } @@ -1645,7 +1652,7 @@ fn all_profile_options() { let profile_toml = toml::to_string(&profile).unwrap(); let roundtrip: cargo_toml::TomlProfile = toml::from_str(&profile_toml).unwrap(); let roundtrip_toml = toml::to_string(&roundtrip).unwrap(); - compare::assert_match_exact(&profile_toml, &roundtrip_toml); + assert_e2e().eq(&roundtrip_toml, &profile_toml); } #[cargo_test] diff --git a/tests/testsuite/config_cli.rs b/tests/testsuite/config_cli.rs index 4fb8e419b47..cf6a52fedf4 100644 --- a/tests/testsuite/config_cli.rs +++ b/tests/testsuite/config_cli.rs @@ -4,8 +4,9 @@ use super::config::{ assert_error, read_output, write_config_at, write_config_toml, GlobalContextBuilder, }; use cargo::util::context::Definition; -use cargo_test_support::compare; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::paths; +use cargo_test_support::str; use std::{collections::HashMap, fs}; #[cargo_test] @@ -348,10 +349,11 @@ fn unused_key() { gctx.build_config().unwrap(); let output = read_output(gctx); - let expected = "\ -warning: unused config key `build.unused` in `--config cli option` -"; - compare::assert_match_exact(expected, &output); + let expected = str![[r#" +[WARNING] unused config key `build.unused` in `--config cli option` + +"#]]; + assert_e2e().eq(&output, expected); } #[cargo_test] diff --git a/tests/testsuite/config_include.rs b/tests/testsuite/config_include.rs index 583fc0e942f..cc133ae587b 100644 --- a/tests/testsuite/config_include.rs +++ b/tests/testsuite/config_include.rs @@ -182,8 +182,7 @@ fn wrong_file_extension() { could not load Cargo configuration Caused by: - expected a config include path ending with `.toml`, but found `config.png` from `[..]/.cargo/config.toml` -", + expected a config include path ending with `.toml`, but found `config.png` from `[ROOT]/.cargo/config.toml`", ); } diff --git a/tests/testsuite/dep_info.rs b/tests/testsuite/dep_info.rs index f53f002ecb4..4aada7da7af 100644 --- a/tests/testsuite/dep_info.rs +++ b/tests/testsuite/dep_info.rs @@ -1,9 +1,10 @@ //! Tests for dep-info files. This includes the dep-info file Cargo creates in //! the output directory, and the ones stored in the fingerprint. -use cargo_test_support::compare::assert_match_exact; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::paths::{self, CargoPathExt}; use cargo_test_support::registry::Package; +use cargo_test_support::str; use cargo_test_support::{ basic_bin_manifest, basic_manifest, main_file, project, rustc_host, Project, }; @@ -593,8 +594,11 @@ fn non_local_build_script() { p.cargo("build").run(); let contents = p.read_file("target/debug/foo.d"); - assert_match_exact( - "[ROOT]/foo/target/debug/foo[EXE]: [ROOT]/foo/src/main.rs", + assert_e2e().eq( &contents, + str![[r#" +[ROOT]/foo/target/debug/foo[EXE]: [ROOT]/foo/src/main.rs + +"#]], ); } diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index 6ebf09e7be0..58c897df5d4 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -1,10 +1,11 @@ //! Tests for the `cargo fix` command. use cargo::core::Edition; -use cargo_test_support::compare::assert_match_exact; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::git::{self, init}; use cargo_test_support::paths::{self, CargoPathExt}; use cargo_test_support::registry::{Dependency, Package}; +use cargo_test_support::str; use cargo_test_support::tools; use cargo_test_support::{basic_manifest, is_nightly, project}; @@ -1537,9 +1538,9 @@ fn fix_shared_cross_workspace() { ) .run(); - assert_match_exact( - "pub fn fixme(_x: Box<&dyn Fn() -> ()>) {}", + assert_e2e().eq( &p.read_file("foo/src/shared.rs"), + str!["pub fn fixme(_x: Box<&dyn Fn() -> ()>) {}"], ); } diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index ef3f4f3ae60..a2f2a7b021a 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -5,10 +5,11 @@ use std::io::prelude::*; use std::path::Path; use std::thread; -use cargo_test_support::compare; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::cross_compile; use cargo_test_support::git; use cargo_test_support::registry::{self, registry_path, Package}; +use cargo_test_support::str; use cargo_test_support::{ basic_manifest, cargo_process, no_such_file_err_msg, project, project_in, symlink_supported, t, }; @@ -2296,26 +2297,23 @@ fn failed_install_retains_temp_directory() { let err = cargo_process("install foo").exec_with_output().unwrap_err(); let err = err.downcast::().unwrap(); let stderr = String::from_utf8(err.stderr.unwrap()).unwrap(); - compare::match_contains( - "\ + assert_e2e().eq(&stderr, str![[r#" [UPDATING] `dummy-registry` index [DOWNLOADING] crates ... [DOWNLOADED] foo v0.0.1 (registry `dummy-registry`) [INSTALLING] foo v0.0.1 [COMPILING] foo v0.0.1 -", - &stderr, - None, - ) - .unwrap(); - compare::match_contains( - "error: failed to compile `foo v0.0.1`, intermediate artifacts can be found at \ - `[..]`.\nTo reuse those artifacts with a future compilation, set the environment \ - variable `CARGO_TARGET_DIR` to that path.", - &stderr, - None, - ) - .unwrap(); +[ERROR] expected one of `!` or `::`, found `` + --> [ROOT]/home/.cargo/registry/src/-[..]/foo-0.0.1/src/main.rs:1:1 + | +1 | x + | ^ expected one of `!` or `::` + +[ERROR] could not compile `foo` (bin "foo") due to 1 previous error +[ERROR] failed to compile `foo v0.0.1`, intermediate artifacts can be found at `[..]`. +To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path. + +"#]]); // Find the path in the output. let stderr = stderr.split_once("found at `").unwrap().1; @@ -2354,39 +2352,39 @@ fn sparse_install() { assert_has_installed_exe(cargo_home(), "foo"); let assert_v1 = |expected| { let v1 = fs::read_to_string(paths::home().join(".cargo/.crates.toml")).unwrap(); - compare::assert_match_exact(expected, &v1); + assert_e2e().eq(&v1, expected); }; - assert_v1( - r#"[v1] + assert_v1(str![[r#" +[v1] "foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"] -"#, - ); + +"#]]); cargo_process("install bar").run(); assert_has_installed_exe(cargo_home(), "bar"); - assert_v1( - r#"[v1] + assert_v1(str![[r#" +[v1] "bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = ["bar[EXE]"] "foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"] -"#, - ); + +"#]]); cargo_process("uninstall bar") .with_stderr("[REMOVING] [CWD]/home/.cargo/bin/bar[EXE]") .run(); assert_has_not_installed_exe(cargo_home(), "bar"); - assert_v1( - r#"[v1] + assert_v1(str![[r#" +[v1] "foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"] -"#, - ); + +"#]]); cargo_process("uninstall foo") .with_stderr("[REMOVING] [CWD]/home/.cargo/bin/foo[EXE]") .run(); assert_has_not_installed_exe(cargo_home(), "foo"); - assert_v1( - r#"[v1] -"#, - ); + assert_v1(str![[r#" +[v1] + +"#]]); } #[cargo_test] diff --git a/tests/testsuite/lockfile_compat.rs b/tests/testsuite/lockfile_compat.rs index bb724f94305..28bd2cb2b65 100644 --- a/tests/testsuite/lockfile_compat.rs +++ b/tests/testsuite/lockfile_compat.rs @@ -1,8 +1,9 @@ //! Tests for supporting older versions of the Cargo.lock file format. -use cargo_test_support::compare::assert_match_exact; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::git; use cargo_test_support::registry::Package; +use cargo_test_support::str; use cargo_test_support::{basic_lib_manifest, basic_manifest, project}; #[cargo_test] @@ -16,7 +17,8 @@ fn oldest_lockfile_still_works() { fn oldest_lockfile_still_works_with_command(cargo_command: &str) { Package::new("bar", "0.1.0").publish(); - let expected_lockfile = r#"# This file is automatically @generated by Cargo. + let expected_lockfile = str![[r##" +# This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 @@ -32,7 +34,8 @@ version = "0.0.1" dependencies = [ "bar", ] -"#; + +"##]]; let old_lockfile = r#" [root] @@ -69,7 +72,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" p.cargo(cargo_command).run(); let lock = p.read_lockfile(); - assert_match_exact(expected_lockfile, &lock); + assert_e2e().eq(&lock, expected_lockfile); } #[cargo_test] @@ -116,7 +119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" p.cargo("check --locked").run(); let lock = p.read_lockfile(); - assert_match_exact(&old_lockfile, &lock); + assert_e2e().eq(&lock, &old_lockfile); } #[cargo_test] @@ -164,8 +167,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" p.cargo("check").run(); let lock = p.read_lockfile(); - assert_match_exact( - r#"# This file is automatically @generated by Cargo. + assert_e2e().eq( + &lock, + str![[r##" +# This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 @@ -181,8 +186,8 @@ version = "0.0.1" dependencies = [ "bar", ] -"#, - &lock, + +"##]], ); } @@ -409,24 +414,26 @@ fn current_lockfile_format() { let actual = p.read_lockfile(); - let expected = "\ -# This file is automatically @generated by Cargo.\n# It is not intended for manual editing. + let expected = str![[r##" +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. version = 3 [[package]] -name = \"bar\" -version = \"0.1.0\" -source = \"registry+https://github.com/rust-lang/crates.io-index\" -checksum = \"[..]\" +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "[..]" [[package]] -name = \"foo\" -version = \"0.0.1\" +name = "foo" +version = "0.0.1" dependencies = [ - \"bar\", + "bar", ] -"; - assert_match_exact(expected, &actual); + +"##]]; + assert_e2e().eq(&actual, expected); } #[cargo_test] @@ -471,9 +478,11 @@ dependencies = [ p.cargo("check").run(); let lock = p.read_lockfile(); - assert_match_exact( - r#"# [..] -# [..] + assert_e2e().eq( + &lock, + str![[r##" +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. version = 3 [[package]] @@ -488,8 +497,8 @@ version = "0.0.1" dependencies = [ "bar", ] -"#, - &lock, + +"##]], ); } @@ -571,7 +580,7 @@ dependencies = [ p.cargo("fetch").run(); let lock = p.read_lockfile(); - assert_match_exact(&lockfile, &lock); + assert_e2e().eq(&lock, &lockfile); } #[cargo_test] @@ -644,7 +653,7 @@ dependencies = [ p.cargo("fetch").run(); let lock = p.read_lockfile(); - assert_match_exact(&lockfile, &lock); + assert_e2e().eq(&lock, &lockfile); } #[cargo_test] @@ -664,7 +673,7 @@ version = 3 [[package]] name = "dep1" version = "0.5.0" -source = "git+{}?branch=master#{}" +source = "git+[ROOTURL]/dep1?branch=master#{}" [[package]] name = "foo" @@ -673,7 +682,6 @@ dependencies = [ "dep1", ] "#, - git_project.url(), head_id, ); @@ -701,7 +709,7 @@ dependencies = [ p.cargo("fetch").run(); let lock = p.read_lockfile(); - assert_match_exact(&lockfile, &lock); + assert_e2e().eq(&lock, &lockfile); } #[cargo_test] @@ -982,7 +990,7 @@ version = "0.0.1" "#; let lock = p.read_lockfile(); - assert_match_exact(lockfile, &lock); + assert_e2e().eq(&lock, lockfile); } fn create_branch(repo: &git2::Repository, branch: &str, head_id: git2::Oid) { @@ -1021,7 +1029,7 @@ version = 3 [[package]] name = "dep1" version = "0.5.0" -source = "git+{url}?{ref_kind}={git_ref}#{head_id}" +source = "git+[ROOTURL]/dep1?{ref_kind}={git_ref}#{head_id}" [[package]] name = "foo" @@ -1066,7 +1074,7 @@ dependencies = [ .run(); let lock = p.read_lockfile(); - assert_match_exact(&lockfile, &lock); + assert_e2e().eq(&lock, &lockfile); // v3 doesn't URL-encode URL parameters, but `url` crate does decode as it // was URL-encoded. Therefore Cargo thinks they are from different source @@ -1117,7 +1125,7 @@ version = 4 [[package]] name = "dep1" version = "0.5.0" -source = "git+{url}?{ref_kind}={encoded_ref}#{head_id}" +source = "git+[ROOTURL]/dep1?{ref_kind}={encoded_ref}#{head_id}" [[package]] name = "foo" @@ -1162,7 +1170,7 @@ dependencies = [ .run(); let lock = p.read_lockfile(); - assert_match_exact(&lockfile, &lock); + assert_e2e().eq(&lock, &lockfile); // Unlike v3_and_git_url_encoded, v4 encodes URL parameters so no git // repository re-clone happen. diff --git a/tests/testsuite/pkgid.rs b/tests/testsuite/pkgid.rs index 05bf9e66fa0..8bbaa03383e 100644 --- a/tests/testsuite/pkgid.rs +++ b/tests/testsuite/pkgid.rs @@ -1,10 +1,11 @@ //! Tests for the `cargo pkgid` command. use cargo_test_support::basic_lib_manifest; -use cargo_test_support::compare; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::git; use cargo_test_support::project; use cargo_test_support::registry::Package; +use cargo_test_support::str; #[cargo_test] fn local() { @@ -305,7 +306,7 @@ fn pkgid_json_message_metadata_consistency() { let output = p.cargo("pkgid").arg("foo").exec_with_output().unwrap(); let pkgid = String::from_utf8(output.stdout).unwrap(); let pkgid = pkgid.trim(); - compare::assert_match_exact("path+file://[..]/foo#0.5.0", &pkgid); + assert_e2e().eq(pkgid, str!["path+[ROOTURL]/foo#0.5.0"]); p.cargo("check --message-format=json") .with_json( diff --git a/tests/testsuite/profile_trim_paths.rs b/tests/testsuite/profile_trim_paths.rs index fbdec2a6919..58a3fd15d5d 100644 --- a/tests/testsuite/profile_trim_paths.rs +++ b/tests/testsuite/profile_trim_paths.rs @@ -1,10 +1,12 @@ //! Tests for `-Ztrim-paths`. use cargo_test_support::basic_manifest; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::git; use cargo_test_support::paths; use cargo_test_support::project; use cargo_test_support::registry::Package; +use cargo_test_support::str; #[cargo_test] fn gated_manifest() { @@ -711,7 +713,6 @@ fn custom_build_env_var_trim_paths() { #[cfg(unix)] #[cargo_test(requires_lldb, nightly, reason = "-Zremap-path-scope is unstable")] fn lldb_works_after_trimmed() { - use cargo_test_support::compare::match_contains; use cargo_util::is_ci; if !is_ci() { @@ -770,14 +771,17 @@ fn lldb_works_after_trimmed() { let bin_path = p.bin("foo"); assert!(bin_path.is_file()); let stdout = String::from_utf8(run_lldb(bin_path).stdout).unwrap(); - match_contains("[..]stopped[..]", &stdout, None).unwrap(); - match_contains("[..]stop reason = breakpoint[..]", &stdout, None).unwrap(); - match_contains( - "\ -(lldb) continue -Hello, Ferris!", + assert_e2e().eq( &stdout, - None, - ) - .unwrap(); + str![[r#" +... +[..]stopped[..] +[..]stop reason = breakpoint 1.1[..] +... +(lldb) continue +Hello, Ferris! +... + +"#]], + ); } diff --git a/tests/testsuite/registry_auth.rs b/tests/testsuite/registry_auth.rs index 1ac1ba28444..12c00998134 100644 --- a/tests/testsuite/registry_auth.rs +++ b/tests/testsuite/registry_auth.rs @@ -1,7 +1,8 @@ //! Tests for registry authentication. -use cargo_test_support::compare::match_contains; +use cargo_test_support::compare::assert_e2e; use cargo_test_support::registry::{Package, RegistryBuilder, Token}; +use cargo_test_support::str; use cargo_test_support::{project, Execs, Project}; fn cargo(p: &Project, s: &str) -> Execs { @@ -473,23 +474,14 @@ fn token_not_logged() { .exec_with_output() .unwrap(); let log = String::from_utf8(output.stderr).unwrap(); - let lines = "\ -[UPDATING] crates.io index -[PACKAGING] foo v0.1.0 [..] -[VERIFYING] foo v0.1.0 [..] -[DOWNLOADING] crates ... -[DOWNLOADED] bar v1.0.0 -[COMPILING] bar v1.0.0 -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] -[PACKAGED] 3 files[..] -[UPLOADING] foo v0.1.0[..] -[UPLOADED] foo v0.1.0 to registry `crates-io` -[NOTE] waiting [..] -"; - for line in lines.lines() { - match_contains(line, &log, None).unwrap(); - } + assert_e2e().eq( + &log, + str![[r#" +... +[PUBLISHED] foo v0.1.0 at registry `crates-io` + +"#]], + ); let authorizations: Vec<_> = log .lines() .filter(|line| {