cargo/tests/testsuite/required_features.rs
Alex Crichton 6514c289d2 Improve git error messages a bit
This commit is targeted at further improving the error messages
generated from git errors. For authentication errors the actual URL
fetched is now printed out as well if it's different from the original
URL. This should help handle `insteadOf` logic where SSH urls are used
instead of HTTPS urls and users can know to track that down.

Otherwise the logic about recommending `net.git-fetch-with-cli` was
tweaked a bit and moved to the same location as the rest of our error
reporting.

Note that a change piggy-backed here as well is that `Caused by:` errors
are now automatically all tabbed over a bit instead of only having the
first line tabbed over. This required a good number of tests to be
updated, but it's just an updated in renderings.
2020-06-25 08:47:15 -07:00

1276 lines
30 KiB
Rust

//! 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#"
[project]
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#"
[project]
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#"
[project]
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#"
[project]
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#"
[project]
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#"
[project]
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#"
[project]
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#"
[project]
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#"
[project]
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]
fn bench_default_features() {
if !is_nightly() {
return;
}
let p = project()
.file(
"Cargo.toml",
r#"
[project]
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]
fn bench_arg_features() {
if !is_nightly() {
return;
}
let p = project()
.file(
"Cargo.toml",
r#"
[project]
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]
fn bench_multiple_required_features() {
if !is_nightly() {
return;
}
let p = project()
.file(
"Cargo.toml",
r#"
[project]
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#"
[project]
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_status(101)
.with_stderr(
"\
[INSTALLING] foo v0.0.1 ([..])
[FINISHED] release [optimized] target(s) in [..]
[ERROR] no binaries are available for install using the selected features
",
)
.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#"
[project]
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#"
[project]
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("install --path .").run();
assert_has_not_installed_exe(cargo_home(), "foo_1");
assert_has_installed_exe(cargo_home(), "foo_2");
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");
p.cargo("uninstall foo").run();
p.cargo("install --path . --no-default-features")
.with_status(101)
.with_stderr(
"\
[INSTALLING] foo v0.0.1 ([..])
[FINISHED] release [optimized] target(s) in [..]
[ERROR] no binaries are available for install using the selected features
",
)
.run();
assert_has_not_installed_exe(cargo_home(), "foo_1");
assert_has_not_installed_exe(cargo_home(), "foo_2");
}
#[cargo_test]
fn dep_feature_in_toml() {
let p = project()
.file(
"Cargo.toml",
r#"
[project]
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#"
[project]
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#"
[project]
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#"
[project]
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_status(101)
.with_stderr(
"\
[INSTALLING] foo v0.0.1 ([..])
[FINISHED] release [optimized] target(s) in [..]
[ERROR] no binaries are available for install using the selected features
",
)
.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#"
[project]
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#"
[project]
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#"
[project]
name = "foo"
version = "0.0.1"
authors = []
[features]
default = ["a"]
a = []
b = []
[[bin]]
name = "foo1"
path = "src/foo1.rs"
required-features = ["a"]
[[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/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",
)
.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();
}