summaryrefslogtreecommitdiffstats
path: root/src/tools/cargo/tests/testsuite/required_features.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/cargo/tests/testsuite/required_features.rs')
-rw-r--r--src/tools/cargo/tests/testsuite/required_features.rs1452
1 files changed, 1452 insertions, 0 deletions
diff --git a/src/tools/cargo/tests/testsuite/required_features.rs b/src/tools/cargo/tests/testsuite/required_features.rs
new file mode 100644
index 000000000..ac6c9d233
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/required_features.rs
@@ -0,0 +1,1452 @@
+//! Tests for targets with `required-features`.
+
+use cargo_test_support::install::{
+ assert_has_installed_exe, assert_has_not_installed_exe, cargo_home,
+};
+use cargo_test_support::is_nightly;
+use cargo_test_support::paths::CargoPathExt;
+use cargo_test_support::project;
+
+#[cargo_test]
+fn build_bin_default_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a"]
+ a = []
+
+ [[bin]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file(
+ "src/main.rs",
+ r#"
+ extern crate foo;
+
+ #[cfg(feature = "a")]
+ fn test() {
+ foo::foo();
+ }
+
+ fn main() {}
+ "#,
+ )
+ .file("src/lib.rs", r#"#[cfg(feature = "a")] pub fn foo() {}"#)
+ .build();
+
+ p.cargo("build").run();
+ assert!(p.bin("foo").is_file());
+
+ p.cargo("build --no-default-features").run();
+
+ p.cargo("build --bin=foo").run();
+ assert!(p.bin("foo").is_file());
+
+ p.cargo("build --bin=foo --no-default-features")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo` in package `foo` requires the features: `a`
+Consider enabling them by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_bin_arg_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ a = []
+
+ [[bin]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ p.cargo("build --features a").run();
+ assert!(p.bin("foo").is_file());
+}
+
+#[cargo_test]
+fn build_bin_multiple_required_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a", "b"]
+ a = []
+ b = ["a"]
+ c = []
+
+ [[bin]]
+ name = "foo_1"
+ path = "src/foo_1.rs"
+ required-features = ["b", "c"]
+
+ [[bin]]
+ name = "foo_2"
+ path = "src/foo_2.rs"
+ required-features = ["a"]
+ "#,
+ )
+ .file("src/foo_1.rs", "fn main() {}")
+ .file("src/foo_2.rs", "fn main() {}")
+ .build();
+
+ p.cargo("build").run();
+
+ assert!(!p.bin("foo_1").is_file());
+ assert!(p.bin("foo_2").is_file());
+
+ p.cargo("build --features c").run();
+
+ assert!(p.bin("foo_1").is_file());
+ assert!(p.bin("foo_2").is_file());
+
+ p.cargo("build --no-default-features").run();
+}
+
+#[cargo_test]
+fn build_example_default_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a"]
+ a = []
+
+ [[example]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file("examples/foo.rs", "fn main() {}")
+ .build();
+
+ p.cargo("build --example=foo").run();
+ assert!(p.bin("examples/foo").is_file());
+
+ p.cargo("build --example=foo --no-default-features")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo` in package `foo` requires the features: `a`
+Consider enabling them by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_example_arg_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ a = []
+
+ [[example]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file("examples/foo.rs", "fn main() {}")
+ .build();
+
+ p.cargo("build --example=foo --features a").run();
+ assert!(p.bin("examples/foo").is_file());
+}
+
+#[cargo_test]
+fn build_example_multiple_required_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a", "b"]
+ a = []
+ b = ["a"]
+ c = []
+
+ [[example]]
+ name = "foo_1"
+ required-features = ["b", "c"]
+
+ [[example]]
+ name = "foo_2"
+ required-features = ["a"]
+ "#,
+ )
+ .file("examples/foo_1.rs", "fn main() {}")
+ .file("examples/foo_2.rs", "fn main() {}")
+ .build();
+
+ p.cargo("build --example=foo_1")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo_1` in package `foo` requires the features: `b`, `c`
+Consider enabling them by passing, e.g., `--features=\"b c\"`
+",
+ )
+ .run();
+ p.cargo("build --example=foo_2").run();
+
+ assert!(!p.bin("examples/foo_1").is_file());
+ assert!(p.bin("examples/foo_2").is_file());
+
+ p.cargo("build --example=foo_1 --features c").run();
+ p.cargo("build --example=foo_2 --features c").run();
+
+ assert!(p.bin("examples/foo_1").is_file());
+ assert!(p.bin("examples/foo_2").is_file());
+
+ p.cargo("build --example=foo_1 --no-default-features")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo_1` in package `foo` requires the features: `b`, `c`
+Consider enabling them by passing, e.g., `--features=\"b c\"`
+",
+ )
+ .run();
+ p.cargo("build --example=foo_2 --no-default-features")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo_2` in package `foo` requires the features: `a`
+Consider enabling them by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn test_default_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a"]
+ a = []
+
+ [[test]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file("tests/foo.rs", "#[test]\nfn test() {}")
+ .build();
+
+ p.cargo("test")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] [..] (target/debug/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test test ... ok")
+ .run();
+
+ p.cargo("test --no-default-features")
+ .with_stderr("[FINISHED] test [unoptimized + debuginfo] target(s) in [..]")
+ .with_stdout("")
+ .run();
+
+ p.cargo("test --test=foo")
+ .with_stderr(
+ "\
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] [..] (target/debug/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test test ... ok")
+ .run();
+
+ p.cargo("test --test=foo --no-default-features")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo` in package `foo` requires the features: `a`
+Consider enabling them by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn test_arg_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ a = []
+
+ [[test]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file("tests/foo.rs", "#[test]\nfn test() {}")
+ .build();
+
+ p.cargo("test --features a")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] [..] (target/debug/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test test ... ok")
+ .run();
+}
+
+#[cargo_test]
+fn test_multiple_required_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a", "b"]
+ a = []
+ b = ["a"]
+ c = []
+
+ [[test]]
+ name = "foo_1"
+ required-features = ["b", "c"]
+
+ [[test]]
+ name = "foo_2"
+ required-features = ["a"]
+ "#,
+ )
+ .file("tests/foo_1.rs", "#[test]\nfn test() {}")
+ .file("tests/foo_2.rs", "#[test]\nfn test() {}")
+ .build();
+
+ p.cargo("test")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] [..] (target/debug/deps/foo_2-[..][EXE])",
+ )
+ .with_stdout_contains("test test ... ok")
+ .run();
+
+ p.cargo("test --features c")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] [..] (target/debug/deps/foo_1-[..][EXE])
+[RUNNING] [..] (target/debug/deps/foo_2-[..][EXE])",
+ )
+ .with_stdout_contains_n("test test ... ok", 2)
+ .run();
+
+ p.cargo("test --no-default-features")
+ .with_stderr("[FINISHED] test [unoptimized + debuginfo] target(s) in [..]")
+ .with_stdout("")
+ .run();
+}
+
+#[cargo_test(nightly, reason = "bench")]
+fn bench_default_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a"]
+ a = []
+
+ [[bench]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file(
+ "benches/foo.rs",
+ r#"
+ #![feature(test)]
+ extern crate test;
+
+ #[bench]
+ fn bench(_: &mut test::Bencher) {
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("bench")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] bench [optimized] target(s) in [..]
+[RUNNING] [..] (target/release/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test bench ... bench: [..]")
+ .run();
+
+ p.cargo("bench --no-default-features")
+ .with_stderr("[FINISHED] bench [optimized] target(s) in [..]".to_string())
+ .with_stdout("")
+ .run();
+
+ p.cargo("bench --bench=foo")
+ .with_stderr(
+ "\
+[FINISHED] bench [optimized] target(s) in [..]
+[RUNNING] [..] (target/release/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test bench ... bench: [..]")
+ .run();
+
+ p.cargo("bench --bench=foo --no-default-features")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo` in package `foo` requires the features: `a`
+Consider enabling them by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+}
+
+#[cargo_test(nightly, reason = "bench")]
+fn bench_arg_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ a = []
+
+ [[bench]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file(
+ "benches/foo.rs",
+ r#"
+ #![feature(test)]
+ extern crate test;
+
+ #[bench]
+ fn bench(_: &mut test::Bencher) {
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("bench --features a")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] bench [optimized] target(s) in [..]
+[RUNNING] [..] (target/release/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test bench ... bench: [..]")
+ .run();
+}
+
+#[cargo_test(nightly, reason = "bench")]
+fn bench_multiple_required_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a", "b"]
+ a = []
+ b = ["a"]
+ c = []
+
+ [[bench]]
+ name = "foo_1"
+ required-features = ["b", "c"]
+
+ [[bench]]
+ name = "foo_2"
+ required-features = ["a"]
+ "#,
+ )
+ .file(
+ "benches/foo_1.rs",
+ r#"
+ #![feature(test)]
+ extern crate test;
+
+ #[bench]
+ fn bench(_: &mut test::Bencher) {
+ }
+ "#,
+ )
+ .file(
+ "benches/foo_2.rs",
+ r#"
+ #![feature(test)]
+ extern crate test;
+
+ #[bench]
+ fn bench(_: &mut test::Bencher) {
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("bench")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] bench [optimized] target(s) in [..]
+[RUNNING] [..] (target/release/deps/foo_2-[..][EXE])",
+ )
+ .with_stdout_contains("test bench ... bench: [..]")
+ .run();
+
+ p.cargo("bench --features c")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] bench [optimized] target(s) in [..]
+[RUNNING] [..] (target/release/deps/foo_1-[..][EXE])
+[RUNNING] [..] (target/release/deps/foo_2-[..][EXE])",
+ )
+ .with_stdout_contains_n("test bench ... bench: [..]", 2)
+ .run();
+
+ p.cargo("bench --no-default-features")
+ .with_stderr("[FINISHED] bench [optimized] target(s) in [..]")
+ .with_stdout("")
+ .run();
+}
+
+#[cargo_test]
+fn install_default_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a"]
+ a = []
+
+ [[bin]]
+ name = "foo"
+ required-features = ["a"]
+
+ [[example]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .file("examples/foo.rs", "fn main() {}")
+ .build();
+
+ p.cargo("install --path .").run();
+ assert_has_installed_exe(cargo_home(), "foo");
+ p.cargo("uninstall foo").run();
+
+ p.cargo("install --path . --no-default-features")
+ .with_stderr(
+ "\
+[INSTALLING] foo v0.0.1 ([..])
+[FINISHED] release [optimized] target(s) in [..]
+[WARNING] none of the package's binaries are available for install using the selected features
+ bin \"foo\" requires the features: `a`
+ example \"foo\" requires the features: `a`
+Consider enabling some of the needed features by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+ assert_has_not_installed_exe(cargo_home(), "foo");
+
+ p.cargo("install --path . --bin=foo").run();
+ assert_has_installed_exe(cargo_home(), "foo");
+ p.cargo("uninstall foo").run();
+
+ p.cargo("install --path . --bin=foo --no-default-features")
+ .with_status(101)
+ .with_stderr(
+ "\
+[INSTALLING] foo v0.0.1 ([..])
+[ERROR] failed to compile `foo v0.0.1 ([..])`, intermediate artifacts can be found at \
+ `[..]target`
+
+Caused by:
+ target `foo` in package `foo` requires the features: `a`
+ Consider enabling them by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+ assert_has_not_installed_exe(cargo_home(), "foo");
+
+ p.cargo("install --path . --example=foo").run();
+ assert_has_installed_exe(cargo_home(), "foo");
+ p.cargo("uninstall foo").run();
+
+ p.cargo("install --path . --example=foo --no-default-features")
+ .with_status(101)
+ .with_stderr(
+ "\
+[INSTALLING] foo v0.0.1 ([..])
+[ERROR] failed to compile `foo v0.0.1 ([..])`, intermediate artifacts can be found at \
+ `[..]target`
+
+Caused by:
+ target `foo` in package `foo` requires the features: `a`
+ Consider enabling them by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+ assert_has_not_installed_exe(cargo_home(), "foo");
+}
+
+#[cargo_test]
+fn install_arg_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ a = []
+
+ [[bin]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ p.cargo("install --features a").run();
+ assert_has_installed_exe(cargo_home(), "foo");
+ p.cargo("uninstall foo").run();
+}
+
+#[cargo_test]
+fn install_multiple_required_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a", "b"]
+ a = []
+ b = ["a"]
+ c = []
+
+ [[bin]]
+ name = "foo_1"
+ path = "src/foo_1.rs"
+ required-features = ["b", "c"]
+
+ [[bin]]
+ name = "foo_2"
+ path = "src/foo_2.rs"
+ required-features = ["a"]
+
+ [[example]]
+ name = "foo_3"
+ path = "src/foo_3.rs"
+ required-features = ["b", "c"]
+
+ [[example]]
+ name = "foo_4"
+ path = "src/foo_4.rs"
+ required-features = ["a"]
+ "#,
+ )
+ .file("src/foo_1.rs", "fn main() {}")
+ .file("src/foo_2.rs", "fn main() {}")
+ .file("src/foo_3.rs", "fn main() {}")
+ .file("src/foo_4.rs", "fn main() {}")
+ .build();
+
+ p.cargo("install --path .").run();
+ assert_has_not_installed_exe(cargo_home(), "foo_1");
+ assert_has_installed_exe(cargo_home(), "foo_2");
+ assert_has_not_installed_exe(cargo_home(), "foo_3");
+ assert_has_not_installed_exe(cargo_home(), "foo_4");
+ p.cargo("uninstall foo").run();
+
+ p.cargo("install --path . --bins --examples").run();
+ assert_has_not_installed_exe(cargo_home(), "foo_1");
+ assert_has_installed_exe(cargo_home(), "foo_2");
+ assert_has_not_installed_exe(cargo_home(), "foo_3");
+ assert_has_installed_exe(cargo_home(), "foo_4");
+ p.cargo("uninstall foo").run();
+
+ p.cargo("install --path . --features c").run();
+ assert_has_installed_exe(cargo_home(), "foo_1");
+ assert_has_installed_exe(cargo_home(), "foo_2");
+ assert_has_not_installed_exe(cargo_home(), "foo_3");
+ assert_has_not_installed_exe(cargo_home(), "foo_4");
+ p.cargo("uninstall foo").run();
+
+ p.cargo("install --path . --features c --bins --examples")
+ .run();
+ assert_has_installed_exe(cargo_home(), "foo_1");
+ assert_has_installed_exe(cargo_home(), "foo_2");
+ assert_has_installed_exe(cargo_home(), "foo_3");
+ assert_has_installed_exe(cargo_home(), "foo_4");
+ p.cargo("uninstall foo").run();
+
+ p.cargo("install --path . --no-default-features")
+ .with_stderr(
+ "\
+[INSTALLING] foo v0.0.1 ([..])
+[FINISHED] release [optimized] target(s) in [..]
+[WARNING] none of the package's binaries are available for install using the selected features
+ bin \"foo_1\" requires the features: `b`, `c`
+ bin \"foo_2\" requires the features: `a`
+ example \"foo_3\" requires the features: `b`, `c`
+ example \"foo_4\" requires the features: `a`
+Consider enabling some of the needed features by passing, e.g., `--features=\"b c\"`
+",
+ )
+ .run();
+ p.cargo("install --path . --no-default-features --bins")
+ .with_stderr(
+ "\
+[INSTALLING] foo v0.0.1 ([..])
+[WARNING] Target filter `bins` specified, but no targets matched. This is a no-op
+[FINISHED] release [optimized] target(s) in [..]
+[WARNING] none of the package's binaries are available for install using the selected features
+ bin \"foo_1\" requires the features: `b`, `c`
+ bin \"foo_2\" requires the features: `a`
+ example \"foo_3\" requires the features: `b`, `c`
+ example \"foo_4\" requires the features: `a`
+Consider enabling some of the needed features by passing, e.g., `--features=\"b c\"`
+",
+ )
+ .run();
+ p.cargo("install --path . --no-default-features --examples")
+ .with_stderr(
+ "\
+[INSTALLING] foo v0.0.1 ([..])
+[WARNING] Target filter `examples` specified, but no targets matched. This is a no-op
+[FINISHED] release [optimized] target(s) in [..]
+[WARNING] none of the package's binaries are available for install using the selected features
+ bin \"foo_1\" requires the features: `b`, `c`
+ bin \"foo_2\" requires the features: `a`
+ example \"foo_3\" requires the features: `b`, `c`
+ example \"foo_4\" requires the features: `a`
+Consider enabling some of the needed features by passing, e.g., `--features=\"b c\"`
+",
+ )
+ .run();
+ p.cargo("install --path . --no-default-features --bins --examples")
+ .with_stderr(
+ "\
+[INSTALLING] foo v0.0.1 ([..])
+[WARNING] Target filters `bins`, `examples` specified, but no targets matched. This is a no-op
+[FINISHED] release [optimized] target(s) in [..]
+[WARNING] none of the package's binaries are available for install using the selected features
+ bin \"foo_1\" requires the features: `b`, `c`
+ bin \"foo_2\" requires the features: `a`
+ example \"foo_3\" requires the features: `b`, `c`
+ example \"foo_4\" requires the features: `a`
+Consider enabling some of the needed features by passing, e.g., `--features=\"b c\"`
+",
+ )
+ .run();
+ assert_has_not_installed_exe(cargo_home(), "foo_1");
+ assert_has_not_installed_exe(cargo_home(), "foo_2");
+ assert_has_not_installed_exe(cargo_home(), "foo_3");
+ assert_has_not_installed_exe(cargo_home(), "foo_4");
+}
+
+#[cargo_test]
+fn dep_feature_in_toml() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = { path = "bar", features = ["a"] }
+
+ [[bin]]
+ name = "foo"
+ required-features = ["bar/a"]
+
+ [[example]]
+ name = "foo"
+ required-features = ["bar/a"]
+
+ [[test]]
+ name = "foo"
+ required-features = ["bar/a"]
+
+ [[bench]]
+ name = "foo"
+ required-features = ["bar/a"]
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .file("examples/foo.rs", "fn main() {}")
+ .file("tests/foo.rs", "#[test]\nfn test() {}")
+ .file(
+ "benches/foo.rs",
+ r#"
+ #![feature(test)]
+ extern crate test;
+
+ #[bench]
+ fn bench(_: &mut test::Bencher) {
+ }
+ "#,
+ )
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ a = []
+ "#,
+ )
+ .file("bar/src/lib.rs", "")
+ .build();
+
+ p.cargo("build").run();
+
+ // bin
+ p.cargo("build --bin=foo").run();
+ assert!(p.bin("foo").is_file());
+
+ // example
+ p.cargo("build --example=foo").run();
+ assert!(p.bin("examples/foo").is_file());
+
+ // test
+ p.cargo("test --test=foo")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] [..] (target/debug/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test test ... ok")
+ .run();
+
+ // bench
+ if is_nightly() {
+ p.cargo("bench --bench=foo")
+ .with_stderr(
+ "\
+[COMPILING] bar v0.0.1 ([CWD]/bar)
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] bench [optimized] target(s) in [..]
+[RUNNING] [..] (target/release/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test bench ... bench: [..]")
+ .run();
+ }
+
+ // install
+ p.cargo("install").run();
+ assert_has_installed_exe(cargo_home(), "foo");
+ p.cargo("uninstall foo").run();
+}
+
+#[cargo_test]
+fn dep_feature_in_cmd_line() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = { path = "bar" }
+
+ [[bin]]
+ name = "foo"
+ required-features = ["bar/a"]
+
+ [[example]]
+ name = "foo"
+ required-features = ["bar/a"]
+
+ [[test]]
+ name = "foo"
+ required-features = ["bar/a"]
+
+ [[bench]]
+ name = "foo"
+ required-features = ["bar/a"]
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .file("examples/foo.rs", "fn main() {}")
+ .file(
+ "tests/foo.rs",
+ r#"
+ #[test]
+ fn bin_is_built() {
+ let s = format!("target/debug/foo{}", std::env::consts::EXE_SUFFIX);
+ let p = std::path::Path::new(&s);
+ assert!(p.exists(), "foo does not exist");
+ }
+ "#,
+ )
+ .file(
+ "benches/foo.rs",
+ r#"
+ #![feature(test)]
+ extern crate test;
+
+ #[bench]
+ fn bench(_: &mut test::Bencher) {
+ }
+ "#,
+ )
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ a = []
+ "#,
+ )
+ .file("bar/src/lib.rs", "")
+ .build();
+
+ // This is a no-op
+ p.cargo("build").with_stderr("[FINISHED] dev [..]").run();
+ assert!(!p.bin("foo").is_file());
+
+ // bin
+ p.cargo("build --bin=foo")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo` in package `foo` requires the features: `bar/a`
+Consider enabling them by passing, e.g., `--features=\"bar/a\"`
+",
+ )
+ .run();
+
+ p.cargo("build --bin=foo --features bar/a").run();
+ assert!(p.bin("foo").is_file());
+
+ // example
+ p.cargo("build --example=foo")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo` in package `foo` requires the features: `bar/a`
+Consider enabling them by passing, e.g., `--features=\"bar/a\"`
+",
+ )
+ .run();
+
+ p.cargo("build --example=foo --features bar/a").run();
+ assert!(p.bin("examples/foo").is_file());
+
+ // test
+ // This is a no-op, since no tests are enabled
+ p.cargo("test")
+ .with_stderr("[FINISHED] test [unoptimized + debuginfo] target(s) in [..]")
+ .with_stdout("")
+ .run();
+
+ // Delete the target directory so this can check if the main.rs gets built.
+ p.build_dir().rm_rf();
+ p.cargo("test --test=foo --features bar/a")
+ .with_stderr(
+ "\
+[COMPILING] bar v0.0.1 ([CWD]/bar)
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] [..] (target/debug/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test bin_is_built ... ok")
+ .run();
+
+ // bench
+ if is_nightly() {
+ p.cargo("bench")
+ .with_stderr("[FINISHED] bench [optimized] target(s) in [..]")
+ .with_stdout("")
+ .run();
+
+ p.cargo("bench --bench=foo --features bar/a")
+ .with_stderr(
+ "\
+[COMPILING] bar v0.0.1 ([CWD]/bar)
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] bench [optimized] target(s) in [..]
+[RUNNING] [..] (target/release/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("test bench ... bench: [..]")
+ .run();
+ }
+
+ // install
+ p.cargo("install --path .")
+ .with_stderr(
+ "\
+[INSTALLING] foo v0.0.1 ([..])
+[FINISHED] release [optimized] target(s) in [..]
+[WARNING] none of the package's binaries are available for install using the selected features
+ bin \"foo\" requires the features: `bar/a`
+ example \"foo\" requires the features: `bar/a`
+Consider enabling some of the needed features by passing, e.g., `--features=\"bar/a\"`
+",
+ )
+ .run();
+ assert_has_not_installed_exe(cargo_home(), "foo");
+
+ p.cargo("install --features bar/a").run();
+ assert_has_installed_exe(cargo_home(), "foo");
+ p.cargo("uninstall foo").run();
+}
+
+#[cargo_test]
+fn test_skips_compiling_bin_with_missing_required_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ a = []
+
+ [[bin]]
+ name = "bin_foo"
+ path = "src/bin/foo.rs"
+ required-features = ["a"]
+ "#,
+ )
+ .file("src/bin/foo.rs", "extern crate bar; fn main() {}")
+ .file("tests/foo.rs", "")
+ .file("benches/foo.rs", "")
+ .build();
+
+ p.cargo("test")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] [..] (target/debug/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("running 0 tests")
+ .run();
+
+ p.cargo("test --features a -j 1")
+ .with_status(101)
+ .with_stderr_contains(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+error[E0463]: can't find crate for `bar`",
+ )
+ .run();
+
+ if is_nightly() {
+ p.cargo("bench")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[FINISHED] bench [optimized] target(s) in [..]
+[RUNNING] [..] (target/release/deps/foo-[..][EXE])",
+ )
+ .with_stdout_contains("running 0 tests")
+ .run();
+
+ p.cargo("bench --features a -j 1")
+ .with_status(101)
+ .with_stderr_contains(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+error[E0463]: can't find crate for `bar`",
+ )
+ .run();
+ }
+}
+
+#[cargo_test]
+fn run_default() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = []
+ a = []
+
+ [[bin]]
+ name = "foo"
+ required-features = ["a"]
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("src/main.rs", "extern crate foo; fn main() {}")
+ .build();
+
+ p.cargo("run")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: target `foo` in package `foo` requires the features: `a`
+Consider enabling them by passing, e.g., `--features=\"a\"`
+",
+ )
+ .run();
+
+ p.cargo("run --features a").run();
+}
+
+#[cargo_test]
+fn run_default_multiple_required_features() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [features]
+ default = ["a"]
+ a = []
+ b = []
+
+ [[bin]]
+ name = "foo1"
+ path = "src/foo1.rs"
+ required-features = ["a"]
+
+ [[bin]]
+ name = "foo3"
+ path = "src/foo3.rs"
+ required-features = ["b"]
+
+ [[bin]]
+ name = "foo2"
+ path = "src/foo2.rs"
+ required-features = ["b"]
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("src/foo1.rs", "extern crate foo; fn main() {}")
+ .file("src/foo3.rs", "extern crate foo; fn main() {}")
+ .file("src/foo2.rs", "extern crate foo; fn main() {}")
+ .build();
+
+ p.cargo("run")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: `cargo run` could not determine which binary to run[..]
+available binaries: foo1, foo2, foo3",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn renamed_required_features() {
+ // Test that required-features uses renamed package feature names.
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ edition = "2018"
+
+ [[bin]]
+ name = "x"
+ required-features = ["a1/f1"]
+
+ [dependencies]
+ a1 = {path="a1", package="a"}
+ a2 = {path="a2", package="a"}
+ "#,
+ )
+ .file(
+ "src/bin/x.rs",
+ r#"
+ fn main() {
+ a1::f();
+ a2::f();
+ }
+ "#,
+ )
+ .file(
+ "a1/Cargo.toml",
+ r#"
+ [package]
+ name = "a"
+ version = "0.1.0"
+
+ [features]
+ f1 = []
+ "#,
+ )
+ .file(
+ "a1/src/lib.rs",
+ r#"
+ pub fn f() {
+ if cfg!(feature="f1") {
+ println!("a1 f1");
+ }
+ }
+ "#,
+ )
+ .file(
+ "a2/Cargo.toml",
+ r#"
+ [package]
+ name = "a"
+ version = "0.2.0"
+
+ [features]
+ f2 = []
+ "#,
+ )
+ .file(
+ "a2/src/lib.rs",
+ r#"
+ pub fn f() {
+ if cfg!(feature="f2") {
+ println!("a2 f2");
+ }
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("run")
+ .with_status(101)
+ .with_stderr(
+ "\
+[ERROR] target `x` in package `foo` requires the features: `a1/f1`
+Consider enabling them by passing, e.g., `--features=\"a1/f1\"`
+",
+ )
+ .run();
+
+ p.cargo("build --features a1/f1").run();
+ p.rename_run("x", "x_with_f1").with_stdout("a1 f1").run();
+
+ p.cargo("build --features a1/f1,a2/f2").run();
+ p.rename_run("x", "x_with_f1_f2")
+ .with_stdout("a1 f1\na2 f2")
+ .run();
+}
+
+#[cargo_test]
+fn truncated_install_warning_message() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ edition = "2021"
+
+ [features]
+ feature1 = []
+ feature2 = []
+ feature3 = []
+ feature4 = []
+ feature5 = []
+
+ [[bin]]
+ name = "foo1"
+ required-features = ["feature1", "feature2", "feature3"]
+
+ [[bin]]
+ name = "foo2"
+ required-features = ["feature2"]
+
+ [[bin]]
+ name = "foo3"
+ required-features = ["feature3"]
+
+ [[bin]]
+ name = "foo4"
+ required-features = ["feature4", "feature1"]
+
+ [[bin]]
+ name = "foo5"
+ required-features = ["feature1", "feature2", "feature3", "feature4", "feature5"]
+
+ [[bin]]
+ name = "foo6"
+ required-features = ["feature1", "feature2", "feature3", "feature4", "feature5"]
+
+ [[bin]]
+ name = "foo7"
+ required-features = ["feature1", "feature2", "feature3", "feature4", "feature5"]
+
+ [[bin]]
+ name = "foo8"
+ required-features = ["feature1", "feature2", "feature3", "feature4", "feature5"]
+
+ [[bin]]
+ name = "foo9"
+ required-features = ["feature1", "feature2", "feature3", "feature4", "feature5"]
+
+ [[bin]]
+ name = "foo10"
+ required-features = ["feature1", "feature2", "feature3", "feature4", "feature5"]
+
+ [[example]]
+ name = "example1"
+ required-features = ["feature1", "feature2"]
+ "#,
+ )
+ .file("src/bin/foo1.rs", "fn main() {}")
+ .file("src/bin/foo2.rs", "fn main() {}")
+ .file("src/bin/foo3.rs", "fn main() {}")
+ .file("src/bin/foo4.rs", "fn main() {}")
+ .file("src/bin/foo5.rs", "fn main() {}")
+ .file("src/bin/foo6.rs", "fn main() {}")
+ .file("src/bin/foo7.rs", "fn main() {}")
+ .file("src/bin/foo8.rs", "fn main() {}")
+ .file("src/bin/foo9.rs", "fn main() {}")
+ .file("src/bin/foo10.rs", "fn main() {}")
+ .file("examples/example1.rs", "fn main() {}")
+ .build();
+
+ p.cargo("install --path .").with_stderr("\
+[INSTALLING] foo v0.1.0 ([..])
+[FINISHED] release [optimized] target(s) in [..]
+[WARNING] none of the package's binaries are available for install using the selected features
+ bin \"foo1\" requires the features: `feature1`, `feature2`, `feature3`
+ bin \"foo2\" requires the features: `feature2`
+ bin \"foo3\" requires the features: `feature3`
+ bin \"foo4\" requires the features: `feature4`, `feature1`
+ bin \"foo5\" requires the features: `feature1`, `feature2`, `feature3`, `feature4`, `feature5`
+ bin \"foo6\" requires the features: `feature1`, `feature2`, `feature3`, `feature4`, `feature5`
+ bin \"foo7\" requires the features: `feature1`, `feature2`, `feature3`, `feature4`, `feature5`
+4 more targets also requires features not enabled. See them in the Cargo.toml file.
+Consider enabling some of the needed features by passing, e.g., `--features=\"feature1 feature2 feature3\"`").run();
+}