| //! Tests for the `cargo tree` command with -e features option. |
| |
| use cargo_test_support::project; |
| use cargo_test_support::registry::{Dependency, Package}; |
| |
| #[cargo_test] |
| fn dep_feature_various() { |
| // Checks different ways of setting features via dependencies. |
| Package::new("optdep", "1.0.0") |
| .feature("default", &["cat"]) |
| .feature("cat", &[]) |
| .publish(); |
| Package::new("defaultdep", "1.0.0") |
| .feature("default", &["f1"]) |
| .feature("f1", &["optdep"]) |
| .add_dep(Dependency::new("optdep", "1.0").optional(true)) |
| .publish(); |
| Package::new("nodefaultdep", "1.0.0") |
| .feature("default", &["f1"]) |
| .feature("f1", &[]) |
| .publish(); |
| Package::new("nameddep", "1.0.0") |
| .add_dep(Dependency::new("serde", "1.0").optional(true)) |
| .feature("default", &["serde-stuff"]) |
| .feature("serde-stuff", &["serde/derive"]) |
| .feature("vehicle", &["car"]) |
| .feature("car", &[]) |
| .publish(); |
| Package::new("serde_derive", "1.0.0").publish(); |
| Package::new("serde", "1.0.0") |
| .feature("derive", &["serde_derive"]) |
| .add_dep(Dependency::new("serde_derive", "1.0").optional(true)) |
| .publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| defaultdep = "1.0" |
| nodefaultdep = {version="1.0", default-features = false} |
| nameddep = {version="1.0", features = ["vehicle", "serde"]} |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("tree -e features") |
| .with_stdout( |
| "\ |
| foo v0.1.0 ([..]/foo) |
| ├── nodefaultdep v1.0.0 |
| ├── defaultdep feature \"default\" |
| │ ├── defaultdep v1.0.0 |
| │ │ └── optdep feature \"default\" |
| │ │ ├── optdep v1.0.0 |
| │ │ └── optdep feature \"cat\" |
| │ │ └── optdep v1.0.0 |
| │ └── defaultdep feature \"f1\" |
| │ ├── defaultdep v1.0.0 (*) |
| │ └── defaultdep feature \"optdep\" |
| │ └── defaultdep v1.0.0 (*) |
| ├── nameddep feature \"default\" |
| │ ├── nameddep v1.0.0 |
| │ │ └── serde feature \"default\" |
| │ │ └── serde v1.0.0 |
| │ │ └── serde_derive feature \"default\" |
| │ │ └── serde_derive v1.0.0 |
| │ └── nameddep feature \"serde-stuff\" |
| │ ├── nameddep v1.0.0 (*) |
| │ ├── nameddep feature \"serde\" |
| │ │ └── nameddep v1.0.0 (*) |
| │ └── serde feature \"derive\" |
| │ ├── serde v1.0.0 (*) |
| │ └── serde feature \"serde_derive\" |
| │ └── serde v1.0.0 (*) |
| ├── nameddep feature \"serde\" (*) |
| └── nameddep feature \"vehicle\" |
| ├── nameddep v1.0.0 (*) |
| └── nameddep feature \"car\" |
| └── nameddep v1.0.0 (*) |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn graph_features_ws_interdependent() { |
| // A workspace with interdependent crates. |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [workspace] |
| members = ["a", "b"] |
| "#, |
| ) |
| .file( |
| "a/Cargo.toml", |
| r#" |
| [package] |
| name = "a" |
| version = "0.1.0" |
| |
| [dependencies] |
| b = {path="../b", features=["feat2"]} |
| |
| [features] |
| default = ["a1"] |
| a1 = [] |
| a2 = [] |
| "#, |
| ) |
| .file("a/src/lib.rs", "") |
| .file( |
| "b/Cargo.toml", |
| r#" |
| [package] |
| name = "b" |
| version = "0.1.0" |
| |
| [features] |
| default = ["feat1"] |
| feat1 = [] |
| feat2 = [] |
| "#, |
| ) |
| .file("b/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("tree -e features") |
| .with_stdout( |
| "\ |
| a v0.1.0 ([..]/foo/a) |
| ├── b feature \"default\" (command-line) |
| │ ├── b v0.1.0 ([..]/foo/b) |
| │ └── b feature \"feat1\" |
| │ └── b v0.1.0 ([..]/foo/b) |
| └── b feature \"feat2\" |
| └── b v0.1.0 ([..]/foo/b) |
| |
| b v0.1.0 ([..]/foo/b) |
| ", |
| ) |
| .run(); |
| |
| p.cargo("tree -e features -i a -i b") |
| .with_stdout( |
| "\ |
| a v0.1.0 ([..]/foo/a) |
| ├── a feature \"a1\" |
| │ └── a feature \"default\" (command-line) |
| └── a feature \"default\" (command-line) |
| |
| b v0.1.0 ([..]/foo/b) |
| ├── b feature \"default\" (command-line) |
| │ └── a v0.1.0 ([..]/foo/a) (*) |
| ├── b feature \"feat1\" |
| │ └── b feature \"default\" (command-line) (*) |
| └── b feature \"feat2\" |
| └── a v0.1.0 ([..]/foo/a) (*) |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn slash_feature_name() { |
| // dep_name/feat_name syntax |
| Package::new("opt", "1.0.0").feature("feat1", &[]).publish(); |
| Package::new("notopt", "1.0.0") |
| .feature("cat", &[]) |
| .feature("animal", &["cat"]) |
| .publish(); |
| Package::new("opt2", "1.0.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| opt = {version = "1.0", optional=true} |
| opt2 = {version = "1.0", optional=true} |
| notopt = "1.0" |
| |
| [features] |
| f1 = ["opt/feat1", "notopt/animal"] |
| f2 = ["f1"] |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("tree -e features --features f1") |
| .with_stdout( |
| "\ |
| foo v0.1.0 ([..]/foo) |
| ├── notopt feature \"default\" |
| │ └── notopt v1.0.0 |
| └── opt feature \"default\" |
| └── opt v1.0.0 |
| ", |
| ) |
| .run(); |
| |
| p.cargo("tree -e features --features f1 -i foo") |
| .with_stdout( |
| "\ |
| foo v0.1.0 ([..]/foo) |
| ├── foo feature \"default\" (command-line) |
| ├── foo feature \"f1\" (command-line) |
| └── foo feature \"opt\" |
| └── foo feature \"f1\" (command-line) |
| ", |
| ) |
| .run(); |
| |
| p.cargo("tree -e features --features f1 -i notopt") |
| .with_stdout( |
| "\ |
| notopt v1.0.0 |
| ├── notopt feature \"animal\" |
| │ └── foo feature \"f1\" (command-line) |
| ├── notopt feature \"cat\" |
| │ └── notopt feature \"animal\" (*) |
| └── notopt feature \"default\" |
| └── foo v0.1.0 ([..]/foo) |
| ├── foo feature \"default\" (command-line) |
| ├── foo feature \"f1\" (command-line) |
| └── foo feature \"opt\" |
| └── foo feature \"f1\" (command-line) |
| ", |
| ) |
| .run(); |
| |
| p.cargo("tree -e features --features notopt/animal -i notopt") |
| .with_stdout( |
| "\ |
| notopt v1.0.0 |
| ├── notopt feature \"animal\" (command-line) |
| ├── notopt feature \"cat\" |
| │ └── notopt feature \"animal\" (command-line) |
| └── notopt feature \"default\" |
| └── foo v0.1.0 ([..]/foo) |
| └── foo feature \"default\" (command-line) |
| ", |
| ) |
| .run(); |
| |
| p.cargo("tree -e features --all-features") |
| .with_stdout( |
| "\ |
| foo v0.1.0 ([..]/foo) |
| ├── notopt feature \"default\" |
| │ └── notopt v1.0.0 |
| ├── opt feature \"default\" |
| │ └── opt v1.0.0 |
| └── opt2 feature \"default\" |
| └── opt2 v1.0.0 |
| ", |
| ) |
| .run(); |
| |
| p.cargo("tree -e features --all-features -i opt2") |
| .with_stdout( |
| "\ |
| opt2 v1.0.0 |
| └── opt2 feature \"default\" |
| └── foo v0.1.0 ([..]/foo) |
| ├── foo feature \"default\" (command-line) |
| ├── foo feature \"f1\" (command-line) |
| │ └── foo feature \"f2\" (command-line) |
| ├── foo feature \"f2\" (command-line) |
| ├── foo feature \"opt\" (command-line) |
| │ └── foo feature \"f1\" (command-line) (*) |
| └── foo feature \"opt2\" (command-line) |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn features_enables_inactive_target() { |
| // Features that enable things on targets that are not enabled. |
| Package::new("optdep", "1.0.0") |
| .feature("feat1", &[]) |
| .publish(); |
| Package::new("dep1", "1.0.0") |
| .feature("somefeat", &[]) |
| .publish(); |
| Package::new("dep2", "1.0.0") |
| .add_dep( |
| Dependency::new("optdep", "1.0.0") |
| .optional(true) |
| .target("cfg(whatever)"), |
| ) |
| .publish(); |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [target.'cfg(whatever)'.dependencies] |
| optdep = {version="1.0", optional=true} |
| dep1 = "1.0" |
| |
| [dependencies] |
| dep2 = "1.0" |
| |
| [features] |
| f1 = ["optdep"] |
| f2 = ["optdep/feat1"] |
| f3 = ["dep1/somefeat"] |
| f4 = ["dep2/optdep"] |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| p.cargo("tree -e features") |
| .with_stdout( |
| "\ |
| foo v0.1.0 ([..]/foo) |
| └── dep2 feature \"default\" |
| └── dep2 v1.0.0 |
| ", |
| ) |
| .run(); |
| p.cargo("tree -e features --all-features") |
| .with_stdout( |
| "\ |
| foo v0.1.0 ([..]/foo) |
| └── dep2 feature \"default\" |
| └── dep2 v1.0.0 |
| ", |
| ) |
| .run(); |
| p.cargo("tree -e features --all-features --target=all") |
| .with_stdout( |
| "\ |
| foo v0.1.0 ([..]/foo) |
| ├── dep1 feature \"default\" |
| │ └── dep1 v1.0.0 |
| ├── dep2 feature \"default\" |
| │ └── dep2 v1.0.0 |
| │ └── optdep feature \"default\" |
| │ └── optdep v1.0.0 |
| └── optdep feature \"default\" (*) |
| ", |
| ) |
| .run(); |
| } |