From ea04b5c4839518c0c2a5d01bde2dbcd4b253578c Mon Sep 17 00:00:00 2001 From: eth3lbert Date: Wed, 19 Jun 2024 01:13:41 +0800 Subject: [PATCH 1/5] test: migrate features to snapbox --- tests/testsuite/features.rs | 530 ++++++++++++++++++++---------------- 1 file changed, 294 insertions(+), 236 deletions(-) diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index 7f97e123173..bbfce71e53c 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -1,9 +1,8 @@ //! Tests for `[features]` table. -#![allow(deprecated)] - use cargo_test_support::paths::CargoPathExt; use cargo_test_support::registry::{Dependency, Package}; +use cargo_test_support::str; use cargo_test_support::{basic_manifest, project}; #[cargo_test] @@ -27,14 +26,13 @@ fn invalid1() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `bar` includes `baz` which is neither a dependency nor another feature -", - ) + +"#]]) .run(); } @@ -59,16 +57,15 @@ fn empty_feature_name() { p.cargo("check") .with_status(101) - .with_stderr( - "\ + .with_stderr_data(str![[r#" [ERROR] feature name cannot be empty --> Cargo.toml:9:17 | -9 | \"\" = [] +9 | "" = [] | ^^ | -", - ) + +"#]]) .run(); } @@ -100,28 +97,25 @@ fn same_name() { p.cargo("tree -f") .arg("{p} [{f}]") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -", - ) - .with_stdout( - "\ -foo v0.0.1 ([..]) [] -└── bar v1.0.0 ([..]) [] -", - ) + +"#]]) + .with_stdout_data(str![[r#" +foo v0.0.1 ([ROOT]/foo) [] +└── bar v1.0.0 ([ROOT]/foo/bar) [] + +"#]]) .run(); p.cargo("tree --features bar -f") .arg("{p} [{f}]") - .with_stderr("") - .with_stdout( - "\ -foo v0.0.1 ([..]) [bar,baz] -└── bar v1.0.0 ([..]) [] -", - ) + .with_stderr_data("") + .with_stdout_data(str![[r#" +foo v0.0.1 ([ROOT]/foo) [bar,baz] +└── bar v1.0.0 ([ROOT]/foo/bar) [] + +"#]]) .run(); } @@ -149,15 +143,14 @@ fn invalid3() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `bar` includes `baz`, but `baz` is not an optional dependency A non-optional dependency of the same name is defined; consider adding `optional = true` to its definition. -", - ) + +"#]]) .run(); } @@ -185,24 +178,27 @@ fn invalid4() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to select a version for `bar`. - ... required by package `foo v0.0.1 ([..])` + .with_stderr_data(str![[r#" +[ERROR] failed to select a version for `bar`. + ... required by package `foo v0.0.1 ([ROOT]/foo)` versions that meet the requirements `*` are: 0.0.1 the package `foo` depends on `bar`, with features: `bar` but `bar` does not have these features. -failed to select a version for `bar` which could resolve this conflict", - ) +failed to select a version for `bar` which could resolve this conflict + +"#]]) .run(); p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1")); p.cargo("check --features test") .with_status(101) - .with_stderr("error: Package `foo v0.0.1 ([..])` does not have the feature `test`") + .with_stderr_data(str![[r#" +[ERROR] Package `foo v0.0.1 ([ROOT]/foo)` does not have the feature `test` + +"#]]) .run(); } @@ -228,14 +224,13 @@ fn invalid5() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: dev-dependencies are not allowed to be optional: `bar` -", - ) + +"#]]) .run(); } @@ -260,14 +255,13 @@ fn invalid6() { p.cargo("check --features foo") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `foo` includes `bar/baz`, but `bar` is not a dependency -", - ) + +"#]]) .run(); } @@ -293,14 +287,13 @@ fn invalid7() { p.cargo("check --features foo") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `foo` includes `bar/baz`, but `bar` is not a dependency -", - ) + +"#]]) .run(); } @@ -328,15 +321,14 @@ fn invalid8() { p.cargo("check --features foo") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[CWD]/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `foo/bar` in dependency `bar` is not allowed to contain slashes If you want to enable features [..] -", - ) + +"#]]) .run(); } @@ -362,12 +354,13 @@ fn invalid9() { .build(); p.cargo("check --features bar") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -error: Package `foo v0.0.1 ([..])` does not have feature `bar`. It has a required dependency with that name, but only optional dependencies can be used as features. -", - ).with_status(101).run(); +[ERROR] Package `foo v0.0.1 ([ROOT]/foo)` does not have feature `bar`. It has a required dependency with that name, but only optional dependencies can be used as features. + +"#]]) + .with_status(101) + .run(); } #[cargo_test] @@ -406,9 +399,10 @@ fn invalid10() { .file("bar/baz/src/lib.rs", "") .build(); - p.cargo("check").with_stderr("\ -error: failed to select a version for `bar`. - ... required by package `foo v0.0.1 ([..])` + p.cargo("check") + .with_stderr_data(str![[r#" +[ERROR] failed to select a version for `bar`. + ... required by package `foo v0.0.1 ([ROOT]/foo)` versions that meet the requirements `*` are: 0.0.1 the package `foo` depends on `bar`, with features: `baz` but `bar` does not have these features. @@ -416,7 +410,9 @@ the package `foo` depends on `bar`, with features: `baz` but `bar` does not have failed to select a version for `bar` which could resolve this conflict -").with_status(101) + +"#]]) + .with_status(101) .run(); } @@ -483,14 +479,13 @@ fn no_transitive_dep_feature_requirement() { .build(); p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[CWD]/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: multiple slashes in feature `derived/bar/qux` (included by feature `default`) are not allowed -", - ) + +"#]]) .run(); } @@ -527,29 +522,44 @@ fn no_feature_doesnt_build() { .build(); p.cargo("build") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -[COMPILING] foo v0.0.1 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) - .run(); - p.process(&p.bin("foo")).with_stdout("").run(); +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +"#]]) + .run(); + p.process(&p.bin("foo")).with_stdout_data("").run(); + + let expected = if cfg!(target_os = "windows") && cfg!(target_env = "msvc") { + str![[r#" +[COMPILING] bar v0.0.1 ([ROOT]/foo/bar) +[RUNNING] `rustc --crate-name bar [..]` +[DIRTY] foo v0.0.1 ([ROOT]/foo): the list of features changed +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + } else { + str![[r#" +[COMPILING] bar v0.0.1 ([ROOT]/foo/bar) +[RUNNING] `rustc --crate-name bar [..]` +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + }; p.cargo("build --features bar -v") - .with_stderr( - "\ -[COMPILING] bar v0.0.1 ([CWD]/bar) -[RUNNING] `rustc --crate-name bar [..] -[DIRTY-MSVC] foo v0.0.1 ([CWD]): the list of features changed -[COMPILING] foo v0.0.1 ([CWD]) -[RUNNING] `rustc --crate-name foo [..] -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) + .with_stderr_data(expected) + .run(); + p.process(&p.bin("foo")) + .with_stdout_data(str![[r#" +bar + +"#]]) .run(); - p.process(&p.bin("foo")).with_stdout("bar\n").run(); } #[cargo_test] @@ -588,28 +598,41 @@ fn default_feature_pulled_in() { .build(); p.cargo("build") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -[COMPILING] bar v0.0.1 ([CWD]/bar) -[COMPILING] foo v0.0.1 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) +[COMPILING] bar v0.0.1 ([ROOT]/foo/bar) +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); + p.process(&p.bin("foo")) + .with_stdout_data(str![[r#" +bar + +"#]]) .run(); - p.process(&p.bin("foo")).with_stdout("bar\n").run(); + let expected = if cfg!(target_os = "windows") && cfg!(target_env = "msvc") { + str![[r#" +[DIRTY] foo v0.0.1 ([ROOT]/foo): the list of features changed +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + } else { + str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + }; p.cargo("build --no-default-features -v") - .with_stderr( - "\ -[DIRTY-MSVC] foo v0.0.1 ([CWD]): the list of features changed -[COMPILING] foo v0.0.1 ([CWD]) -[RUNNING] `rustc --crate-name foo [..] -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) + .with_stderr_data(expected) .run(); - p.process(&p.bin("foo")).with_stdout("").run(); + p.process(&p.bin("foo")).with_stdout_data("").run(); } #[cargo_test] @@ -633,7 +656,10 @@ fn cyclic_feature() { p.cargo("check") .with_status(101) - .with_stderr("[ERROR] cyclic feature dependency: feature `default` depends on itself") + .with_stderr_data(str![[r#" +[ERROR] cyclic feature dependency: feature `default` depends on itself + +"#]]) .run(); } @@ -658,12 +684,11 @@ fn cyclic_feature2() { .build(); p.cargo("check") - .with_stderr( - "\ -[CHECKING] foo [..] -[FINISHED] [..] -", - ) + .with_stderr_data(str![[r#" +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -715,15 +740,14 @@ fn groups_on_groups_on_groups() { .build(); p.cargo("check") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 3 packages to latest compatible versions -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] foo v0.0.1 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -766,15 +790,14 @@ fn many_cli_features() { p.cargo("check --features") .arg("bar baz") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 3 packages to latest compatible versions -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] foo v0.0.1 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -853,15 +876,14 @@ fn union_features() { .build(); p.cargo("check") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 3 packages to latest compatible versions -[CHECKING] d2 v0.0.1 ([CWD]/d2) -[CHECKING] d1 v0.0.1 ([CWD]/d1) -[CHECKING] foo v0.0.1 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) +[CHECKING] d2 v0.0.1 ([ROOT]/foo/d2) +[CHECKING] d1 v0.0.1 ([ROOT]/foo/d1) +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -902,25 +924,23 @@ fn many_features_no_rebuilds() { .build(); p.cargo("check") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -[CHECKING] a v0.1.0 ([CWD]/a) -[CHECKING] b v0.1.0 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) +[CHECKING] a v0.1.0 ([ROOT]/foo/a) +[CHECKING] b v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); p.root().move_into_the_past(); p.cargo("check -v") - .with_stderr( - "\ -[FRESH] a v0.1.0 ([..]/a) -[FRESH] b v0.1.0 ([..]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) + .with_stderr_data(str![[r#" +[FRESH] a v0.1.0 ([ROOT]/foo/a) +[FRESH] b v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -1103,8 +1123,18 @@ fn no_rebuild_when_frobbing_default_feature() { .build(); p.cargo("check").run(); - p.cargo("check").with_stderr("[FINISHED] [..]").run(); - p.cargo("check").with_stderr("[FINISHED] [..]").run(); + p.cargo("check") + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); + p.cargo("check") + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); } #[cargo_test] @@ -1157,8 +1187,18 @@ fn unions_work_with_no_default_features() { .build(); p.cargo("check").run(); - p.cargo("check").with_stderr("[FINISHED] [..]").run(); - p.cargo("check").with_stderr("[FINISHED] [..]").run(); + p.cargo("check") + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); + p.cargo("check") + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); } #[cargo_test] @@ -1185,13 +1225,12 @@ fn optional_and_dev_dep() { .build(); p.cargo("check") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -[CHECKING] test v0.1.0 ([..]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) +[CHECKING] test v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -1359,7 +1398,11 @@ fn dep_feature_in_cmd_line() { // Building without any features enabled should fail: p.cargo("check") .with_status(101) - .with_stderr_contains("[..]unresolved import `bar::test`") + .with_stderr_data(str![[r#" +... +error[E0432]: unresolved import `bar::test` +... +"#]]) .run(); // We should be able to enable the feature "derived-feat", which enables "some-feat", @@ -1369,13 +1412,19 @@ fn dep_feature_in_cmd_line() { // Trying to enable features of transitive dependencies is an error p.cargo("check --features bar/some-feat") .with_status(101) - .with_stderr("error: package `foo v0.0.1 ([..])` does not have a dependency named `bar`") + .with_stderr_data(str![[r#" +[ERROR] package `foo v0.0.1 ([ROOT]/foo)` does not have a dependency named `bar` + +"#]]) .run(); // Hierarchical feature specification should still be disallowed p.cargo("check --features derived/bar/some-feat") .with_status(101) - .with_stderr("[ERROR] multiple slashes in feature `derived/bar/some-feat` is not allowed") + .with_stderr_data(str![[r#" +[ERROR] multiple slashes in feature `derived/bar/some-feat` is not allowed + +"#]]) .run(); } @@ -1463,15 +1512,14 @@ fn many_cli_features_comma_delimited() { .build(); p.cargo("check --features bar,baz") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 3 packages to latest compatible versions -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] foo v0.0.1 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -1530,17 +1578,16 @@ fn many_cli_features_comma_and_space_delimited() { p.cargo("check --features") .arg("bar,baz bam bap") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 5 packages to latest compatible versions -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] ba[..] v0.0.1 ([CWD]/ba[..]) -[CHECKING] foo v0.0.1 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] -", - ) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] ba[..] v0.0.1 ([ROOT]/foo/ba[..]) +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -1700,15 +1747,13 @@ fn warn_if_default_features() { .file("bar/src/lib.rs", "pub fn bar() {}") .build(); - p.cargo("check") - .with_stderr( - r#" + p.cargo("check").with_stderr_data(str![[r#" [WARNING] `default-features = [".."]` was found in [features]. Did you mean to use `default = [".."]`? [LOCKING] 2 packages to latest compatible versions -[CHECKING] foo v0.0.1 ([CWD]) -[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..] - "#.trim(), - ).run(); +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]).run(); } #[cargo_test] @@ -1917,14 +1962,30 @@ fn all_features_virtual_ws() { ) .build(); - p.cargo("run").with_stdout("f1\n").run(); + p.cargo("run") + .with_stdout_data(str![[r#" +f1 + +"#]]) + .run(); p.cargo("run --all-features") - .with_stdout("f1\nf2\nf3\nf4\n") + .with_stdout_data(str![[r#" +f1 +f2 +f3 +f4 + +"#]]) .run(); // In `a`, it behaves differently. :( p.cargo("run --all-features") .cwd("a") - .with_stdout("f1\nf2\nf3\n") + .with_stdout_data(str![[r#" +f1 +f2 +f3 + +"#]]) .run(); } @@ -1974,7 +2035,11 @@ fn slash_optional_enables() { p.cargo("check") .with_status(101) - .with_stderr_contains("[..]dep not set[..]") + .with_stderr_data(str![[r#" +... +[ERROR] dep not set +... +"#]]) .run(); p.cargo("check --features dep/feat").run(); @@ -2040,21 +2105,23 @@ fn registry_summary_order_doesnt_matter() { .build(); p.cargo("run") - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 3 packages to latest compatible versions [DOWNLOADING] crates ... -[DOWNLOADED] [..] -[DOWNLOADED] [..] +[DOWNLOADED] dep v0.1.0 (registry `dummy-registry`) +[DOWNLOADED] bar v0.1.0 (registry `dummy-registry`) [COMPILING] dep v0.1.0 [COMPILING] bar v0.1.0 -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] `target/debug/foo[EXE]` -", - ) - .with_stdout("it works") + +"#]]) + .with_stdout_data(str![[r#" +it works + +"#]]) .run(); } @@ -2095,19 +2162,13 @@ fn nonexistent_required_features() { .file("examples/ololo.rs", "fn main() {}") .build(); - p.cargo("check --examples") - .with_stderr_contains( - "\ -[WARNING] invalid feature `not_present` in required-features of target `ololo`: \ - `not_present` is not present in [features] section -[WARNING] invalid feature `required_dependency/not_existing` in required-features \ - of target `ololo`: feature `not_existing` does not exist in package \ - `required_dependency v0.1.0` -[WARNING] invalid feature `not_specified_dependency/some_feature` in required-features \ - of target `ololo`: dependency `not_specified_dependency` does not exist -", - ) - .run(); + p.cargo("check --examples").with_stderr_data(str![[r#" +... +[WARNING] invalid feature `not_present` in required-features of target `ololo`: `not_present` is not present in [features] section +[WARNING] invalid feature `required_dependency/not_existing` in required-features of target `ololo`: feature `not_existing` does not exist in package `required_dependency v0.1.0` +[WARNING] invalid feature `not_specified_dependency/some_feature` in required-features of target `ololo`: dependency `not_specified_dependency` does not exist +... +"#]]).run(); } #[cargo_test] @@ -2132,16 +2193,15 @@ fn invalid_feature_names_error() { p.cargo("check") .with_status(101) - .with_stderr( - "\ + .with_stderr_data(str![[r#" [ERROR] invalid character `+` in feature name: `+foo`, the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) --> Cargo.toml:9:17 | -9 | \"+foo\" = [] +9 | "+foo" = [] | ^^^^^^ | -", - ) + +"#]]) .run(); p.change_file( @@ -2160,16 +2220,15 @@ fn invalid_feature_names_error() { p.cargo("check") .with_status(101) - .with_stderr( - "\ + .with_stderr_data(str![[r#" [ERROR] invalid character `&` in feature name: `a&b`, characters must be Unicode XID characters, '-', `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) --> Cargo.toml:9:13 | -9 | \"a&b\" = [] +9 | "a&b" = [] | ^^^^^ | -", - ) + +"#]]) .run(); } @@ -2194,15 +2253,14 @@ fn invalid_feature_name_slash_error() { p.cargo("check") .with_status(101) - .with_stderr( - "\ + .with_stderr_data(str![[r#" [ERROR] invalid character `/` in feature name: `foo/bar`, feature name is not allowed to contain slashes --> Cargo.toml:8:17 | -8 | \"foo/bar\" = [] +8 | "foo/bar" = [] | ^^^^^^^^^ | -", - ) + +"#]]) .run(); } From 4740f48b8160f57e880d1f5b0de02f8ffae8eba6 Mon Sep 17 00:00:00 2001 From: eth3lbert Date: Wed, 19 Jun 2024 02:45:50 +0800 Subject: [PATCH 2/5] test: migrate features2 to snapbox --- tests/testsuite/features2.rs | 680 +++++++++++++++++++++-------------- 1 file changed, 402 insertions(+), 278 deletions(-) diff --git a/tests/testsuite/features2.rs b/tests/testsuite/features2.rs index 0afc0aa68bf..2a51585bc83 100644 --- a/tests/testsuite/features2.rs +++ b/tests/testsuite/features2.rs @@ -1,12 +1,12 @@ //! Tests for the new feature resolver. -#![allow(deprecated)] - use cargo_test_support::cross_compile::{self, alternate}; use cargo_test_support::install::cargo_home; use cargo_test_support::paths::CargoPathExt; +use cargo_test_support::prelude::*; use cargo_test_support::publish::validate_crate_contents; use cargo_test_support::registry::{Dependency, Package}; +use cargo_test_support::str; use cargo_test_support::{basic_manifest, cargo_process, project, rustc_host, Project}; use std::fs::File; @@ -68,7 +68,14 @@ fn inactivate_targets() { p.cargo("check") .with_status(101) - .with_stderr_contains("[..]f1 should not activate[..]") + .with_stderr_data( + str![[r#" +... +[ERROR] f1 should not activate +... +"#]] + .unordered(), + ) .run(); switch_to_resolver_2(&p); @@ -172,29 +179,85 @@ fn inactive_target_optional() { .build(); p.cargo("run --all-features") - .with_stdout("foo1\nfoo2\ndep1\ndep2\ncommon\nf1\nf2\nf3\nf4\n") + .with_stdout_data(str![[r#" +foo1 +foo2 +dep1 +dep2 +common +f1 +f2 +f3 +f4 + +"#]]) .run(); p.cargo("run --features dep1") - .with_stdout("dep1\nf1\n") + .with_stdout_data(str![[r#" +dep1 +f1 + +"#]]) .run(); p.cargo("run --features foo1") - .with_stdout("foo1\ndep1\nf1\nf2\n") + .with_stdout_data(str![[r#" +foo1 +dep1 +f1 +f2 + +"#]]) .run(); p.cargo("run --features dep2") - .with_stdout("dep2\nf3\n") + .with_stdout_data(str![[r#" +dep2 +f3 + +"#]]) .run(); p.cargo("run --features common") - .with_stdout("common\nf4\n") + .with_stdout_data(str![[r#" +common +f4 + +"#]]) .run(); switch_to_resolver_2(&p); p.cargo("run --all-features") - .with_stdout("foo1\nfoo2\ndep1\ndep2\ncommon") + .with_stdout_data(str![[r#" +foo1 +foo2 +dep1 +dep2 +common + +"#]]) + .run(); + p.cargo("run --features dep1") + .with_stdout_data(str![[r#" +dep1 + +"#]]) + .run(); + p.cargo("run --features foo1") + .with_stdout_data(str![[r#" +foo1 + +"#]]) + .run(); + p.cargo("run --features dep2") + .with_stdout_data(str![[r#" +dep2 + +"#]]) + .run(); + p.cargo("run --features common") + .with_stdout_data(str![[r#" +common + +"#]]) .run(); - p.cargo("run --features dep1").with_stdout("dep1\n").run(); - p.cargo("run --features foo1").with_stdout("foo1\n").run(); - p.cargo("run --features dep2").with_stdout("dep2\n").run(); - p.cargo("run --features common").with_stdout("common").run(); } #[cargo_test] @@ -281,7 +344,11 @@ fn decouple_host_deps() { p.cargo("check") .with_status(101) - .with_stderr_contains("[..]unresolved import `common::bar`[..]") + .with_stderr_data(str![[r#" +... +error[E0432]: unresolved import `common::bar` +... +"#]]) .run(); switch_to_resolver_2(&p); @@ -345,7 +412,11 @@ fn decouple_host_deps_nested() { p.cargo("check") .with_status(101) - .with_stderr_contains("[..]unresolved import `common::bar`[..]") + .with_stderr_data(str![[r#" +... +error[E0432]: unresolved import `common::bar` +... +"#]]) .run(); switch_to_resolver_2(&p); @@ -836,13 +907,12 @@ fn required_features_host_dep() { p.cargo("run") .with_status(101) - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions [ERROR] target `x` in package `foo` requires the features: `bdep/f1` -Consider enabling them by passing, e.g., `--features=\"bdep/f1\"` -", - ) +Consider enabling them by passing, e.g., `--features="bdep/f1"` + +"#]]) .run(); // New behavior. @@ -917,7 +987,12 @@ fn disabled_shared_host_dep() { ) .build(); - p.cargo("run -v").with_stdout("hello from somedep").run(); + p.cargo("run -v") + .with_stdout_data(str![[r#" +hello from somedep + +"#]]) + .run(); } #[cargo_test] @@ -950,15 +1025,19 @@ fn required_features_inactive_dep() { .build(); p.cargo("check") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -[FINISHED] [..]", - ) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); p.cargo("check --features=feat1") - .with_stderr("[CHECKING] foo[..]\n[FINISHED] [..]") + .with_stderr_data(str![[r#" +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -1033,12 +1112,19 @@ fn decouple_proc_macro() { p.cargo("run") .env("TEST_EXPECTS_ENABLED", "1") - .with_stdout("it is true") + .with_stdout_data(str![[r#" +it is true + +"#]]) .run(); // Make sure the test is fallible. p.cargo("test --doc") .with_status(101) - .with_stdout_contains("[..]common is wrong[..]") + .with_stdout_data(str![[r#" +... +assertion `left == right` failed: common is wrong +... +"#]]) .run(); p.cargo("test --doc").env("TEST_EXPECTS_ENABLED", "1").run(); p.cargo("doc").run(); @@ -1052,7 +1138,12 @@ fn decouple_proc_macro() { // New behavior. switch_to_resolver_2(&p); - p.cargo("run").with_stdout("it is false").run(); + p.cargo("run") + .with_stdout_data(str![[r#" +it is false + +"#]]) + .run(); p.cargo("test --doc").run(); p.cargo("doc").run(); @@ -1114,7 +1205,11 @@ fn proc_macro_ws() { .build(); p.cargo("check -p pm -v") - .with_stderr_contains("[RUNNING] `rustc --crate-name foo [..]--cfg[..]feat1[..]") + .with_stderr_data(str![[r#" +... +[RUNNING] `rustc --crate-name foo [..]--cfg[..]feat1[..]` +... +"#]]) .run(); // This may be surprising that `foo` doesn't get built separately. It is // because pm might have other units (binaries, tests, etc.), and so the @@ -1122,21 +1217,30 @@ fn proc_macro_ws() { // is related to the bigger issue where the features selected in a // workspace depend on which packages are selected. p.cargo("check --workspace -v") - .with_stderr( - "\ -[FRESH] foo v0.1.0 [..] -[FRESH] pm v0.1.0 [..] -[FINISHED] `dev` profile [..] -", - ) + .with_stderr_data(str![[r#" +[FRESH] foo v0.1.0 ([ROOT]/foo/foo) +[FRESH] pm v0.1.0 ([ROOT]/foo/pm) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); // Selecting just foo will build without unification. + let expected = if cfg!(target_os = "macos") { + str![[r#" +... +[RUNNING] `rustc --crate-name foo --edition=2015 foo/src/lib.rs --error-format=json --json=[..] --crate-type lib --emit=[..] -C embed-bitcode=no -C debuginfo=2 -C split-debuginfo=unpacked --check-cfg[..] --check-cfg[..] -C metadata=[..] -C extra-filename=[..] --out-dir [ROOT]/foo/target/debug/deps -L dependency=[ROOT]/foo/target/debug/deps` +... +"#]] + } else { + str![[r#" +... +[RUNNING] `rustc --crate-name foo --edition=2015 foo/src/lib.rs --error-format=json --json=[..] --crate-type lib --emit=[..] -C embed-bitcode=no -C debuginfo=2 --check-cfg[..] --check-cfg[..] -C metadata=[..] -C extra-filename=[..] --out-dir [ROOT]/foo/target/debug/deps -L dependency=[ROOT]/foo/target/debug/deps` +... +"#]] + }; p.cargo("check -p foo -v") // Make sure `foo` is built without feat1 - .with_stderr_line_without( - &["[RUNNING] `rustc --crate-name foo --edition=2015"], - &["--cfg[..]feat1"], - ) + .with_stderr_data(expected) .run(); } @@ -1188,37 +1292,34 @@ fn has_dev_dep_for_test() { .build(); p.cargo("check -v") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -[CHECKING] foo v0.1.0 [..] -[RUNNING] `rustc --crate-name foo [..] -[FINISHED] [..] -", - ) +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); p.cargo("check -v --profile=test") - .with_stderr( - "\ -[CHECKING] dep v0.1.0 [..] -[RUNNING] `rustc --crate-name dep [..] -[CHECKING] foo v0.1.0 [..] -[RUNNING] `rustc --crate-name foo [..] -[FINISHED] [..] -", - ) + .with_stderr_data(str![[r#" +[CHECKING] dep v0.1.0 ([ROOT]/foo/dep) +[RUNNING] `rustc --crate-name dep [..]` +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); // New resolver should not be any different. switch_to_resolver_2(&p); p.cargo("check -v --profile=test") - .with_stderr( - "\ -[FRESH] dep [..] -[FRESH] foo [..] -[FINISHED] [..] -", - ) + .with_stderr_data(str![[r#" +[FRESH] dep v0.1.0 ([ROOT]/foo/dep) +[FRESH] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -1300,14 +1401,13 @@ fn resolver_bad_setting() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[..]/foo/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: - `resolver` setting `foo` is not valid, valid options are \"1\" or \"2\" -", - ) + `resolver` setting `foo` is not valid, valid options are "1" or "2" + +"#]]) .run(); } @@ -1357,7 +1457,14 @@ fn resolver_original() { p.cargo("check") .with_status(101) - .with_stderr_contains("[..]f1 should not activate[..]") + .with_stderr_data( + str![[r#" +... +[ERROR] f1 should not activate +... +"#]] + .unordered(), + ) .run(); p.change_file("Cargo.toml", &manifest("2")); @@ -1386,14 +1493,13 @@ fn resolver_not_both() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[..]/foo/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: cannot specify `resolver` field in both `[workspace]` and `[package]` -", - ) + +"#]]) .run(); } @@ -1422,15 +1528,14 @@ fn resolver_ws_member() { .build(); p.cargo("check") - .with_stderr( - "\ -warning: resolver for the non root package will be ignored, specify resolver at the workspace root: -package: [..]/foo/a/Cargo.toml -workspace: [..]/foo/Cargo.toml -[CHECKING] a v0.1.0 [..] -[FINISHED] [..] -", - ) + .with_stderr_data(str![[r#" +[WARNING] resolver for the non root package will be ignored, specify resolver at the workspace root: +package: [ROOT]/foo/a/Cargo.toml +workspace: [ROOT]/foo/Cargo.toml +[CHECKING] a v0.1.0 ([ROOT]/foo/a) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -1456,18 +1561,15 @@ fn edition_2021_workspace_member() { .file("a/src/lib.rs", "") .build(); - p.cargo("check") - .with_stderr( - "\ -warning: virtual workspace defaulting to `resolver = \"1\"` despite one or more workspace members being on edition 2021 which implies `resolver = \"2\"` -note: to keep the current resolver, specify `workspace.resolver = \"1\"` in the workspace root's manifest -note: to use the edition 2021 resolver, specify `workspace.resolver = \"2\"` in the workspace root's manifest -note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions -[CHECKING] a v0.1.0 [..] -[FINISHED] [..] -", - ) - .run(); + p.cargo("check").with_stderr_data(str![[r#" +[WARNING] virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"` +[NOTE] to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest +[NOTE] to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest +[NOTE] for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions +[CHECKING] a v0.1.0 ([ROOT]/foo/a) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]).run(); } #[cargo_test] @@ -1497,12 +1599,11 @@ fn resolver_ws_root_and_member() { // Ignores if they are the same. p.cargo("check") - .with_stderr( - "\ -[CHECKING] a v0.1.0 [..] -[FINISHED] [..] -", - ) + .with_stderr_data(str![[r#" +[CHECKING] a v0.1.0 ([ROOT]/foo/a) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -1604,18 +1705,17 @@ fn resolver_enables_new_features() { // Only normal. p.cargo("run --bin a") .env("EXPECTED_FEATS", "1") - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 3 packages to latest compatible versions [DOWNLOADING] crates ... -[DOWNLOADED] common [..] +[DOWNLOADED] common v1.0.0 (registry `dummy-registry`) [COMPILING] common v1.0.0 -[COMPILING] a v0.1.0 [..] -[FINISHED] [..] +[COMPILING] a v0.1.0 ([ROOT]/foo/a) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] `target/debug/a[EXE]` -", - ) + +"#]]) .run(); // only normal+dev @@ -1624,7 +1724,10 @@ fn resolver_enables_new_features() { // Can specify features of packages from a different directory. p.cargo("run -p b --features=ping") .cwd("a") - .with_stdout("pong") + .with_stdout_data(str![[r#" +pong + +"#]]) .run(); } @@ -1753,12 +1856,11 @@ fn tree_all() { .file("src/lib.rs", "") .build(); p.cargo("tree --target=all") - .with_stdout( - "\ -foo v0.1.0 ([..]/foo) + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) └── log v0.4.8 -", - ) + +"#]]) .run(); } @@ -1850,33 +1952,40 @@ fn shared_dep_same_but_dependencies() { p.cargo("build --bin bin1 --bin bin2") // unordered because bin1 and bin2 build at the same time - .with_stderr_unordered( - "\ + .with_stderr_data( + str![[r#" [LOCKING] 4 packages to latest compatible versions -[COMPILING] subdep [..] -[COMPILING] dep [..] -[COMPILING] bin2 [..] -[COMPILING] bin1 [..] -warning: bin2@0.1.0: feat: enabled -[FINISHED] [..] -", +[COMPILING] subdep v0.1.0 ([ROOT]/foo/subdep) +[COMPILING] dep v0.1.0 ([ROOT]/foo/dep) +[COMPILING] bin1 v0.1.0 ([ROOT]/foo/bin1) +[COMPILING] bin2 v0.1.0 ([ROOT]/foo/bin2) +[WARNING] bin2@0.1.0: feat: enabled +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + .unordered(), ) .run(); p.process(p.bin("bin1")) - .with_stdout("cargo::warning=feat: not enabled") + .with_stdout_data(str![[r#" +cargo::warning=feat: not enabled + +"#]]) .run(); // Make sure everything stays cached. p.cargo("build -v --bin bin1 --bin bin2") - .with_stderr_unordered( - "\ -[FRESH] subdep [..] -[FRESH] dep [..] -[FRESH] bin1 [..] -warning: bin2@0.1.0: feat: enabled -[FRESH] bin2 [..] -[FINISHED] [..] -", + .with_stderr_data( + str![[r#" +[FRESH] subdep v0.1.0 ([ROOT]/foo/subdep) +[FRESH] dep v0.1.0 ([ROOT]/foo/dep) +[FRESH] bin1 v0.1.0 ([ROOT]/foo/bin1) +[WARNING] bin2@0.1.0: feat: enabled +[FRESH] bin2 v0.1.0 ([ROOT]/foo/bin2) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + .unordered(), ) .run(); } @@ -2000,19 +2109,21 @@ fn doc_optional() { .build(); p.cargo("doc") - .with_stderr_unordered( - "\ -[UPDATING] [..] + .with_stderr_data( + str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 4 packages to latest compatible versions [DOWNLOADING] crates ... -[DOWNLOADED] spin v1.0.0 [..] -[DOWNLOADED] bar v1.0.0 [..] +[DOWNLOADED] spin v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`) [DOCUMENTING] bar v1.0.0 [CHECKING] bar v1.0.0 -[DOCUMENTING] foo v0.1.0 [..] -[FINISHED] [..] -[GENERATED] [CWD]/target/doc/foo/index.html -", +[DOCUMENTING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[GENERATED] [ROOT]/foo/target/doc/foo/index.html + +"#]] + .unordered(), ) .run(); } @@ -2115,22 +2226,24 @@ fn minimal_download() { // Should be the same as `-Zfeatures=all` p.cargo("check -Zfeatures=compare") .masquerade_as_nightly_cargo(&["features=compare"]) - .with_stderr_unordered( - "\ -[UPDATING] [..] + .with_stderr_data( + str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 15 packages to latest compatible versions [DOWNLOADING] crates ... -[DOWNLOADED] normal_pm v1.0.0 [..] -[DOWNLOADED] normal v1.0.0 [..] -[DOWNLOADED] build_dep_pm v1.0.0 [..] -[DOWNLOADED] build_dep v1.0.0 [..] +[DOWNLOADED] normal_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] normal v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep v1.0.0 (registry `dummy-registry`) [COMPILING] build_dep v1.0.0 [COMPILING] build_dep_pm v1.0.0 [CHECKING] normal_pm v1.0.0 [CHECKING] normal v1.0.0 -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] -", +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + .unordered(), ) .run(); clear(); @@ -2140,97 +2253,103 @@ fn minimal_download() { // all p.cargo("check") - .with_stderr_unordered( - "\ + .with_stderr_data( + str![[r#" [DOWNLOADING] crates ... -[DOWNLOADED] normal_pm v1.0.0 [..] -[DOWNLOADED] normal v1.0.0 [..] -[DOWNLOADED] build_dep_pm v1.0.0 [..] -[DOWNLOADED] build_dep v1.0.0 [..] -[COMPILING] build_dep v1.0.0 +[DOWNLOADED] normal_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] normal v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep v1.0.0 (registry `dummy-registry`) [COMPILING] build_dep_pm v1.0.0 -[CHECKING] normal v1.0.0 +[COMPILING] build_dep v1.0.0 [CHECKING] normal_pm v1.0.0 -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] -", +[CHECKING] normal v1.0.0 +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + .unordered(), ) .run(); clear(); // This disables decouple_dev_deps. p.cargo("test --no-run") - .with_stderr_unordered( - "\ + .with_stderr_data( + str![[r#" [DOWNLOADING] crates ... -[DOWNLOADED] normal_pm v1.0.0 [..] -[DOWNLOADED] normal v1.0.0 [..] -[DOWNLOADED] dev_dep_pm v1.0.0 [..] -[DOWNLOADED] dev_dep v1.0.0 [..] -[DOWNLOADED] build_dep_pm v1.0.0 [..] -[DOWNLOADED] build_dep v1.0.0 [..] -[COMPILING] build_dep v1.0.0 +[DOWNLOADED] normal_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] normal v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] dev_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] dev_dep v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep v1.0.0 (registry `dummy-registry`) [COMPILING] build_dep_pm v1.0.0 +[COMPILING] build_dep v1.0.0 [COMPILING] normal_pm v1.0.0 [COMPILING] normal v1.0.0 -[COMPILING] dev_dep_pm v1.0.0 [COMPILING] dev_dep v1.0.0 -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] -[EXECUTABLE] unittests src/lib.rs (target/debug/deps/foo-[..][EXE]) -", +[COMPILING] dev_dep_pm v1.0.0 +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[EXECUTABLE] unittests src/lib.rs (target/debug/deps/foo-[HASH][EXE]) + +"#]] + .unordered(), ) .run(); clear(); // This disables itarget, but leaves decouple_dev_deps enabled. p.cargo("tree -e normal --target=all") - .with_stderr_unordered( - "\ + .with_stderr_data( + str![[r#" [DOWNLOADING] crates ... -[DOWNLOADED] normal v1.0.0 [..] -[DOWNLOADED] normal_pm v1.0.0 [..] -[DOWNLOADED] build_dep v1.0.0 [..] -[DOWNLOADED] build_dep_pm v1.0.0 [..] -[DOWNLOADED] itarget_normal v1.0.0 [..] -[DOWNLOADED] itarget_normal_pm v1.0.0 [..] -[DOWNLOADED] itarget_build_dep v1.0.0 [..] -[DOWNLOADED] itarget_build_dep_pm v1.0.0 [..] -", - ) - .with_stdout( - "\ +[DOWNLOADED] normal_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] normal v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_normal_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_normal v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_build_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_build_dep v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep v1.0.0 (registry `dummy-registry`) + +"#]] + .unordered(), + ) + .with_stdout_data(str![[r#" foo v0.1.0 ([ROOT]/foo) ├── itarget_normal v1.0.0 ├── itarget_normal_pm v1.0.0 ├── normal v1.0.0 └── normal_pm v1.0.0 -", - ) + +"#]]) .run(); clear(); // This disables itarget and decouple_dev_deps. p.cargo("tree --target=all") - .with_stderr_unordered( - "\ + .with_stderr_data( + str![[r#" [DOWNLOADING] crates ... -[DOWNLOADED] normal_pm v1.0.0 [..] -[DOWNLOADED] normal v1.0.0 [..] -[DOWNLOADED] itarget_normal_pm v1.0.0 [..] -[DOWNLOADED] itarget_normal v1.0.0 [..] -[DOWNLOADED] itarget_dev_dep_pm v1.0.0 [..] -[DOWNLOADED] itarget_dev_dep v1.0.0 [..] -[DOWNLOADED] itarget_build_dep_pm v1.0.0 [..] -[DOWNLOADED] itarget_build_dep v1.0.0 [..] -[DOWNLOADED] dev_dep_pm v1.0.0 [..] -[DOWNLOADED] dev_dep v1.0.0 [..] -[DOWNLOADED] build_dep_pm v1.0.0 [..] -[DOWNLOADED] build_dep v1.0.0 [..] -", - ) - .with_stdout( - "\ +[DOWNLOADED] normal_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] normal v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_normal_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_normal v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_dev_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_dev_dep v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_build_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] itarget_build_dep v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] dev_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] dev_dep v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep_pm v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] build_dep v1.0.0 (registry `dummy-registry`) + +"#]] + .unordered(), + ) + .with_stdout_data(str![[r#" foo v0.1.0 ([ROOT]/foo) ├── itarget_normal v1.0.0 ├── itarget_normal_pm v1.0.0 @@ -2246,8 +2365,8 @@ foo v0.1.0 ([ROOT]/foo) ├── dev_dep_pm v1.0.0 ├── itarget_dev_dep v1.0.0 └── itarget_dev_dep_pm v1.0.0 -", - ) + +"#]]) .run(); clear(); } @@ -2354,33 +2473,38 @@ fn pm_with_int_shared() { .build(); p.cargo("build --workspace --all-targets --all-features -v") - .with_stderr_unordered( - "\ + .with_stderr_data( + str![[r#" [LOCKING] 3 packages to latest compatible versions -[COMPILING] shared [..] -[RUNNING] `rustc --crate-name shared [..]--crate-type lib [..] -[RUNNING] `rustc --crate-name shared [..]--crate-type lib [..] -[RUNNING] `rustc --crate-name shared [..]--test[..] -[COMPILING] pm [..] -[RUNNING] `rustc --crate-name pm [..]--crate-type proc-macro[..] -[RUNNING] `rustc --crate-name pm [..]--test[..] -[COMPILING] foo [..] -[RUNNING] `rustc --crate-name foo [..]--test[..] -[RUNNING] `rustc --crate-name pm_test [..]--test[..] -[RUNNING] `rustc --crate-name foo [..]--crate-type lib[..] -[FINISHED] [..] -", +[COMPILING] shared v0.1.0 ([ROOT]/foo/shared) +[RUNNING] `rustc --crate-name shared [..]--crate-type lib [..]` +[RUNNING] `rustc --crate-name shared [..]--crate-type lib [..]` +[RUNNING] `rustc --crate-name shared [..]--test[..]` +[COMPILING] pm v0.1.0 ([ROOT]/foo/pm) +[RUNNING] `rustc --crate-name pm [..]--crate-type proc-macro[..]` +[RUNNING] `rustc --crate-name pm [..]--test[..]` +[COMPILING] foo v0.1.0 ([ROOT]/foo/foo) +[RUNNING] `rustc --crate-name foo [..]--crate-type lib [..]` +[RUNNING] `rustc --crate-name foo [..]--test[..]` +[RUNNING] `rustc --crate-name pm_test [..]--test[..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + .unordered(), ) .run(); // And again, should stay fresh. p.cargo("build --workspace --all-targets --all-features -v") - .with_stderr_unordered( - "\ -[FRESH] shared [..] -[FRESH] pm [..] -[FRESH] foo [..] -[FINISHED] [..]", + .with_stderr_data( + str![[r#" +[FRESH] pm v0.1.0 ([ROOT]/foo/pm) +[FRESH] foo v0.1.0 ([ROOT]/foo/foo) +[FRESH] shared v0.1.0 ([ROOT]/foo/shared) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + .unordered(), ) .run(); } @@ -2470,13 +2594,12 @@ fn edition_2021_default_2() { // First without edition. p.cargo("tree -f") .arg("{p} feats:{f}") - .with_stdout( - "\ -foo v0.1.0 [..] + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) feats: ├── bar v1.0.0 feats: └── common v1.0.0 feats:f1 -", - ) + +"#]]) .run(); p.change_file( @@ -2498,13 +2621,12 @@ foo v0.1.0 [..] // Importantly, this does not include `f1` on `common`. p.cargo("tree -f") .arg("{p} feats:{f}") - .with_stdout( - "\ -foo v0.1.0 [..] + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) feats: ├── bar v1.0.0 feats: └── common v1.0.0 feats: -", - ) + +"#]]) .run(); } @@ -2555,31 +2677,35 @@ fn all_features_merges_with_features() { .build(); p.cargo("run --example ex --all-features --features dep/feat1") - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 2 packages to latest compatible versions [DOWNLOADING] crates ... -[DOWNLOADED] [..] +[DOWNLOADED] dep v0.1.0 (registry `dummy-registry`) [COMPILING] dep v0.1.0 -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] `target/debug/examples/ex[EXE]` -", - ) - .with_stdout("it works") + +"#]]) + .with_stdout_data(str![[r#" +it works + +"#]]) .run(); switch_to_resolver_2(&p); p.cargo("run --example ex --all-features --features dep/feat1") - .with_stderr( - "\ -[FINISHED] [..] + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] `target/debug/examples/ex[EXE]` -", - ) - .with_stdout("it works") + +"#]]) + .with_stdout_data(str![[r#" +it works + +"#]]) .run(); } @@ -2642,16 +2768,15 @@ fn dep_with_optional_host_deps_activated() { .build(); p.cargo("check") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 4 packages to latest compatible versions -[COMPILING] serde_build v0.1.0 ([CWD]/serde_build) -[COMPILING] serde_derive v0.1.0 ([CWD]/serde_derive) -[COMPILING] serde v0.1.0 ([CWD]/serde) -[CHECKING] foo v0.1.0 ([CWD]) -[FINISHED] `dev` profile [..] -", - ) +[COMPILING] serde_build v0.1.0 ([ROOT]/foo/serde_build) +[COMPILING] serde_derive v0.1.0 ([ROOT]/foo/serde_derive) +[COMPILING] serde v0.1.0 ([ROOT]/foo/serde) +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -2688,13 +2813,12 @@ fn dont_unify_proc_macro_example_from_dependency() { .build(); p.cargo("check") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -[CHECKING] pm_helper v0.0.0 ([CWD]/pm_helper) -[CHECKING] foo v0.0.0 ([CWD]) -[FINISHED] `dev` [..] -", - ) +[CHECKING] pm_helper v0.0.0 ([ROOT]/foo/pm_helper) +[CHECKING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } From 5b77457b4c33d5dbb1dafc4dc53ab418bdc0661b Mon Sep 17 00:00:00 2001 From: eth3lbert Date: Wed, 19 Jun 2024 03:10:57 +0800 Subject: [PATCH 3/5] test: migrate features_namespaced to snapbox --- tests/testsuite/features_namespaced.rs | 603 +++++++++++++------------ 1 file changed, 308 insertions(+), 295 deletions(-) diff --git a/tests/testsuite/features_namespaced.rs b/tests/testsuite/features_namespaced.rs index e1639d3b8eb..462f1eca37f 100644 --- a/tests/testsuite/features_namespaced.rs +++ b/tests/testsuite/features_namespaced.rs @@ -1,9 +1,9 @@ //! Tests for namespaced features. -#![allow(deprecated)] - use super::features2::switch_to_resolver_2; +use cargo_test_support::prelude::*; use cargo_test_support::registry::{Dependency, Package, RegistryBuilder}; +use cargo_test_support::str; use cargo_test_support::{project, publish}; #[cargo_test] @@ -31,19 +31,18 @@ fn dependency_with_crate_syntax() { .build(); p.cargo("check") - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 3 packages to latest compatible versions [DOWNLOADING] crates ... -[DOWNLOADED] [..] -[DOWNLOADED] [..] +[DOWNLOADED] baz v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`) [CHECKING] baz v1.0.0 [CHECKING] bar v1.0.0 -[CHECKING] foo v0.1.0 [..] -[FINISHED] [..] -", - ) +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -69,14 +68,13 @@ fn namespaced_invalid_feature() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `bar` includes `baz` which is neither a dependency nor another feature -", - ) + +"#]]) .run(); } @@ -101,14 +99,13 @@ fn namespaced_invalid_dependency() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `bar` includes `dep:baz`, but `baz` is not listed as a dependency -", - ) + +"#]]) .run(); } @@ -135,17 +132,15 @@ fn namespaced_non_optional_dependency() { .build(); p.cargo("check") - .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `bar` includes `dep:baz`, but `baz` is not an optional dependency A non-optional dependency of the same name is defined; consider adding `optional = true` to its definition. -", - ) + +"#]]) .run(); } @@ -174,25 +169,23 @@ fn namespaced_implicit_feature() { .build(); p.cargo("check") - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 2 packages to latest compatible versions -[CHECKING] foo v0.0.1 [..] -[FINISHED] [..] -", - ) +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); p.cargo("check --features baz") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [DOWNLOADING] crates ... -[DOWNLOADED] baz v0.1.0 [..] +[DOWNLOADED] baz v0.1.0 (registry `dummy-registry`) [CHECKING] baz v0.1.0 -[CHECKING] foo v0.0.1 [..] -[FINISHED] [..] -", - ) +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -221,15 +214,14 @@ fn namespaced_shadowed_dep() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: optional dependency `baz` is not included in any feature Make sure that `dep:baz` is included in one of features in the [features] table. -", - ) + +"#]]) .run(); } @@ -281,15 +273,17 @@ fn namespaced_implicit_non_optional() { .file("src/main.rs", "fn main() {}") .build(); - p.cargo("check").with_status(101).with_stderr( - "\ -[ERROR] failed to parse manifest at `[..]` + p.cargo("check") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `bar` includes `baz`, but `baz` is not an optional dependency A non-optional dependency of the same name is defined; consider adding `optional = true` to its definition. -", - ).run(); + +"#]]) + .run(); } #[cargo_test] @@ -324,30 +318,31 @@ fn namespaced_same_name() { .build(); p.cargo("run") - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 2 packages to latest compatible versions -[COMPILING] foo v0.0.1 [..] -[FINISHED] [..] -[RUNNING] [..] -", - ) - .with_stdout("") +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `target/debug/foo[EXE]` + +"#]]) + .with_stdout_data("") .run(); p.cargo("run --features baz") - .with_stderr( - "\ + .with_stderr_data(str![[r#" [DOWNLOADING] crates ... -[DOWNLOADED] baz v0.1.0 [..] +[DOWNLOADED] baz v0.1.0 (registry `dummy-registry`) [COMPILING] baz v0.1.0 -[COMPILING] foo v0.0.1 [..] -[FINISHED] [..] -[RUNNING] [..] -", - ) - .with_stdout("baz") +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `target/debug/foo[EXE]` + +"#]]) + .with_stdout_data(str![[r#" +baz + +"#]]) .run(); } @@ -387,42 +382,43 @@ fn no_implicit_feature() { .build(); p.cargo("run") - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 3 packages to latest compatible versions -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] `target/debug/foo[EXE]` -", - ) - .with_stdout("") + +"#]]) + .with_stdout_data("") .run(); p.cargo("run --features regex") - .with_stderr_unordered( - "\ + .with_stderr_data( + str![[r#" [DOWNLOADING] crates ... -[DOWNLOADED] regex v1.0.0 [..] -[DOWNLOADED] lazy_static v1.0.0 [..] +[DOWNLOADED] regex v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] lazy_static v1.0.0 (registry `dummy-registry`) [COMPILING] regex v1.0.0 [COMPILING] lazy_static v1.0.0 -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] `target/debug/foo[EXE]` -", + +"#]] + .unordered(), ) - .with_stdout("regex") + .with_stdout_data(str![[r#" +regex + +"#]]) .run(); p.cargo("run --features lazy_static") - .with_stderr( - "\ -[ERROR] Package `foo v0.1.0 [..]` does not have feature `lazy_static`. \ -It has an optional dependency with that name, but that dependency uses the \"dep:\" \ -syntax in the features table, so it does not have an implicit feature with that name. -", - ) + .with_stderr_data(str![[r#" +[ERROR] Package `foo v0.1.0 ([ROOT]/foo)` does not have feature `lazy_static`. It has an optional dependency with that name, but that dependency uses the "dep:" syntax in the features table, so it does not have an implicit feature with that name. + +"#]]) .with_status(101) .run(); } @@ -452,16 +448,15 @@ fn crate_syntax_bad_name() { p.cargo("check --features dep:bar") .with_status(101) - .with_stderr( - "\ + .with_stderr_data(str![[r#" [ERROR] feature named `dep:bar` is not allowed to start with `dep:` --> Cargo.toml:11:17 | -11 | \"dep:bar\" = [] +11 | "dep:bar" = [] | ^^^^^^^^^ | -", - ) + +"#]]) .run(); } @@ -490,15 +485,14 @@ fn crate_syntax_in_dep() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[CWD]/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `dep:baz` in dependency `bar` is not allowed to use explicit `dep:` syntax - If you want to enable [..] -", - ) + If you want to enable an optional dependency, specify the name of the optional dependency without the `dep:` prefix, or specify a feature from the dependency's `[features]` table that enables the optional dependency. + +"#]]) .run(); } @@ -524,21 +518,19 @@ fn crate_syntax_cli() { p.cargo("check --features dep:bar") .with_status(101) - .with_stderr( - "\ + .with_stderr_data(str![[r#" [ERROR] feature `dep:bar` is not allowed to use explicit `dep:` syntax -", - ) + +"#]]) .run(); switch_to_resolver_2(&p); p.cargo("check --features dep:bar") .with_status(101) - .with_stderr( - "\ + .with_stderr_data(str![[r#" [ERROR] feature `dep:bar` is not allowed to use explicit `dep:` syntax -", - ) + +"#]]) .run(); } @@ -568,14 +560,12 @@ fn crate_required_features() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 2 packages to latest compatible versions -[ERROR] invalid feature `dep:bar` in required-features of target `foo`: \ -`dep:` prefixed feature values are not allowed in required-features -", - ) +[ERROR] invalid feature `dep:bar` in required-features of target `foo`: `dep:` prefixed feature values are not allowed in required-features + +"#]]) .run(); } @@ -600,48 +590,84 @@ fn json_exposed() { .build(); p.cargo("metadata --no-deps") - .with_json( - r#" - { - "packages": [ - { - "name": "foo", - "version": "0.1.0", - "id": "[..]foo#0.1.0", - "license": null, - "license_file": null, - "description": null, - "homepage": null, - "documentation": null, - "source": null, - "dependencies": "{...}", - "targets": "{...}", - "features": { - "bar": ["dep:bar"] - }, - "manifest_path": "[..]foo/Cargo.toml", - "metadata": null, - "publish": null, - "authors": [], - "categories": [], - "default_run": null, - "keywords": [], - "readme": null, - "repository": null, - "rust_version": null, - "edition": "2015", - "links": null - } - ], - "workspace_members": "{...}", - "workspace_default_members": "{...}", - "resolve": null, - "target_directory": "[..]foo/target", - "version": 1, - "workspace_root": "[..]foo", - "metadata": null - } - "#, + .with_stdout_data( + str![[r#" +{ + "metadata": null, + "packages": [ + { + "authors": [], + "categories": [], + "default_run": null, + "dependencies": [ + { + "features": [], + "kind": null, + "name": "bar", + "optional": true, + "registry": null, + "rename": null, + "req": "^1.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "target": null, + "uses_default_features": true + } + ], + "description": null, + "documentation": null, + "edition": "2015", + "features": { + "bar": [ + "dep:bar" + ] + }, + "homepage": null, + "id": "path+[ROOTURL]/foo#0.1.0", + "keywords": [], + "license": null, + "license_file": null, + "links": null, + "manifest_path": "[ROOT]/foo/Cargo.toml", + "metadata": null, + "name": "foo", + "publish": null, + "readme": null, + "repository": null, + "rust_version": null, + "source": null, + "targets": [ + { + "crate_types": [ + "lib" + ], + "doc": true, + "doctest": true, + "edition": "2015", + "kind": [ + "lib" + ], + "name": "foo", + "src_path": "[ROOT]/foo/src/lib.rs", + "test": true + } + ], + "version": "0.1.0" + } + ], + "resolve": null, + "target_directory": "[ROOT]/foo/target", + "version": 1, + "workspace_default_members": [ + "path+[ROOTURL]/foo#0.1.0" + ], + "workspace_members": [ + "path+[ROOTURL]/foo#0.1.0" + ], + "workspace_root": "[ROOT]/foo" +} + +"#]] + .json(), ) .run(); } @@ -691,17 +717,16 @@ fn crate_feature_with_explicit() { .build(); p.cargo("check --features f1") - .with_stderr( - "\ -[UPDATING] [..] + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index [LOCKING] 2 packages to latest compatible versions [DOWNLOADING] crates ... -[DOWNLOADED] bar v1.0.0 [..] +[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`) [CHECKING] bar v1.0.0 -[CHECKING] foo v0.1.0 [..] -[FINISHED] [..] -", - ) +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) .run(); } @@ -732,15 +757,14 @@ fn optional_explicit_without_crate() { p.cargo("check") .with_status(101) - .with_stderr( - "\ -[ERROR] failed to parse manifest at [..] + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `feat2` includes `bar`, but `bar` is an optional dependency without an implicit feature Use `dep:bar` to enable the dependency. -", - ) + +"#]]) .run(); } @@ -773,67 +797,66 @@ fn tree() { .build(); p.cargo("tree -e features") - .with_stdout("foo v0.1.0 ([ROOT]/foo)") + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) + +"#]]) .run(); p.cargo("tree -e features --features a") - .with_stdout( - "\ + .with_stdout_data(str![[r#" foo v0.1.0 ([ROOT]/foo) -├── bar feature \"default\" +├── bar feature "default" │ └── bar v1.0.0 -│ └── baz feature \"default\" +│ └── baz feature "default" │ └── baz v1.0.0 -└── bar feature \"feat1\" +└── bar feature "feat1" └── bar v1.0.0 (*) -", - ) + +"#]]) .run(); p.cargo("tree -e features --features a -i bar") - .with_stdout( - "\ + .with_stdout_data(str![[r#" bar v1.0.0 -├── bar feature \"default\" +├── bar feature "default" │ └── foo v0.1.0 ([ROOT]/foo) -│ ├── foo feature \"a\" (command-line) -│ ├── foo feature \"bar\" -│ │ └── foo feature \"a\" (command-line) -│ └── foo feature \"default\" (command-line) -├── bar feature \"feat1\" +│ ├── foo feature "a" (command-line) +│ ├── foo feature "bar" +│ │ └── foo feature "a" (command-line) +│ └── foo feature "default" (command-line) +├── bar feature "feat1" │ └── foo v0.1.0 ([ROOT]/foo) (*) -└── bar feature \"feat2\" - └── foo feature \"a\" (command-line) -", - ) +└── bar feature "feat2" + └── foo feature "a" (command-line) + +"#]]) .run(); p.cargo("tree -e features --features bar") - .with_stdout( - "\ + .with_stdout_data(str![[r#" foo v0.1.0 ([ROOT]/foo) -├── bar feature \"default\" +├── bar feature "default" │ └── bar v1.0.0 -│ └── baz feature \"default\" +│ └── baz feature "default" │ └── baz v1.0.0 -└── bar feature \"feat1\" +└── bar feature "feat1" └── bar v1.0.0 (*) -", - ) + +"#]]) .run(); p.cargo("tree -e features --features bar -i bar") - .with_stdout( - "\ + .with_stdout_data(str![[r#" bar v1.0.0 -├── bar feature \"default\" +├── bar feature "default" │ └── foo v0.1.0 ([ROOT]/foo) -│ ├── foo feature \"bar\" (command-line) -│ └── foo feature \"default\" (command-line) -└── bar feature \"feat1\" +│ ├── foo feature "bar" (command-line) +│ └── foo feature "default" (command-line) +└── bar feature "feat1" └── foo v0.1.0 ([ROOT]/foo) (*) -", - ) + +"#]]) .run(); } @@ -861,29 +884,30 @@ fn tree_no_implicit() { .build(); p.cargo("tree -e features") - .with_stdout("foo v0.1.0 ([ROOT]/foo)") + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) + +"#]]) .run(); p.cargo("tree -e features --all-features") - .with_stdout( - "\ + .with_stdout_data(str![[r#" foo v0.1.0 ([ROOT]/foo) -└── bar feature \"default\" +└── bar feature "default" └── bar v1.0.0 -", - ) + +"#]]) .run(); p.cargo("tree -e features -i bar --all-features") - .with_stdout( - "\ + .with_stdout_data(str![[r#" bar v1.0.0 -└── bar feature \"default\" +└── bar feature "default" └── foo v0.1.0 ([ROOT]/foo) - ├── foo feature \"a\" (command-line) - └── foo feature \"default\" (command-line) -", - ) + ├── foo feature "a" (command-line) + └── foo feature "default" (command-line) + +"#]]) .run(); } @@ -920,18 +944,17 @@ fn publish_no_implicit() { p.cargo("publish --no-verify") .replace_crates_io(registry.index_url()) - .with_stderr( - "\ -[UPDATING] [..] -[PACKAGING] foo v0.1.0 [..] -[PACKAGED] [..] -[UPLOADING] foo v0.1.0 [..] -[UPLOADED] foo v0.1.0 [..] -[NOTE] waiting [..] -You may press ctrl-c [..] -[PUBLISHED] foo v0.1.0 [..] -", - ) + .with_stderr_data(str![[r#" +[UPDATING] crates.io index +[PACKAGING] foo v0.1.0 ([ROOT]/foo) +[PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed) +[UPLOADING] foo v0.1.0 ([ROOT]/foo) +[UPLOADED] foo v0.1.0 to registry `crates-io` +[NOTE] waiting for `foo v0.1.0` to be available at registry `crates-io`. +You may press ctrl-c to skip waiting; the crate should be available shortly. +[PUBLISHED] foo v0.1.0 at registry `crates-io` + +"#]]) .run(); publish::validate_upload_with_contents( @@ -1051,22 +1074,21 @@ fn publish() { p.cargo("publish") .replace_crates_io(registry.index_url()) - .with_stderr( - "\ -[UPDATING] [..] -[PACKAGING] foo v0.1.0 [..] -[PACKAGED] [..] -[VERIFYING] foo v0.1.0 [..] -[UPDATING] [..] -[COMPILING] foo v0.1.0 [..] -[FINISHED] [..] -[UPLOADING] foo v0.1.0 [..] -[UPLOADED] foo v0.1.0 [..] -[NOTE] waiting [..] -You may press ctrl-c [..] -[PUBLISHED] foo v0.1.0 [..] -", - ) + .with_stderr_data(str![[r#" +[UPDATING] crates.io index +[PACKAGING] foo v0.1.0 ([ROOT]/foo) +[PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed) +[VERIFYING] foo v0.1.0 ([ROOT]/foo) +[UPDATING] crates.io index +[COMPILING] foo v0.1.0 ([ROOT]/foo/target/package/foo-0.1.0) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[UPLOADING] foo v0.1.0 ([ROOT]/foo) +[UPLOADED] foo v0.1.0 to registry `crates-io` +[NOTE] waiting for `foo v0.1.0` to be available at registry `crates-io`. +You may press ctrl-c to skip waiting; the crate should be available shortly. +[PUBLISHED] foo v0.1.0 at registry `crates-io` + +"#]]) .run(); publish::validate_upload_with_contents( @@ -1173,15 +1195,14 @@ fn namespaced_feature_together() { .build(); p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[ROOT]/foo/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `f1` includes `dep:bar/bar-feat` with both `dep:` and `/` To fix this, remove the `dep:` prefix. -", - ) + +"#]]) .run(); // Weak dependency shouldn't have extra err. @@ -1202,15 +1223,14 @@ Caused by: ); p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[ROOT]/foo/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `f1` includes `dep:bar?/bar-feat` with both `dep:` and `/` To fix this, remove the `dep:` prefix. -", - ) + +"#]]) .run(); // If dep: is already specified, shouldn't have extra err. @@ -1231,15 +1251,14 @@ Caused by: ); p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[ROOT]/foo/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `f1` includes `dep:bar/bar-feat` with both `dep:` and `/` To fix this, remove the `dep:` prefix. -", - ) + +"#]]) .run(); // Only when the other 3 cases aren't true should it give some extra help. @@ -1260,18 +1279,16 @@ Caused by: ); p.cargo("check") .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[ROOT]/foo/Cargo.toml` + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: feature `f1` includes `dep:bar/bar-feat` with both `dep:` and `/` To fix this, remove the `dep:` prefix. - If the intent is to avoid creating an implicit feature `bar` for an optional \ - dependency, then consider replacing this with two values: - \"dep:bar\", \"bar/bar-feat\" -", - ) + If the intent is to avoid creating an implicit feature `bar` for an optional dependency, then consider replacing this with two values: + "dep:bar", "bar/bar-feat" + +"#]]) .run(); } @@ -1314,47 +1331,43 @@ fn dep_feature_when_hidden() { p.cargo("tree -f") .arg("{p} features={f}") - .with_stdout( - "\ -foo v0.1.0 ([ROOT]/foo) features=", - ) - .with_stderr( - "\ + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) features= + +"#]]) + .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -", - ) + +"#]]) .run(); p.cargo("tree -F f1 -f") .arg("{p} features={f}") - .with_stdout( - "\ + .with_stdout_data(str![[r#" foo v0.1.0 ([ROOT]/foo) features=f1 └── bar v0.1.0 ([ROOT]/foo/bar) features= -", - ) - .with_stderr("") + +"#]]) + .with_stderr_data("") .run(); p.cargo("tree -F f2 -f") .arg("{p} features={f}") - .with_stdout( - "\ + .with_stdout_data(str![[r#" foo v0.1.0 ([ROOT]/foo) features=f2 └── bar v0.1.0 ([ROOT]/foo/bar) features=bar_feat -", - ) - .with_stderr("") + +"#]]) + .with_stderr_data("") .run(); p.cargo("tree --all-features -f") .arg("{p} features={f}") - .with_stdout( - "\ + .with_stdout_data(str![[r#" foo v0.1.0 ([ROOT]/foo) features=f1,f2 └── bar v0.1.0 ([ROOT]/foo/bar) features=bar_feat -", - ) - .with_stderr("") + +"#]]) + .with_stderr_data("") .run(); } From c2301fa75d4441d2710b915dbd78e12c03ff5042 Mon Sep 17 00:00:00 2001 From: eth3lbert Date: Fri, 21 Jun 2024 13:52:01 +0800 Subject: [PATCH 4/5] fixup! test: migrate features_namespaced to snapbox --- tests/testsuite/features_namespaced.rs | 32 ++------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/tests/testsuite/features_namespaced.rs b/tests/testsuite/features_namespaced.rs index 462f1eca37f..f47cfbbbe8d 100644 --- a/tests/testsuite/features_namespaced.rs +++ b/tests/testsuite/features_namespaced.rs @@ -599,20 +599,7 @@ fn json_exposed() { "authors": [], "categories": [], "default_run": null, - "dependencies": [ - { - "features": [], - "kind": null, - "name": "bar", - "optional": true, - "registry": null, - "rename": null, - "req": "^1.0", - "source": "registry+https://github.com/rust-lang/crates.io-index", - "target": null, - "uses_default_features": true - } - ], + "dependencies": "{...}", "description": null, "documentation": null, "edition": "2015", @@ -635,22 +622,7 @@ fn json_exposed() { "repository": null, "rust_version": null, "source": null, - "targets": [ - { - "crate_types": [ - "lib" - ], - "doc": true, - "doctest": true, - "edition": "2015", - "kind": [ - "lib" - ], - "name": "foo", - "src_path": "[ROOT]/foo/src/lib.rs", - "test": true - } - ], + "targets": "{...}", "version": "0.1.0" } ], From a50e0a121c7a673806a09bb6896c6eca85760d9f Mon Sep 17 00:00:00 2001 From: eth3lbert Date: Fri, 21 Jun 2024 13:57:16 +0800 Subject: [PATCH 5/5] fixup! test: migrate features2 to snapbox --- tests/testsuite/features2.rs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/tests/testsuite/features2.rs b/tests/testsuite/features2.rs index 2a51585bc83..200094dcce4 100644 --- a/tests/testsuite/features2.rs +++ b/tests/testsuite/features2.rs @@ -1153,6 +1153,7 @@ it is false .exists()); } +#[allow(deprecated)] #[cargo_test] fn proc_macro_ws() { // Checks for bug with proc-macro in a workspace with dependency (shouldn't panic). @@ -1225,22 +1226,12 @@ fn proc_macro_ws() { "#]]) .run(); // Selecting just foo will build without unification. - let expected = if cfg!(target_os = "macos") { - str![[r#" -... -[RUNNING] `rustc --crate-name foo --edition=2015 foo/src/lib.rs --error-format=json --json=[..] --crate-type lib --emit=[..] -C embed-bitcode=no -C debuginfo=2 -C split-debuginfo=unpacked --check-cfg[..] --check-cfg[..] -C metadata=[..] -C extra-filename=[..] --out-dir [ROOT]/foo/target/debug/deps -L dependency=[ROOT]/foo/target/debug/deps` -... -"#]] - } else { - str![[r#" -... -[RUNNING] `rustc --crate-name foo --edition=2015 foo/src/lib.rs --error-format=json --json=[..] --crate-type lib --emit=[..] -C embed-bitcode=no -C debuginfo=2 --check-cfg[..] --check-cfg[..] -C metadata=[..] -C extra-filename=[..] --out-dir [ROOT]/foo/target/debug/deps -L dependency=[ROOT]/foo/target/debug/deps` -... -"#]] - }; p.cargo("check -p foo -v") // Make sure `foo` is built without feat1 - .with_stderr_data(expected) + .with_stderr_line_without( + &["[RUNNING] `rustc --crate-name foo --edition=2015"], + &["--cfg[..]feat1"], + ) .run(); }