2015-02-27 01:04:25 +00:00
|
|
|
use std::fs::File;
|
|
|
|
use std::io::prelude::*;
|
2014-11-05 19:13:04 +00:00
|
|
|
|
2016-05-26 00:06:25 +00:00
|
|
|
use cargotest::support::paths::CargoPathExt;
|
2018-03-14 15:17:44 +00:00
|
|
|
use cargotest::support::{execs, project};
|
2018-04-13 14:36:09 +00:00
|
|
|
use cargotest::ChannelChanger;
|
2014-09-03 18:52:47 +00:00
|
|
|
use hamcrest::assert_that;
|
2018-04-13 14:36:09 +00:00
|
|
|
use cargotest::support::registry::Package;
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid1() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
bar = ["baz"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(101).with_stderr(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[ERROR] failed to parse manifest at `[..]`
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2015-01-16 17:43:28 +00:00
|
|
|
Caused by:
|
|
|
|
Feature `bar` includes `baz` which is neither a dependency nor another feature
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid2() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
bar = ["baz"]
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "foo"
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(101).with_stderr(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[ERROR] failed to parse manifest at `[..]`
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2015-01-16 17:43:28 +00:00
|
|
|
Caused by:
|
|
|
|
Features and dependencies cannot have the same name: `bar`
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid3() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
bar = ["baz"]
|
|
|
|
|
|
|
|
[dependencies.baz]
|
|
|
|
path = "foo"
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(101).with_stderr(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[ERROR] failed to parse manifest at `[..]`
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2015-01-16 17:43:28 +00:00
|
|
|
Caused by:
|
|
|
|
Feature `bar` depends on `baz` which is not an optional dependency.
|
2014-09-03 18:52:47 +00:00
|
|
|
Consider adding `optional = true` to the dependency
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid4() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
features = ["bar"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-09-03 18:52:47 +00:00
|
|
|
.file("src/main.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("bar/src/lib.rs", "")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(101).with_stderr(
|
|
|
|
"\
|
2018-02-27 21:42:39 +00:00
|
|
|
error: failed to select a version for `bar`.
|
|
|
|
... required by package `foo v0.0.1 ([..])`
|
|
|
|
versions that meet the requirements `*` are: 0.0.1
|
|
|
|
|
2018-03-01 18:12:27 +00:00
|
|
|
the package `foo` depends on `bar`, with features: `bar` but `bar` does not have these features.
|
2018-02-27 21:42:39 +00:00
|
|
|
|
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
failed to select a version for `bar` which could resolve this conflict",
|
|
|
|
),
|
|
|
|
);
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
p.change_file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2017-02-15 14:16:41 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("test"),
|
2018-03-14 15:43:41 +00:00
|
|
|
execs()
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr("error: Package `foo v0.0.1 ([..])` does not have these features: `test`"),
|
2018-03-14 15:17:44 +00:00
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid5() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dev-dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(101).with_stderr(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[ERROR] failed to parse manifest at `[..]`
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2015-01-16 17:43:28 +00:00
|
|
|
Caused by:
|
|
|
|
Dev-dependencies are not allowed to be optional: `bar`
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid6() {
|
2014-10-16 17:09:39 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-10-16 17:09:39 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
foo = ["bar/baz"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "")
|
|
|
|
.build();
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("foo"),
|
|
|
|
execs().with_status(101).with_stderr(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[ERROR] failed to parse manifest at `[..]`
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2015-01-16 17:43:28 +00:00
|
|
|
Caused by:
|
2017-08-05 04:27:26 +00:00
|
|
|
Feature `foo` requires a feature of `bar` which is not a dependency
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid7() {
|
2014-10-16 17:09:39 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-10-16 17:09:39 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
foo = ["bar/baz"]
|
|
|
|
bar = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "")
|
|
|
|
.build();
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("foo"),
|
|
|
|
execs().with_status(101).with_stderr(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[ERROR] failed to parse manifest at `[..]`
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2015-01-16 17:43:28 +00:00
|
|
|
Caused by:
|
2017-08-05 04:27:26 +00:00
|
|
|
Feature `foo` requires a feature of `bar` which is not a dependency
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid8() {
|
2014-10-16 17:09:39 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-10-16 17:09:39 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
features = ["foo/bar"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-10-16 17:09:39 +00:00
|
|
|
.file("src/main.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2014-10-16 17:09:39 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("bar/src/lib.rs", "")
|
|
|
|
.build();
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("foo"),
|
2018-03-14 15:43:41 +00:00
|
|
|
execs()
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr("[ERROR] feature names may not contain slashes: `foo/bar`"),
|
2018-03-14 15:17:44 +00:00
|
|
|
);
|
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.
2016-07-01 20:36:05 +00:00
|
|
|
}
|
|
|
|
|
2017-08-05 03:21:38 +00:00
|
|
|
#[test]
|
|
|
|
fn invalid9() {
|
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2017-08-05 03:21:38 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-08-18 17:37:12 +00:00
|
|
|
.file("src/main.rs", "fn main() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2017-08-05 03:21:38 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("bar/src/lib.rs", "")
|
|
|
|
.build();
|
2017-08-05 03:21:38 +00:00
|
|
|
|
2017-07-22 03:12:21 +00:00
|
|
|
assert_that(p.cargo("build").arg("--features").arg("bar"),
|
2017-08-18 17:37:12 +00:00
|
|
|
execs().with_status(0).with_stderr("\
|
|
|
|
warning: 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. [..]
|
|
|
|
Compiling bar v0.0.1 ([..])
|
|
|
|
Compiling foo v0.0.1 ([..])
|
|
|
|
Finished dev [unoptimized + debuginfo] target(s) in [..] secs
|
2017-08-05 03:21:38 +00:00
|
|
|
"));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn invalid10() {
|
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2017-08-05 03:21:38 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
features = ["baz"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-08-18 17:37:12 +00:00
|
|
|
.file("src/main.rs", "fn main() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2017-08-05 03:21:38 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.baz]
|
|
|
|
path = "baz"
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-08-05 03:21:38 +00:00
|
|
|
.file("bar/src/lib.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"bar/baz/Cargo.toml",
|
|
|
|
r#"
|
2017-08-05 03:21:38 +00:00
|
|
|
[package]
|
|
|
|
name = "baz"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("bar/baz/src/lib.rs", "")
|
|
|
|
.build();
|
2017-08-05 03:21:38 +00:00
|
|
|
|
2017-07-22 03:12:21 +00:00
|
|
|
assert_that(p.cargo("build"),
|
2017-08-18 17:37:12 +00:00
|
|
|
execs().with_status(0).with_stderr("\
|
|
|
|
warning: Package `bar v0.0.1 ([..])` does not have feature `baz`. It has a required dependency with \
|
|
|
|
that name, but only optional dependencies can be used as features. [..]
|
|
|
|
Compiling baz v0.0.1 ([..])
|
|
|
|
Compiling bar v0.0.1 ([..])
|
|
|
|
Compiling foo v0.0.1 ([..])
|
|
|
|
Finished dev [unoptimized + debuginfo] target(s) in [..] secs
|
2017-08-05 03:21:38 +00:00
|
|
|
"));
|
|
|
|
}
|
|
|
|
|
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.
2016-07-01 20:36:05 +00:00
|
|
|
#[test]
|
|
|
|
fn no_transitive_dep_feature_requirement() {
|
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.
2016-07-01 20:36:05 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.derived]
|
|
|
|
path = "derived"
|
|
|
|
|
|
|
|
[features]
|
|
|
|
default = ["derived/bar/qux"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.
2016-07-01 20:36:05 +00:00
|
|
|
extern crate derived;
|
|
|
|
fn main() { derived::test(); }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"derived/Cargo.toml",
|
|
|
|
r#"
|
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.
2016-07-01 20:36:05 +00:00
|
|
|
[package]
|
|
|
|
name = "derived"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "../bar"
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"derived/src/lib.rs",
|
|
|
|
r#"
|
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.
2016-07-01 20:36:05 +00:00
|
|
|
extern crate bar;
|
|
|
|
pub use bar::test;
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.
2016-07-01 20:36:05 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
qux = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/src/lib.rs",
|
|
|
|
r#"
|
Disallow specifying features of transitive deps
Before this commit, it was possible to activate a feature in a transtive
dependency, using a Cargo.toml like the following one:
...
[features]
# this will enable feature fast in package bar, which is a
# dependency of foo
default = [ foo/bar/fast ]
This is a bug, and was never intended, and it is checked in other places
already. The behavior was possible because `build_features::add_feature`
treats the specification "foo/bar/fast" as just another feature. So when
we require the feature "foo/bar/fast", add_feature for foo will generate a
dependency on "foo" requiring that feature "bar/fast" is enabled. Then,
when resolving foo, add_feature will find that "bar/fast" is a required
feature, so it'll happily add "fast" as the required feature for the
dependency "foo".
The fix for this is to make sure that the `add_feature` function does
not treat `a/b` specifications as just another feature. Instead, it now
handles that case without recursion directly when it encounters it.
We can see how this resolves the above problem: when resolving foo,
add_feature for the required feature "bar/fast" will be called.
Because add_feature no longer treats such specifciations differently at
the top level, it will try to enable a feature with the exact name
"bar/fast", and Context::resolve_features will later find that no such
feature exists for package foo.
To give a friendlier error message, we also check in
Context::resolve_features that we never ever require a feature with a
slash in a name from a dependency.
2016-07-01 20:36:05 +00:00
|
|
|
#[cfg(feature = "qux")]
|
|
|
|
pub fn test() { print!("test"); }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.build();
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
2018-03-14 15:43:41 +00:00
|
|
|
execs()
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr("[ERROR] feature names may not contain slashes: `bar/qux`"),
|
2018-03-14 15:17:44 +00:00
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn no_feature_doesnt_build() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
#[cfg(feature = "bar")]
|
|
|
|
extern crate bar;
|
|
|
|
#[cfg(feature = "bar")]
|
|
|
|
fn main() { bar::bar(); println!("bar") }
|
|
|
|
#[cfg(not(feature = "bar"))]
|
|
|
|
fn main() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
|
|
|
assert_that(
|
|
|
|
p.process(&p.bin("foo")),
|
|
|
|
execs().with_status(0).with_stdout(""),
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("bar"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] bar v0.0.1 ({dir}/bar)
|
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
|
|
|
assert_that(
|
|
|
|
p.process(&p.bin("foo")),
|
|
|
|
execs().with_status(0).with_stdout("bar\n"),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn default_feature_pulled_in() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
default = ["bar"]
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
#[cfg(feature = "bar")]
|
|
|
|
extern crate bar;
|
|
|
|
#[cfg(feature = "bar")]
|
|
|
|
fn main() { bar::bar(); println!("bar") }
|
|
|
|
#[cfg(not(feature = "bar"))]
|
|
|
|
fn main() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] bar v0.0.1 ({dir}/bar)
|
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
|
|
|
assert_that(
|
|
|
|
p.process(&p.bin("foo")),
|
|
|
|
execs().with_status(0).with_stdout("bar\n"),
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--no-default-features"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
|
|
|
assert_that(
|
|
|
|
p.process(&p.bin("foo")),
|
|
|
|
execs().with_status(0).with_stdout(""),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn cyclic_feature() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
default = ["default"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
2018-03-14 15:43:41 +00:00
|
|
|
execs()
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr("[ERROR] Cyclic feature dependency: feature `default` depends on itself"),
|
2018-03-14 15:17:44 +00:00
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn cyclic_feature2() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
foo = ["bar"]
|
|
|
|
bar = ["foo"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "fn main() {}")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn groups_on_groups_on_groups() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
default = ["f1"]
|
|
|
|
f1 = ["f2", "bar"]
|
|
|
|
f2 = ["f3", "f4"]
|
|
|
|
f3 = ["f5", "f6", "baz"]
|
|
|
|
f4 = ["f5", "f7"]
|
|
|
|
f5 = ["f6"]
|
|
|
|
f6 = ["f7"]
|
|
|
|
f7 = ["bar"]
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
optional = true
|
|
|
|
|
|
|
|
[dependencies.baz]
|
|
|
|
path = "baz"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2014-09-03 18:52:47 +00:00
|
|
|
extern crate bar;
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2014-09-03 18:52:47 +00:00
|
|
|
extern crate baz;
|
|
|
|
fn main() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-09-03 18:52:47 +00:00
|
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"baz/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[package]
|
|
|
|
name = "baz"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("baz/src/lib.rs", "pub fn baz() {}")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn many_cli_features() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
optional = true
|
|
|
|
|
|
|
|
[dependencies.baz]
|
|
|
|
path = "baz"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2014-09-03 18:52:47 +00:00
|
|
|
extern crate bar;
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2014-09-03 18:52:47 +00:00
|
|
|
extern crate baz;
|
|
|
|
fn main() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-09-03 18:52:47 +00:00
|
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"baz/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[package]
|
|
|
|
name = "baz"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("baz/src/lib.rs", "pub fn baz() {}")
|
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("bar baz"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn union_features() {
|
2014-09-03 18:52:47 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.d1]
|
|
|
|
path = "d1"
|
|
|
|
features = ["f1"]
|
|
|
|
[dependencies.d2]
|
|
|
|
path = "d2"
|
|
|
|
features = ["f2"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2014-09-03 18:52:47 +00:00
|
|
|
extern crate d1;
|
|
|
|
extern crate d2;
|
|
|
|
fn main() {
|
|
|
|
d2::f1();
|
|
|
|
d2::f2();
|
|
|
|
}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"d1/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[package]
|
|
|
|
name = "d1"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
f1 = ["d2"]
|
|
|
|
|
|
|
|
[dependencies.d2]
|
|
|
|
path = "../d2"
|
|
|
|
features = ["f1"]
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-09-03 18:52:47 +00:00
|
|
|
.file("d1/src/lib.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"d2/Cargo.toml",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
[package]
|
|
|
|
name = "d2"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
f1 = []
|
|
|
|
f2 = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"d2/src/lib.rs",
|
|
|
|
r#"
|
2014-09-03 18:52:47 +00:00
|
|
|
#[cfg(feature = "f1")] pub fn f1() {}
|
|
|
|
#[cfg(feature = "f2")] pub fn f2() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.build();
|
2014-09-03 18:52:47 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] d2 v0.0.1 ({dir}/d2)
|
|
|
|
[COMPILING] d1 v0.0.1 ({dir}/d1)
|
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-10-06 03:21:57 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn many_features_no_rebuilds() {
|
2014-10-06 03:21:57 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-10-06 03:21:57 +00:00
|
|
|
[package]
|
|
|
|
name = "b"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.a]
|
|
|
|
path = "a"
|
|
|
|
features = ["fall"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-10-06 03:21:57 +00:00
|
|
|
.file("src/main.rs", "fn main() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"a/Cargo.toml",
|
|
|
|
r#"
|
2014-10-06 03:21:57 +00:00
|
|
|
[package]
|
|
|
|
name = "a"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
ftest = []
|
|
|
|
ftest2 = []
|
|
|
|
fall = ["ftest", "ftest2"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("a/src/lib.rs", "")
|
|
|
|
.build();
|
2014-10-06 03:21:57 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] a v0.1.0 ({dir}/a)
|
|
|
|
[COMPILING] b v0.1.0 ({dir})
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
2016-05-26 00:06:25 +00:00
|
|
|
p.root().move_into_the_past();
|
2014-10-06 03:21:57 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("-v"),
|
|
|
|
execs().with_status(0).with_stderr(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[FRESH] a v0.1.0 ([..]/a)
|
|
|
|
[FRESH] b v0.1.0 ([..])
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-10-08 05:54:16 +00:00
|
|
|
|
|
|
|
// Tests that all cmd lines work with `--features ""`
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn empty_features() {
|
2014-10-08 05:54:16 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-10-08 05:54:16 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("src/main.rs", "fn main() {}")
|
|
|
|
.build();
|
2014-10-08 05:54:16 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg(""),
|
|
|
|
execs().with_status(0),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-10-16 17:09:39 +00:00
|
|
|
|
|
|
|
// Tests that all cmd lines work with `--features ""`
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn transitive_features() {
|
2014-10-16 17:09:39 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-10-16 17:09:39 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
foo = ["bar/baz"]
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
"
|
2014-10-16 17:09:39 +00:00
|
|
|
extern crate bar;
|
|
|
|
fn main() { bar::baz(); }
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2014-10-16 17:09:39 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
baz = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/src/lib.rs",
|
|
|
|
r#"
|
2014-10-16 17:09:39 +00:00
|
|
|
#[cfg(feature = "baz")]
|
|
|
|
pub fn baz() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.build();
|
2014-10-16 17:09:39 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("foo"),
|
|
|
|
execs().with_status(0),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2014-11-05 19:13:04 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn everything_in_the_lockfile() {
|
2014-11-05 19:13:04 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2014-11-05 19:13:04 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
f1 = ["d1/f1"]
|
|
|
|
f2 = ["d2"]
|
|
|
|
|
|
|
|
[dependencies.d1]
|
|
|
|
path = "d1"
|
|
|
|
[dependencies.d2]
|
|
|
|
path = "d2"
|
|
|
|
optional = true
|
|
|
|
[dependencies.d3]
|
|
|
|
path = "d3"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-11-05 19:13:04 +00:00
|
|
|
.file("src/main.rs", "fn main() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"d1/Cargo.toml",
|
|
|
|
r#"
|
2014-11-05 19:13:04 +00:00
|
|
|
[package]
|
|
|
|
name = "d1"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
f1 = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-11-05 19:13:04 +00:00
|
|
|
.file("d1/src/lib.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"d2/Cargo.toml",
|
|
|
|
r#"
|
2014-11-05 19:13:04 +00:00
|
|
|
[package]
|
|
|
|
name = "d2"
|
|
|
|
version = "0.0.2"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2014-11-05 19:13:04 +00:00
|
|
|
.file("d2/src/lib.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"d3/Cargo.toml",
|
|
|
|
r#"
|
2014-11-05 19:13:04 +00:00
|
|
|
[package]
|
|
|
|
name = "d3"
|
|
|
|
version = "0.0.3"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
f3 = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("d3/src/lib.rs", "")
|
|
|
|
.build();
|
2014-11-05 19:13:04 +00:00
|
|
|
|
2017-07-22 03:12:21 +00:00
|
|
|
assert_that(p.cargo("fetch"), execs().with_status(0));
|
2015-02-27 01:04:25 +00:00
|
|
|
let loc = p.root().join("Cargo.lock");
|
|
|
|
let mut lockfile = String::new();
|
2016-05-26 00:06:25 +00:00
|
|
|
t!(t!(File::open(&loc)).read_to_string(&mut lockfile));
|
2018-03-14 15:17:44 +00:00
|
|
|
assert!(
|
|
|
|
lockfile.contains(r#"name = "d1""#),
|
|
|
|
"d1 not found\n{}",
|
|
|
|
lockfile
|
|
|
|
);
|
|
|
|
assert!(
|
|
|
|
lockfile.contains(r#"name = "d2""#),
|
|
|
|
"d2 not found\n{}",
|
|
|
|
lockfile
|
|
|
|
);
|
|
|
|
assert!(
|
|
|
|
lockfile.contains(r#"name = "d3""#),
|
|
|
|
"d3 not found\n{}",
|
|
|
|
lockfile
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2015-05-05 05:55:03 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn no_rebuild_when_frobbing_default_feature() {
|
2015-05-05 05:55:03 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2015-05-05 05:55:03 +00:00
|
|
|
[package]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
a = { path = "a" }
|
|
|
|
b = { path = "b" }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2015-05-05 05:55:03 +00:00
|
|
|
.file("src/lib.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"b/Cargo.toml",
|
|
|
|
r#"
|
2015-05-05 05:55:03 +00:00
|
|
|
[package]
|
|
|
|
name = "b"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
a = { path = "../a", features = ["f1"], default-features = false }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2015-05-05 05:55:03 +00:00
|
|
|
.file("b/src/lib.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"a/Cargo.toml",
|
|
|
|
r#"
|
2015-05-05 05:55:03 +00:00
|
|
|
[package]
|
|
|
|
name = "a"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
default = ["f1"]
|
|
|
|
f1 = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("a/src/lib.rs", "")
|
|
|
|
.build();
|
2015-05-05 05:55:03 +00:00
|
|
|
|
2017-07-22 03:12:21 +00:00
|
|
|
assert_that(p.cargo("build"), execs().with_status(0));
|
2015-05-05 05:55:03 +00:00
|
|
|
assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
|
|
|
|
assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2015-06-14 18:16:46 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn unions_work_with_no_default_features() {
|
2015-06-14 18:16:46 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2015-06-14 18:16:46 +00:00
|
|
|
[package]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
a = { path = "a" }
|
|
|
|
b = { path = "b" }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/lib.rs",
|
|
|
|
r#"
|
2015-06-14 18:16:46 +00:00
|
|
|
extern crate a;
|
|
|
|
pub fn foo() { a::a(); }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"b/Cargo.toml",
|
|
|
|
r#"
|
2015-06-14 18:16:46 +00:00
|
|
|
[package]
|
|
|
|
name = "b"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
a = { path = "../a", features = [], default-features = false }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2015-06-14 18:16:46 +00:00
|
|
|
.file("b/src/lib.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"a/Cargo.toml",
|
|
|
|
r#"
|
2015-06-14 18:16:46 +00:00
|
|
|
[package]
|
|
|
|
name = "a"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
default = ["f1"]
|
|
|
|
f1 = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"a/src/lib.rs",
|
|
|
|
r#"
|
2015-06-14 18:16:46 +00:00
|
|
|
#[cfg(feature = "f1")]
|
|
|
|
pub fn a() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.build();
|
2015-06-14 18:16:46 +00:00
|
|
|
|
2017-07-22 03:12:21 +00:00
|
|
|
assert_that(p.cargo("build"), execs().with_status(0));
|
2015-06-14 18:16:46 +00:00
|
|
|
assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
|
|
|
|
assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2015-07-17 17:05:57 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn optional_and_dev_dep() {
|
2015-07-17 17:05:57 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2015-07-17 17:05:57 +00:00
|
|
|
[package]
|
|
|
|
name = "test"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
foo = { path = "foo", optional = true }
|
|
|
|
[dev-dependencies]
|
|
|
|
foo = { path = "foo" }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2015-07-17 17:05:57 +00:00
|
|
|
.file("src/lib.rs", "")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"foo/Cargo.toml",
|
|
|
|
r#"
|
2015-07-17 17:05:57 +00:00
|
|
|
[package]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("foo/src/lib.rs", "")
|
|
|
|
.build();
|
2015-07-17 17:05:57 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build"),
|
|
|
|
execs().with_status(0).with_stderr(
|
|
|
|
"\
|
2016-05-11 16:55:43 +00:00
|
|
|
[COMPILING] test v0.1.0 ([..])
|
2017-01-12 01:03:36 +00:00
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2015-08-03 22:10:31 +00:00
|
|
|
|
2016-05-25 20:55:42 +00:00
|
|
|
#[test]
|
|
|
|
fn activating_feature_activates_dep() {
|
2015-08-03 22:10:31 +00:00
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2015-08-03 22:10:31 +00:00
|
|
|
[package]
|
|
|
|
name = "test"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
foo = { path = "foo", optional = true }
|
|
|
|
|
|
|
|
[features]
|
|
|
|
a = ["foo/a"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/lib.rs",
|
|
|
|
"
|
2015-08-03 22:10:31 +00:00
|
|
|
extern crate foo;
|
|
|
|
pub fn bar() {
|
|
|
|
foo::bar();
|
|
|
|
}
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"foo/Cargo.toml",
|
|
|
|
r#"
|
2015-08-03 22:10:31 +00:00
|
|
|
[package]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.1.0"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
a = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"foo/src/lib.rs",
|
|
|
|
r#"
|
2015-08-03 22:10:31 +00:00
|
|
|
#[cfg(feature = "a")]
|
|
|
|
pub fn bar() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.build();
|
2015-08-03 22:10:31 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("a").arg("-v"),
|
|
|
|
execs().with_status(0),
|
|
|
|
);
|
2016-05-25 20:55:42 +00:00
|
|
|
}
|
2016-07-14 13:06:29 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dep_feature_in_cmd_line() {
|
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2016-07-14 13:06:29 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.derived]
|
|
|
|
path = "derived"
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2016-07-14 13:06:29 +00:00
|
|
|
extern crate derived;
|
|
|
|
fn main() { derived::test(); }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"derived/Cargo.toml",
|
|
|
|
r#"
|
2016-07-14 13:06:29 +00:00
|
|
|
[package]
|
|
|
|
name = "derived"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "../bar"
|
|
|
|
|
|
|
|
[features]
|
|
|
|
default = []
|
|
|
|
derived-feat = ["bar/some-feat"]
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"derived/src/lib.rs",
|
|
|
|
r#"
|
2016-07-14 13:06:29 +00:00
|
|
|
extern crate bar;
|
|
|
|
pub use bar::test;
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2016-07-14 13:06:29 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
some-feat = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/src/lib.rs",
|
|
|
|
r#"
|
2016-07-14 13:06:29 +00:00
|
|
|
#[cfg(feature = "some-feat")]
|
|
|
|
pub fn test() { print!("test"); }
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.build();
|
2016-07-14 13:06:29 +00:00
|
|
|
|
|
|
|
// The foo project requires that feature "some-feat" in "bar" is enabled.
|
|
|
|
// Building without any features enabled should fail:
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(p.cargo("build"), execs().with_status(101));
|
2016-07-14 13:06:29 +00:00
|
|
|
|
|
|
|
// We should be able to enable the feature "derived-feat", which enables "some-feat",
|
|
|
|
// on the command line. The feature is enabled, thus building should be successful:
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build")
|
|
|
|
.arg("--features")
|
|
|
|
.arg("derived/derived-feat"),
|
|
|
|
execs().with_status(0),
|
|
|
|
);
|
2016-07-14 13:06:29 +00:00
|
|
|
|
|
|
|
// Trying to enable features of transitive dependencies is an error
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("bar/some-feat"),
|
2018-03-14 15:43:41 +00:00
|
|
|
execs()
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr("error: Package `foo v0.0.1 ([..])` does not have these features: `bar`"),
|
2018-03-14 15:17:44 +00:00
|
|
|
);
|
2016-07-14 13:06:29 +00:00
|
|
|
|
|
|
|
// Hierarchical feature specification should still be disallowed
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build")
|
|
|
|
.arg("--features")
|
|
|
|
.arg("derived/bar/some-feat"),
|
2018-03-14 15:43:41 +00:00
|
|
|
execs()
|
|
|
|
.with_status(101)
|
|
|
|
.with_stderr("[ERROR] feature names may not contain slashes: `bar/some-feat`"),
|
2018-03-14 15:17:44 +00:00
|
|
|
);
|
2016-09-10 21:25:23 +00:00
|
|
|
}
|
2016-08-31 17:03:26 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn all_features_flag_enables_all_features() {
|
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2016-08-31 17:03:26 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[features]
|
|
|
|
foo = []
|
|
|
|
bar = []
|
|
|
|
|
|
|
|
[dependencies.baz]
|
|
|
|
path = "baz"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2016-08-31 17:03:26 +00:00
|
|
|
#[cfg(feature = "foo")]
|
|
|
|
pub fn foo() {}
|
|
|
|
|
|
|
|
#[cfg(feature = "bar")]
|
|
|
|
pub fn bar() {
|
|
|
|
extern crate baz;
|
|
|
|
baz::baz();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
foo();
|
|
|
|
bar();
|
|
|
|
}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"baz/Cargo.toml",
|
|
|
|
r#"
|
2016-08-31 17:03:26 +00:00
|
|
|
[package]
|
|
|
|
name = "baz"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("baz/src/lib.rs", "pub fn baz() {}")
|
|
|
|
.build();
|
2016-08-31 17:03:26 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--all-features"),
|
|
|
|
execs().with_status(0),
|
|
|
|
);
|
2016-08-31 17:03:26 +00:00
|
|
|
}
|
2017-05-22 13:14:03 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn many_cli_features_comma_delimited() {
|
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2017-05-22 13:14:03 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
optional = true
|
|
|
|
|
|
|
|
[dependencies.baz]
|
|
|
|
path = "baz"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2017-05-22 13:14:03 +00:00
|
|
|
extern crate bar;
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2017-05-22 13:14:03 +00:00
|
|
|
extern crate baz;
|
|
|
|
fn main() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2017-05-22 13:14:03 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-05-22 13:14:03 +00:00
|
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"baz/Cargo.toml",
|
|
|
|
r#"
|
2017-05-22 13:14:03 +00:00
|
|
|
[package]
|
|
|
|
name = "baz"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("baz/src/lib.rs", "pub fn baz() {}")
|
|
|
|
.build();
|
2017-05-22 13:14:03 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("bar,baz"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2017-05-22 13:14:03 +00:00
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
2017-05-22 13:14:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn many_cli_features_comma_and_space_delimited() {
|
|
|
|
let p = project("foo")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
2017-05-22 13:14:03 +00:00
|
|
|
[project]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[dependencies.bar]
|
|
|
|
path = "bar"
|
|
|
|
optional = true
|
|
|
|
|
|
|
|
[dependencies.baz]
|
|
|
|
path = "baz"
|
|
|
|
optional = true
|
|
|
|
|
|
|
|
[dependencies.bam]
|
|
|
|
path = "bam"
|
|
|
|
optional = true
|
|
|
|
|
|
|
|
[dependencies.bap]
|
|
|
|
path = "bap"
|
|
|
|
optional = true
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"src/main.rs",
|
|
|
|
r#"
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2017-05-22 13:14:03 +00:00
|
|
|
extern crate bar;
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2017-05-22 13:14:03 +00:00
|
|
|
extern crate baz;
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2017-05-22 13:14:03 +00:00
|
|
|
extern crate bam;
|
2017-08-27 07:31:16 +00:00
|
|
|
#[allow(unused_extern_crates)]
|
2017-05-22 13:14:03 +00:00
|
|
|
extern crate bap;
|
|
|
|
fn main() {}
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file(
|
|
|
|
"bar/Cargo.toml",
|
|
|
|
r#"
|
2017-05-22 13:14:03 +00:00
|
|
|
[package]
|
|
|
|
name = "bar"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-05-22 13:14:03 +00:00
|
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"baz/Cargo.toml",
|
|
|
|
r#"
|
2017-05-22 13:14:03 +00:00
|
|
|
[package]
|
|
|
|
name = "baz"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-05-22 13:14:03 +00:00
|
|
|
.file("baz/src/lib.rs", "pub fn baz() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"bam/Cargo.toml",
|
|
|
|
r#"
|
2017-05-22 13:14:03 +00:00
|
|
|
[package]
|
|
|
|
name = "bam"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-05-22 13:14:03 +00:00
|
|
|
.file("bam/src/lib.rs", "pub fn bam() {}")
|
2018-03-14 15:17:44 +00:00
|
|
|
.file(
|
|
|
|
"bap/Cargo.toml",
|
|
|
|
r#"
|
2017-05-22 13:14:03 +00:00
|
|
|
[package]
|
|
|
|
name = "bap"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
2018-03-14 15:17:44 +00:00
|
|
|
"#,
|
|
|
|
)
|
2017-07-22 03:12:21 +00:00
|
|
|
.file("bap/src/lib.rs", "pub fn bap() {}")
|
|
|
|
.build();
|
2017-05-22 13:14:03 +00:00
|
|
|
|
2018-03-14 15:17:44 +00:00
|
|
|
assert_that(
|
|
|
|
p.cargo("build").arg("--features").arg("bar,baz bam bap"),
|
|
|
|
execs().with_status(0).with_stderr(format!(
|
|
|
|
"\
|
2017-05-22 13:14:03 +00:00
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] ba[..] v0.0.1 ({dir}/ba[..])
|
|
|
|
[COMPILING] foo v0.0.1 ({dir})
|
|
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
2018-03-14 15:17:44 +00:00
|
|
|
",
|
|
|
|
dir = p.url()
|
|
|
|
)),
|
|
|
|
);
|
2017-05-22 13:14:03 +00:00
|
|
|
}
|
2018-04-13 14:36:09 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn combining_features_and_package() {
|
|
|
|
Package::new("dep", "1.0.0").publish();
|
|
|
|
|
|
|
|
let p = project("ws")
|
|
|
|
.file(
|
|
|
|
"Cargo.toml",
|
|
|
|
r#"
|
|
|
|
[project]
|
|
|
|
name = "ws"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
|
|
|
|
[workspace]
|
|
|
|
members = ["foo"]
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
dep = "1"
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.file("src/lib.rs", "")
|
|
|
|
.file(
|
|
|
|
"foo/Cargo.toml",
|
|
|
|
r#"
|
|
|
|
[package]
|
|
|
|
name = "foo"
|
|
|
|
version = "0.0.1"
|
|
|
|
authors = []
|
|
|
|
[features]
|
|
|
|
main = []
|
|
|
|
"#,
|
|
|
|
)
|
2018-04-13 17:59:55 +00:00
|
|
|
.file(
|
|
|
|
"foo/src/main.rs",
|
|
|
|
r#"
|
2018-04-13 14:36:09 +00:00
|
|
|
#[cfg(feature = "main")]
|
|
|
|
fn main() {}
|
2018-04-13 17:59:55 +00:00
|
|
|
"#,
|
|
|
|
)
|
2018-04-13 14:36:09 +00:00
|
|
|
.build();
|
|
|
|
|
|
|
|
assert_that(
|
|
|
|
p.cargo("build -Z package-features --all --features main")
|
|
|
|
.masquerade_as_nightly_cargo(),
|
2018-04-13 17:59:55 +00:00
|
|
|
execs().with_status(101).with_stderr_contains(
|
|
|
|
"\
|
|
|
|
[ERROR] cannot specify features for more than one package",
|
2018-04-13 14:36:09 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_that(
|
|
|
|
p.cargo("build -Z package-features --package dep --features main")
|
|
|
|
.masquerade_as_nightly_cargo(),
|
2018-04-13 17:59:55 +00:00
|
|
|
execs().with_status(101).with_stderr_contains(
|
|
|
|
"\
|
|
|
|
[ERROR] cannot specify features for packages outside of workspace",
|
2018-04-13 14:36:09 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
assert_that(
|
|
|
|
p.cargo("build -Z package-features --package dep --all-features")
|
|
|
|
.masquerade_as_nightly_cargo(),
|
2018-04-13 17:59:55 +00:00
|
|
|
execs().with_status(101).with_stderr_contains(
|
|
|
|
"\
|
|
|
|
[ERROR] cannot specify features for packages outside of workspace",
|
2018-04-13 14:36:09 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
assert_that(
|
|
|
|
p.cargo("build -Z package-features --package dep --no-default-features")
|
|
|
|
.masquerade_as_nightly_cargo(),
|
2018-04-13 17:59:55 +00:00
|
|
|
execs().with_status(101).with_stderr_contains(
|
|
|
|
"\
|
|
|
|
[ERROR] cannot specify features for packages outside of workspace",
|
2018-04-13 14:36:09 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_that(
|
|
|
|
p.cargo("build -Z package-features --all --all-features")
|
|
|
|
.masquerade_as_nightly_cargo(),
|
|
|
|
execs().with_status(0),
|
|
|
|
);
|
|
|
|
assert_that(
|
|
|
|
p.cargo("run -Z package-features --package foo --features main")
|
|
|
|
.masquerade_as_nightly_cargo(),
|
|
|
|
execs().with_status(0),
|
|
|
|
);
|
|
|
|
}
|