]>
Commit | Line | Data |
---|---|---|
83571aee EH |
1 | //! Tests for `[features]` table. |
2 | ||
9115b2c3 | 3 | use cargo_test_support::paths::CargoPathExt; |
ab73b2c3 | 4 | use cargo_test_support::registry::{Dependency, Package}; |
4ae79d2f | 5 | use cargo_test_support::{basic_manifest, project}; |
2b46d039 | 6 | |
0e0d9688 | 7 | #[cargo_test] |
6950bbb0 | 8 | fn invalid1() { |
7fe2fbc8 | 9 | let p = project() |
1e682848 AC |
10 | .file( |
11 | "Cargo.toml", | |
12 | r#" | |
6f8c7d5a EH |
13 | [project] |
14 | name = "foo" | |
15 | version = "0.0.1" | |
16 | authors = [] | |
2b46d039 | 17 | |
6f8c7d5a EH |
18 | [features] |
19 | bar = ["baz"] | |
20 | "#, | |
fecb7246 AC |
21 | ) |
22 | .file("src/main.rs", "") | |
d43ee1dd | 23 | .build(); |
2b46d039 | 24 | |
85984a87 DW |
25 | p.cargo("build") |
26 | .with_status(101) | |
27 | .with_stderr( | |
1e682848 | 28 | "\ |
29cdad4f | 29 | [ERROR] failed to parse manifest at `[..]` |
2b46d039 | 30 | |
d14abb6e | 31 | Caused by: |
bcfdf9fb | 32 | feature `bar` includes `baz` which is neither a dependency nor another feature |
1e682848 | 33 | ", |
fecb7246 AC |
34 | ) |
35 | .run(); | |
6950bbb0 | 36 | } |
2b46d039 | 37 | |
0e0d9688 | 38 | #[cargo_test] |
43a063c8 EH |
39 | fn same_name() { |
40 | // Feature with the same name as a dependency. | |
7fe2fbc8 | 41 | let p = project() |
1e682848 AC |
42 | .file( |
43 | "Cargo.toml", | |
44 | r#" | |
6f8c7d5a EH |
45 | [project] |
46 | name = "foo" | |
47 | version = "0.0.1" | |
48 | authors = [] | |
2b46d039 | 49 | |
6f8c7d5a EH |
50 | [features] |
51 | bar = ["baz"] | |
bcfdf9fb | 52 | baz = [] |
2b46d039 | 53 | |
6f8c7d5a | 54 | [dependencies.bar] |
bcfdf9fb | 55 | path = "bar" |
6f8c7d5a | 56 | "#, |
fecb7246 AC |
57 | ) |
58 | .file("src/main.rs", "") | |
bcfdf9fb EH |
59 | .file("bar/Cargo.toml", &basic_manifest("bar", "1.0.0")) |
60 | .file("bar/src/lib.rs", "") | |
d43ee1dd | 61 | .build(); |
2b46d039 | 62 | |
43a063c8 EH |
63 | p.cargo("tree -f") |
64 | .arg("{p} [{f}]") | |
65 | .with_stderr("") | |
66 | .with_stdout( | |
1e682848 | 67 | "\ |
43a063c8 EH |
68 | foo v0.0.1 ([..]) [] |
69 | └── bar v1.0.0 ([..]) [] | |
70 | ", | |
71 | ) | |
72 | .run(); | |
2b46d039 | 73 | |
43a063c8 EH |
74 | p.cargo("tree --features bar -f") |
75 | .arg("{p} [{f}]") | |
76 | .with_stderr("") | |
77 | .with_stdout( | |
78 | "\ | |
79 | foo v0.0.1 ([..]) [bar,baz] | |
80 | └── bar v1.0.0 ([..]) [] | |
1e682848 | 81 | ", |
fecb7246 AC |
82 | ) |
83 | .run(); | |
6950bbb0 | 84 | } |
2b46d039 | 85 | |
0e0d9688 | 86 | #[cargo_test] |
6950bbb0 | 87 | fn invalid3() { |
7fe2fbc8 | 88 | let p = project() |
1e682848 AC |
89 | .file( |
90 | "Cargo.toml", | |
91 | r#" | |
6f8c7d5a EH |
92 | [project] |
93 | name = "foo" | |
94 | version = "0.0.1" | |
95 | authors = [] | |
2b46d039 | 96 | |
6f8c7d5a EH |
97 | [features] |
98 | bar = ["baz"] | |
2b46d039 | 99 | |
6f8c7d5a EH |
100 | [dependencies.baz] |
101 | path = "foo" | |
102 | "#, | |
fecb7246 AC |
103 | ) |
104 | .file("src/main.rs", "") | |
d43ee1dd | 105 | .build(); |
2b46d039 | 106 | |
85984a87 DW |
107 | p.cargo("build") |
108 | .with_status(101) | |
109 | .with_stderr( | |
1e682848 | 110 | "\ |
29cdad4f | 111 | [ERROR] failed to parse manifest at `[..]` |
2b46d039 | 112 | |
d14abb6e | 113 | Caused by: |
bcfdf9fb EH |
114 | feature `bar` includes `baz`, but `baz` is not an optional dependency |
115 | A non-optional dependency of the same name is defined; consider adding `optional = true` to its definition. | |
1e682848 | 116 | ", |
fecb7246 AC |
117 | ) |
118 | .run(); | |
6950bbb0 | 119 | } |
2b46d039 | 120 | |
0e0d9688 | 121 | #[cargo_test] |
6950bbb0 | 122 | fn invalid4() { |
7fe2fbc8 | 123 | let p = project() |
1e682848 AC |
124 | .file( |
125 | "Cargo.toml", | |
126 | r#" | |
6f8c7d5a EH |
127 | [project] |
128 | name = "foo" | |
129 | version = "0.0.1" | |
130 | authors = [] | |
2b46d039 | 131 | |
6f8c7d5a EH |
132 | [dependencies.bar] |
133 | path = "bar" | |
134 | features = ["bar"] | |
135 | "#, | |
fecb7246 AC |
136 | ) |
137 | .file("src/main.rs", "") | |
ab19c483 | 138 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) |
d43ee1dd NK |
139 | .file("bar/src/lib.rs", "") |
140 | .build(); | |
2b46d039 | 141 | |
85984a87 DW |
142 | p.cargo("build") |
143 | .with_status(101) | |
144 | .with_stderr( | |
1e682848 | 145 | "\ |
5d4402ce E |
146 | error: failed to select a version for `bar`. |
147 | ... required by package `foo v0.0.1 ([..])` | |
148 | versions that meet the requirements `*` are: 0.0.1 | |
149 | ||
2cbd1ddc | 150 | the package `foo` depends on `bar`, with features: `bar` but `bar` does not have these features. |
5d4402ce | 151 | |
5d4402ce | 152 | |
1e682848 | 153 | failed to select a version for `bar` which could resolve this conflict", |
fecb7246 AC |
154 | ) |
155 | .run(); | |
2b46d039 | 156 | |
ab19c483 | 157 | p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1")); |
1e682848 | 158 | |
85984a87 DW |
159 | p.cargo("build --features test") |
160 | .with_status(101) | |
bcfdf9fb | 161 | .with_stderr("error: Package `foo v0.0.1 ([..])` does not have the feature `test`") |
85984a87 | 162 | .run(); |
6950bbb0 | 163 | } |
2b46d039 | 164 | |
0e0d9688 | 165 | #[cargo_test] |
6950bbb0 | 166 | fn invalid5() { |
7fe2fbc8 | 167 | let p = project() |
1e682848 AC |
168 | .file( |
169 | "Cargo.toml", | |
170 | r#" | |
6f8c7d5a EH |
171 | [project] |
172 | name = "foo" | |
173 | version = "0.0.1" | |
174 | authors = [] | |
2b46d039 | 175 | |
6f8c7d5a EH |
176 | [dev-dependencies.bar] |
177 | path = "bar" | |
178 | optional = true | |
179 | "#, | |
fecb7246 AC |
180 | ) |
181 | .file("src/main.rs", "") | |
d43ee1dd | 182 | .build(); |
2b46d039 | 183 | |
85984a87 DW |
184 | p.cargo("build") |
185 | .with_status(101) | |
186 | .with_stderr( | |
1e682848 | 187 | "\ |
29cdad4f | 188 | [ERROR] failed to parse manifest at `[..]` |
2b46d039 | 189 | |
d14abb6e | 190 | Caused by: |
bcfdf9fb | 191 | dev-dependencies are not allowed to be optional: `bar` |
1e682848 | 192 | ", |
fecb7246 AC |
193 | ) |
194 | .run(); | |
6950bbb0 | 195 | } |
2b46d039 | 196 | |
0e0d9688 | 197 | #[cargo_test] |
6950bbb0 | 198 | fn invalid6() { |
7fe2fbc8 | 199 | let p = project() |
1e682848 AC |
200 | .file( |
201 | "Cargo.toml", | |
202 | r#" | |
6f8c7d5a EH |
203 | [project] |
204 | name = "foo" | |
205 | version = "0.0.1" | |
206 | authors = [] | |
f5f34e85 | 207 | |
6f8c7d5a EH |
208 | [features] |
209 | foo = ["bar/baz"] | |
210 | "#, | |
fecb7246 AC |
211 | ) |
212 | .file("src/main.rs", "") | |
d43ee1dd | 213 | .build(); |
f5f34e85 | 214 | |
85984a87 DW |
215 | p.cargo("build --features foo") |
216 | .with_status(101) | |
217 | .with_stderr( | |
1e682848 | 218 | "\ |
29cdad4f | 219 | [ERROR] failed to parse manifest at `[..]` |
f5f34e85 | 220 | |
d14abb6e | 221 | Caused by: |
bcfdf9fb | 222 | feature `foo` includes `bar/baz`, but `bar` is not a dependency |
1e682848 | 223 | ", |
fecb7246 AC |
224 | ) |
225 | .run(); | |
6950bbb0 | 226 | } |
f5f34e85 | 227 | |
0e0d9688 | 228 | #[cargo_test] |
6950bbb0 | 229 | fn invalid7() { |
7fe2fbc8 | 230 | let p = project() |
1e682848 AC |
231 | .file( |
232 | "Cargo.toml", | |
233 | r#" | |
6f8c7d5a EH |
234 | [project] |
235 | name = "foo" | |
236 | version = "0.0.1" | |
237 | authors = [] | |
f5f34e85 | 238 | |
6f8c7d5a EH |
239 | [features] |
240 | foo = ["bar/baz"] | |
241 | bar = [] | |
242 | "#, | |
fecb7246 AC |
243 | ) |
244 | .file("src/main.rs", "") | |
d43ee1dd | 245 | .build(); |
f5f34e85 | 246 | |
85984a87 DW |
247 | p.cargo("build --features foo") |
248 | .with_status(101) | |
249 | .with_stderr( | |
1e682848 | 250 | "\ |
29cdad4f | 251 | [ERROR] failed to parse manifest at `[..]` |
f5f34e85 | 252 | |
d14abb6e | 253 | Caused by: |
bcfdf9fb | 254 | feature `foo` includes `bar/baz`, but `bar` is not a dependency |
1e682848 | 255 | ", |
fecb7246 AC |
256 | ) |
257 | .run(); | |
6950bbb0 | 258 | } |
f5f34e85 | 259 | |
0e0d9688 | 260 | #[cargo_test] |
6950bbb0 | 261 | fn invalid8() { |
7fe2fbc8 | 262 | let p = project() |
1e682848 AC |
263 | .file( |
264 | "Cargo.toml", | |
265 | r#" | |
6f8c7d5a EH |
266 | [project] |
267 | name = "foo" | |
268 | version = "0.0.1" | |
269 | authors = [] | |
f5f34e85 | 270 | |
6f8c7d5a EH |
271 | [dependencies.bar] |
272 | path = "bar" | |
273 | features = ["foo/bar"] | |
274 | "#, | |
fecb7246 AC |
275 | ) |
276 | .file("src/main.rs", "") | |
ab19c483 | 277 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) |
d43ee1dd NK |
278 | .file("bar/src/lib.rs", "") |
279 | .build(); | |
f5f34e85 | 280 | |
85984a87 DW |
281 | p.cargo("build --features foo") |
282 | .with_status(101) | |
85854b18 EH |
283 | .with_stderr( |
284 | "\ | |
285 | error: failed to parse manifest at `[CWD]/Cargo.toml` | |
286 | ||
287 | Caused by: | |
288 | feature `foo/bar` in dependency `bar` is not allowed to contain slashes | |
289 | If you want to enable features [..] | |
290 | ", | |
291 | ) | |
85984a87 | 292 | .run(); |
848f8b59 BF |
293 | } |
294 | ||
0e0d9688 | 295 | #[cargo_test] |
c72df674 | 296 | fn invalid9() { |
7fe2fbc8 | 297 | let p = project() |
1e682848 AC |
298 | .file( |
299 | "Cargo.toml", | |
300 | r#" | |
6f8c7d5a EH |
301 | [project] |
302 | name = "foo" | |
303 | version = "0.0.1" | |
304 | authors = [] | |
c72df674 | 305 | |
6f8c7d5a EH |
306 | [dependencies.bar] |
307 | path = "bar" | |
308 | "#, | |
fecb7246 AC |
309 | ) |
310 | .file("src/main.rs", "fn main() {}") | |
ab19c483 | 311 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) |
d43ee1dd NK |
312 | .file("bar/src/lib.rs", "") |
313 | .build(); | |
c72df674 | 314 | |
35ff555b | 315 | p.cargo("build --features bar") |
19a95790 | 316 | .with_stderr( |
35ff555b E |
317 | "\ |
318 | error: Package `foo v0.0.1 ([..])` does not have feature `bar`. It has a required dependency with that name, but only optional dependencies can be used as features. | |
319 | ", | |
320 | ).with_status(101).run(); | |
c72df674 RJ |
321 | } |
322 | ||
0e0d9688 | 323 | #[cargo_test] |
c72df674 | 324 | fn invalid10() { |
7fe2fbc8 | 325 | let p = project() |
1e682848 AC |
326 | .file( |
327 | "Cargo.toml", | |
328 | r#" | |
6f8c7d5a EH |
329 | [project] |
330 | name = "foo" | |
331 | version = "0.0.1" | |
332 | authors = [] | |
c72df674 | 333 | |
6f8c7d5a EH |
334 | [dependencies.bar] |
335 | path = "bar" | |
336 | features = ["baz"] | |
337 | "#, | |
fecb7246 AC |
338 | ) |
339 | .file("src/main.rs", "fn main() {}") | |
1e682848 AC |
340 | .file( |
341 | "bar/Cargo.toml", | |
342 | r#" | |
6f8c7d5a EH |
343 | [package] |
344 | name = "bar" | |
345 | version = "0.0.1" | |
346 | authors = [] | |
c72df674 | 347 | |
6f8c7d5a EH |
348 | [dependencies.baz] |
349 | path = "baz" | |
350 | "#, | |
fecb7246 AC |
351 | ) |
352 | .file("bar/src/lib.rs", "") | |
ab19c483 | 353 | .file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) |
d43ee1dd NK |
354 | .file("bar/baz/src/lib.rs", "") |
355 | .build(); | |
c72df674 | 356 | |
85984a87 | 357 | p.cargo("build").with_stderr("\ |
35ff555b E |
358 | error: failed to select a version for `bar`. |
359 | ... required by package `foo v0.0.1 ([..])` | |
360 | versions that meet the requirements `*` are: 0.0.1 | |
361 | ||
362 | the package `foo` depends on `bar`, with features: `baz` but `bar` does not have these features. | |
363 | It has a required dependency with that name, but only optional dependencies can be used as features. | |
364 | ||
365 | ||
366 | failed to select a version for `bar` which could resolve this conflict | |
367 | ").with_status(101) | |
368 | .run(); | |
c72df674 RJ |
369 | } |
370 | ||
0e0d9688 | 371 | #[cargo_test] |
848f8b59 | 372 | fn no_transitive_dep_feature_requirement() { |
7fe2fbc8 | 373 | let p = project() |
1e682848 AC |
374 | .file( |
375 | "Cargo.toml", | |
376 | r#" | |
6f8c7d5a EH |
377 | [project] |
378 | name = "foo" | |
379 | version = "0.0.1" | |
380 | authors = [] | |
848f8b59 | 381 | |
6f8c7d5a EH |
382 | [dependencies.derived] |
383 | path = "derived" | |
848f8b59 | 384 | |
6f8c7d5a EH |
385 | [features] |
386 | default = ["derived/bar/qux"] | |
387 | "#, | |
fecb7246 AC |
388 | ) |
389 | .file( | |
1e682848 AC |
390 | "src/main.rs", |
391 | r#" | |
6f8c7d5a EH |
392 | extern crate derived; |
393 | fn main() { derived::test(); } | |
394 | "#, | |
fecb7246 AC |
395 | ) |
396 | .file( | |
1e682848 AC |
397 | "derived/Cargo.toml", |
398 | r#" | |
6f8c7d5a EH |
399 | [package] |
400 | name = "derived" | |
401 | version = "0.0.1" | |
402 | authors = [] | |
848f8b59 | 403 | |
6f8c7d5a EH |
404 | [dependencies.bar] |
405 | path = "../bar" | |
406 | "#, | |
fecb7246 AC |
407 | ) |
408 | .file("derived/src/lib.rs", "extern crate bar; pub use bar::test;") | |
1e682848 AC |
409 | .file( |
410 | "bar/Cargo.toml", | |
411 | r#" | |
6f8c7d5a EH |
412 | [package] |
413 | name = "bar" | |
414 | version = "0.0.1" | |
415 | authors = [] | |
848f8b59 | 416 | |
6f8c7d5a EH |
417 | [features] |
418 | qux = [] | |
419 | "#, | |
fecb7246 AC |
420 | ) |
421 | .file( | |
1e682848 AC |
422 | "bar/src/lib.rs", |
423 | r#" | |
6f8c7d5a EH |
424 | #[cfg(feature = "qux")] |
425 | pub fn test() { print!("test"); } | |
426 | "#, | |
fecb7246 AC |
427 | ) |
428 | .build(); | |
85984a87 DW |
429 | p.cargo("build") |
430 | .with_status(101) | |
85854b18 EH |
431 | .with_stderr( |
432 | "\ | |
433 | error: failed to parse manifest at `[CWD]/Cargo.toml` | |
434 | ||
435 | Caused by: | |
436 | multiple slashes in feature `derived/bar/qux` (included by feature `default`) are not allowed | |
437 | ", | |
438 | ) | |
85984a87 | 439 | .run(); |
6950bbb0 | 440 | } |
f5f34e85 | 441 | |
0e0d9688 | 442 | #[cargo_test] |
6950bbb0 | 443 | fn no_feature_doesnt_build() { |
7fe2fbc8 | 444 | let p = project() |
1e682848 AC |
445 | .file( |
446 | "Cargo.toml", | |
447 | r#" | |
6f8c7d5a EH |
448 | [project] |
449 | name = "foo" | |
450 | version = "0.0.1" | |
451 | authors = [] | |
2b46d039 | 452 | |
6f8c7d5a EH |
453 | [dependencies.bar] |
454 | path = "bar" | |
455 | optional = true | |
456 | "#, | |
fecb7246 AC |
457 | ) |
458 | .file( | |
1e682848 AC |
459 | "src/main.rs", |
460 | r#" | |
6f8c7d5a EH |
461 | #[cfg(feature = "bar")] |
462 | extern crate bar; | |
463 | #[cfg(feature = "bar")] | |
464 | fn main() { bar::bar(); println!("bar") } | |
465 | #[cfg(not(feature = "bar"))] | |
466 | fn main() {} | |
467 | "#, | |
fecb7246 AC |
468 | ) |
469 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) | |
d43ee1dd NK |
470 | .file("bar/src/lib.rs", "pub fn bar() {}") |
471 | .build(); | |
2b46d039 | 472 | |
85984a87 | 473 | p.cargo("build") |
2cd9cce6 | 474 | .with_stderr( |
1e682848 | 475 | "\ |
89f43938 | 476 | [COMPILING] foo v0.0.1 ([CWD]) |
34628b65 | 477 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 478 | ", |
fecb7246 AC |
479 | ) |
480 | .run(); | |
2554afe7 | 481 | p.process(&p.bin("foo")).with_stdout("").run(); |
1e682848 | 482 | |
85984a87 | 483 | p.cargo("build --features bar") |
2cd9cce6 | 484 | .with_stderr( |
1e682848 | 485 | "\ |
89f43938 ZL |
486 | [COMPILING] bar v0.0.1 ([CWD]/bar) |
487 | [COMPILING] foo v0.0.1 ([CWD]) | |
34628b65 | 488 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 489 | ", |
fecb7246 AC |
490 | ) |
491 | .run(); | |
2554afe7 | 492 | p.process(&p.bin("foo")).with_stdout("bar\n").run(); |
6950bbb0 | 493 | } |
2b46d039 | 494 | |
0e0d9688 | 495 | #[cargo_test] |
6950bbb0 | 496 | fn default_feature_pulled_in() { |
7fe2fbc8 | 497 | let p = project() |
1e682848 AC |
498 | .file( |
499 | "Cargo.toml", | |
500 | r#" | |
6f8c7d5a EH |
501 | [project] |
502 | name = "foo" | |
503 | version = "0.0.1" | |
504 | authors = [] | |
2b46d039 | 505 | |
6f8c7d5a EH |
506 | [features] |
507 | default = ["bar"] | |
2b46d039 | 508 | |
6f8c7d5a EH |
509 | [dependencies.bar] |
510 | path = "bar" | |
511 | optional = true | |
512 | "#, | |
fecb7246 AC |
513 | ) |
514 | .file( | |
1e682848 AC |
515 | "src/main.rs", |
516 | r#" | |
6f8c7d5a EH |
517 | #[cfg(feature = "bar")] |
518 | extern crate bar; | |
519 | #[cfg(feature = "bar")] | |
520 | fn main() { bar::bar(); println!("bar") } | |
521 | #[cfg(not(feature = "bar"))] | |
522 | fn main() {} | |
523 | "#, | |
fecb7246 AC |
524 | ) |
525 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) | |
d43ee1dd NK |
526 | .file("bar/src/lib.rs", "pub fn bar() {}") |
527 | .build(); | |
2b46d039 | 528 | |
85984a87 | 529 | p.cargo("build") |
2cd9cce6 | 530 | .with_stderr( |
1e682848 | 531 | "\ |
89f43938 ZL |
532 | [COMPILING] bar v0.0.1 ([CWD]/bar) |
533 | [COMPILING] foo v0.0.1 ([CWD]) | |
34628b65 | 534 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 535 | ", |
fecb7246 AC |
536 | ) |
537 | .run(); | |
2554afe7 | 538 | p.process(&p.bin("foo")).with_stdout("bar\n").run(); |
1e682848 | 539 | |
85984a87 | 540 | p.cargo("build --no-default-features") |
2cd9cce6 | 541 | .with_stderr( |
1e682848 | 542 | "\ |
89f43938 | 543 | [COMPILING] foo v0.0.1 ([CWD]) |
34628b65 | 544 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 545 | ", |
fecb7246 AC |
546 | ) |
547 | .run(); | |
2554afe7 | 548 | p.process(&p.bin("foo")).with_stdout("").run(); |
6950bbb0 | 549 | } |
2b46d039 | 550 | |
0e0d9688 | 551 | #[cargo_test] |
6950bbb0 | 552 | fn cyclic_feature() { |
7fe2fbc8 | 553 | let p = project() |
1e682848 AC |
554 | .file( |
555 | "Cargo.toml", | |
556 | r#" | |
6f8c7d5a EH |
557 | [project] |
558 | name = "foo" | |
559 | version = "0.0.1" | |
560 | authors = [] | |
2b46d039 | 561 | |
6f8c7d5a EH |
562 | [features] |
563 | default = ["default"] | |
564 | "#, | |
fecb7246 AC |
565 | ) |
566 | .file("src/main.rs", "") | |
d43ee1dd | 567 | .build(); |
2b46d039 | 568 | |
85984a87 DW |
569 | p.cargo("build") |
570 | .with_status(101) | |
f7c91ba6 | 571 | .with_stderr("[ERROR] cyclic feature dependency: feature `default` depends on itself") |
85984a87 | 572 | .run(); |
6950bbb0 | 573 | } |
2b46d039 | 574 | |
0e0d9688 | 575 | #[cargo_test] |
6950bbb0 | 576 | fn cyclic_feature2() { |
7fe2fbc8 | 577 | let p = project() |
1e682848 AC |
578 | .file( |
579 | "Cargo.toml", | |
580 | r#" | |
6f8c7d5a EH |
581 | [project] |
582 | name = "foo" | |
583 | version = "0.0.1" | |
584 | authors = [] | |
2b46d039 | 585 | |
6f8c7d5a EH |
586 | [features] |
587 | foo = ["bar"] | |
588 | bar = ["foo"] | |
589 | "#, | |
fecb7246 AC |
590 | ) |
591 | .file("src/main.rs", "fn main() {}") | |
d43ee1dd | 592 | .build(); |
2b46d039 | 593 | |
85984a87 | 594 | p.cargo("build").with_stdout("").run(); |
6950bbb0 | 595 | } |
2b46d039 | 596 | |
0e0d9688 | 597 | #[cargo_test] |
6950bbb0 | 598 | fn groups_on_groups_on_groups() { |
7fe2fbc8 | 599 | let p = project() |
1e682848 AC |
600 | .file( |
601 | "Cargo.toml", | |
602 | r#" | |
6f8c7d5a EH |
603 | [project] |
604 | name = "foo" | |
605 | version = "0.0.1" | |
606 | authors = [] | |
2b46d039 | 607 | |
6f8c7d5a EH |
608 | [features] |
609 | default = ["f1"] | |
610 | f1 = ["f2", "bar"] | |
611 | f2 = ["f3", "f4"] | |
612 | f3 = ["f5", "f6", "baz"] | |
613 | f4 = ["f5", "f7"] | |
614 | f5 = ["f6"] | |
615 | f6 = ["f7"] | |
616 | f7 = ["bar"] | |
617 | ||
618 | [dependencies.bar] | |
619 | path = "bar" | |
620 | optional = true | |
621 | ||
622 | [dependencies.baz] | |
623 | path = "baz" | |
624 | optional = true | |
625 | "#, | |
fecb7246 AC |
626 | ) |
627 | .file( | |
1e682848 AC |
628 | "src/main.rs", |
629 | r#" | |
6f8c7d5a EH |
630 | #[allow(unused_extern_crates)] |
631 | extern crate bar; | |
632 | #[allow(unused_extern_crates)] | |
633 | extern crate baz; | |
634 | fn main() {} | |
635 | "#, | |
fecb7246 AC |
636 | ) |
637 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) | |
2b46d039 | 638 | .file("bar/src/lib.rs", "pub fn bar() {}") |
ab19c483 | 639 | .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) |
d43ee1dd NK |
640 | .file("baz/src/lib.rs", "pub fn baz() {}") |
641 | .build(); | |
2b46d039 | 642 | |
85984a87 | 643 | p.cargo("build") |
2cd9cce6 | 644 | .with_stderr( |
1e682848 | 645 | "\ |
89f43938 ZL |
646 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) |
647 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) | |
648 | [COMPILING] foo v0.0.1 ([CWD]) | |
34628b65 | 649 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 650 | ", |
fecb7246 AC |
651 | ) |
652 | .run(); | |
6950bbb0 | 653 | } |
2b46d039 | 654 | |
0e0d9688 | 655 | #[cargo_test] |
6950bbb0 | 656 | fn many_cli_features() { |
7fe2fbc8 | 657 | let p = project() |
1e682848 AC |
658 | .file( |
659 | "Cargo.toml", | |
660 | r#" | |
6f8c7d5a EH |
661 | [project] |
662 | name = "foo" | |
663 | version = "0.0.1" | |
664 | authors = [] | |
2b46d039 | 665 | |
6f8c7d5a EH |
666 | [dependencies.bar] |
667 | path = "bar" | |
668 | optional = true | |
2b46d039 | 669 | |
6f8c7d5a EH |
670 | [dependencies.baz] |
671 | path = "baz" | |
672 | optional = true | |
673 | "#, | |
fecb7246 AC |
674 | ) |
675 | .file( | |
1e682848 AC |
676 | "src/main.rs", |
677 | r#" | |
6f8c7d5a EH |
678 | #[allow(unused_extern_crates)] |
679 | extern crate bar; | |
680 | #[allow(unused_extern_crates)] | |
681 | extern crate baz; | |
682 | fn main() {} | |
683 | "#, | |
fecb7246 AC |
684 | ) |
685 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) | |
2b46d039 | 686 | .file("bar/src/lib.rs", "pub fn bar() {}") |
ab19c483 | 687 | .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) |
d43ee1dd NK |
688 | .file("baz/src/lib.rs", "pub fn baz() {}") |
689 | .build(); | |
2b46d039 | 690 | |
85984a87 DW |
691 | p.cargo("build --features") |
692 | .arg("bar baz") | |
2cd9cce6 | 693 | .with_stderr( |
1e682848 | 694 | "\ |
89f43938 ZL |
695 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) |
696 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) | |
697 | [COMPILING] foo v0.0.1 ([CWD]) | |
34628b65 | 698 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 699 | ", |
fecb7246 AC |
700 | ) |
701 | .run(); | |
6950bbb0 | 702 | } |
2b46d039 | 703 | |
0e0d9688 | 704 | #[cargo_test] |
6950bbb0 | 705 | fn union_features() { |
7fe2fbc8 | 706 | let p = project() |
1e682848 AC |
707 | .file( |
708 | "Cargo.toml", | |
709 | r#" | |
6f8c7d5a EH |
710 | [project] |
711 | name = "foo" | |
712 | version = "0.0.1" | |
713 | authors = [] | |
2b46d039 | 714 | |
6f8c7d5a EH |
715 | [dependencies.d1] |
716 | path = "d1" | |
717 | features = ["f1"] | |
718 | [dependencies.d2] | |
719 | path = "d2" | |
720 | features = ["f2"] | |
721 | "#, | |
fecb7246 AC |
722 | ) |
723 | .file( | |
1e682848 AC |
724 | "src/main.rs", |
725 | r#" | |
6f8c7d5a EH |
726 | #[allow(unused_extern_crates)] |
727 | extern crate d1; | |
728 | extern crate d2; | |
729 | fn main() { | |
730 | d2::f1(); | |
731 | d2::f2(); | |
732 | } | |
733 | "#, | |
fecb7246 AC |
734 | ) |
735 | .file( | |
1e682848 AC |
736 | "d1/Cargo.toml", |
737 | r#" | |
6f8c7d5a EH |
738 | [package] |
739 | name = "d1" | |
740 | version = "0.0.1" | |
741 | authors = [] | |
2b46d039 | 742 | |
6f8c7d5a EH |
743 | [features] |
744 | f1 = ["d2"] | |
2b46d039 | 745 | |
6f8c7d5a EH |
746 | [dependencies.d2] |
747 | path = "../d2" | |
748 | features = ["f1"] | |
749 | optional = true | |
750 | "#, | |
fecb7246 AC |
751 | ) |
752 | .file("d1/src/lib.rs", "") | |
1e682848 AC |
753 | .file( |
754 | "d2/Cargo.toml", | |
755 | r#" | |
6f8c7d5a EH |
756 | [package] |
757 | name = "d2" | |
758 | version = "0.0.1" | |
759 | authors = [] | |
2b46d039 | 760 | |
6f8c7d5a EH |
761 | [features] |
762 | f1 = [] | |
763 | f2 = [] | |
764 | "#, | |
fecb7246 AC |
765 | ) |
766 | .file( | |
1e682848 AC |
767 | "d2/src/lib.rs", |
768 | r#" | |
6f8c7d5a EH |
769 | #[cfg(feature = "f1")] pub fn f1() {} |
770 | #[cfg(feature = "f2")] pub fn f2() {} | |
771 | "#, | |
fecb7246 AC |
772 | ) |
773 | .build(); | |
2b46d039 | 774 | |
85984a87 | 775 | p.cargo("build") |
2cd9cce6 | 776 | .with_stderr( |
1e682848 | 777 | "\ |
89f43938 ZL |
778 | [COMPILING] d2 v0.0.1 ([CWD]/d2) |
779 | [COMPILING] d1 v0.0.1 ([CWD]/d1) | |
780 | [COMPILING] foo v0.0.1 ([CWD]) | |
34628b65 | 781 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 782 | ", |
fecb7246 AC |
783 | ) |
784 | .run(); | |
6950bbb0 | 785 | } |
99087dd3 | 786 | |
0e0d9688 | 787 | #[cargo_test] |
6950bbb0 | 788 | fn many_features_no_rebuilds() { |
7fe2fbc8 | 789 | let p = project() |
1e682848 AC |
790 | .file( |
791 | "Cargo.toml", | |
792 | r#" | |
6f8c7d5a EH |
793 | [package] |
794 | name = "b" | |
795 | version = "0.1.0" | |
796 | authors = [] | |
99087dd3 | 797 | |
6f8c7d5a EH |
798 | [dependencies.a] |
799 | path = "a" | |
800 | features = ["fall"] | |
801 | "#, | |
fecb7246 AC |
802 | ) |
803 | .file("src/main.rs", "fn main() {}") | |
1e682848 AC |
804 | .file( |
805 | "a/Cargo.toml", | |
806 | r#" | |
6f8c7d5a EH |
807 | [package] |
808 | name = "a" | |
809 | version = "0.1.0" | |
810 | authors = [] | |
99087dd3 | 811 | |
6f8c7d5a EH |
812 | [features] |
813 | ftest = [] | |
814 | ftest2 = [] | |
815 | fall = ["ftest", "ftest2"] | |
816 | "#, | |
fecb7246 AC |
817 | ) |
818 | .file("a/src/lib.rs", "") | |
d43ee1dd | 819 | .build(); |
99087dd3 | 820 | |
85984a87 | 821 | p.cargo("build") |
2cd9cce6 | 822 | .with_stderr( |
1e682848 | 823 | "\ |
89f43938 ZL |
824 | [COMPILING] a v0.1.0 ([CWD]/a) |
825 | [COMPILING] b v0.1.0 ([CWD]) | |
34628b65 | 826 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 827 | ", |
fecb7246 AC |
828 | ) |
829 | .run(); | |
763ba535 | 830 | p.root().move_into_the_past(); |
99087dd3 | 831 | |
85984a87 DW |
832 | p.cargo("build -v") |
833 | .with_stderr( | |
1e682848 | 834 | "\ |
29cdad4f AK |
835 | [FRESH] a v0.1.0 ([..]/a) |
836 | [FRESH] b v0.1.0 ([..]) | |
34628b65 | 837 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 838 | ", |
fecb7246 AC |
839 | ) |
840 | .run(); | |
6950bbb0 | 841 | } |
e53e981d VH |
842 | |
843 | // Tests that all cmd lines work with `--features ""` | |
0e0d9688 | 844 | #[cargo_test] |
6950bbb0 | 845 | fn empty_features() { |
85984a87 | 846 | let p = project().file("src/main.rs", "fn main() {}").build(); |
e53e981d | 847 | |
85984a87 | 848 | p.cargo("build --features").arg("").run(); |
6950bbb0 | 849 | } |
f5f34e85 AC |
850 | |
851 | // Tests that all cmd lines work with `--features ""` | |
0e0d9688 | 852 | #[cargo_test] |
6950bbb0 | 853 | fn transitive_features() { |
7fe2fbc8 | 854 | let p = project() |
1e682848 AC |
855 | .file( |
856 | "Cargo.toml", | |
857 | r#" | |
6f8c7d5a EH |
858 | [project] |
859 | name = "foo" | |
860 | version = "0.0.1" | |
861 | authors = [] | |
f5f34e85 | 862 | |
6f8c7d5a EH |
863 | [features] |
864 | foo = ["bar/baz"] | |
f5f34e85 | 865 | |
6f8c7d5a EH |
866 | [dependencies.bar] |
867 | path = "bar" | |
868 | "#, | |
fecb7246 AC |
869 | ) |
870 | .file("src/main.rs", "extern crate bar; fn main() { bar::baz(); }") | |
1e682848 AC |
871 | .file( |
872 | "bar/Cargo.toml", | |
873 | r#" | |
6f8c7d5a EH |
874 | [package] |
875 | name = "bar" | |
876 | version = "0.0.1" | |
877 | authors = [] | |
f5f34e85 | 878 | |
6f8c7d5a EH |
879 | [features] |
880 | baz = [] | |
881 | "#, | |
fecb7246 AC |
882 | ) |
883 | .file( | |
85984a87 DW |
884 | "bar/src/lib.rs", |
885 | r#"#[cfg(feature = "baz")] pub fn baz() {}"#, | |
fecb7246 AC |
886 | ) |
887 | .build(); | |
f5f34e85 | 888 | |
85984a87 | 889 | p.cargo("build --features foo").run(); |
6950bbb0 | 890 | } |
8670b56a | 891 | |
0e0d9688 | 892 | #[cargo_test] |
6950bbb0 | 893 | fn everything_in_the_lockfile() { |
7fe2fbc8 | 894 | let p = project() |
1e682848 AC |
895 | .file( |
896 | "Cargo.toml", | |
897 | r#" | |
6f8c7d5a EH |
898 | [project] |
899 | name = "foo" | |
900 | version = "0.0.1" | |
901 | authors = [] | |
8670b56a | 902 | |
6f8c7d5a EH |
903 | [features] |
904 | f1 = ["d1/f1"] | |
905 | f2 = ["d2"] | |
906 | ||
907 | [dependencies.d1] | |
908 | path = "d1" | |
909 | [dependencies.d2] | |
910 | path = "d2" | |
911 | optional = true | |
912 | [dependencies.d3] | |
913 | path = "d3" | |
914 | optional = true | |
915 | "#, | |
fecb7246 AC |
916 | ) |
917 | .file("src/main.rs", "fn main() {}") | |
1e682848 AC |
918 | .file( |
919 | "d1/Cargo.toml", | |
920 | r#" | |
6f8c7d5a EH |
921 | [package] |
922 | name = "d1" | |
923 | version = "0.0.1" | |
924 | authors = [] | |
8670b56a | 925 | |
6f8c7d5a EH |
926 | [features] |
927 | f1 = [] | |
928 | "#, | |
fecb7246 AC |
929 | ) |
930 | .file("d1/src/lib.rs", "") | |
ab19c483 | 931 | .file("d2/Cargo.toml", &basic_manifest("d2", "0.0.2")) |
8670b56a | 932 | .file("d2/src/lib.rs", "") |
1e682848 AC |
933 | .file( |
934 | "d3/Cargo.toml", | |
935 | r#" | |
6f8c7d5a EH |
936 | [package] |
937 | name = "d3" | |
938 | version = "0.0.3" | |
939 | authors = [] | |
8670b56a | 940 | |
6f8c7d5a EH |
941 | [features] |
942 | f3 = [] | |
943 | "#, | |
fecb7246 AC |
944 | ) |
945 | .file("d3/src/lib.rs", "") | |
d43ee1dd | 946 | .build(); |
8670b56a | 947 | |
85984a87 | 948 | p.cargo("fetch").run(); |
4ae79d2f | 949 | let lockfile = p.read_lockfile(); |
1e682848 AC |
950 | assert!( |
951 | lockfile.contains(r#"name = "d1""#), | |
952 | "d1 not found\n{}", | |
953 | lockfile | |
954 | ); | |
955 | assert!( | |
956 | lockfile.contains(r#"name = "d2""#), | |
957 | "d2 not found\n{}", | |
958 | lockfile | |
959 | ); | |
960 | assert!( | |
961 | lockfile.contains(r#"name = "d3""#), | |
962 | "d3 not found\n{}", | |
963 | lockfile | |
964 | ); | |
6950bbb0 | 965 | } |
40d1c10a | 966 | |
0e0d9688 | 967 | #[cargo_test] |
6950bbb0 | 968 | fn no_rebuild_when_frobbing_default_feature() { |
7fe2fbc8 | 969 | let p = project() |
1e682848 AC |
970 | .file( |
971 | "Cargo.toml", | |
972 | r#" | |
6f8c7d5a EH |
973 | [package] |
974 | name = "foo" | |
975 | version = "0.1.0" | |
976 | authors = [] | |
40d1c10a | 977 | |
6f8c7d5a EH |
978 | [dependencies] |
979 | a = { path = "a" } | |
980 | b = { path = "b" } | |
981 | "#, | |
fecb7246 AC |
982 | ) |
983 | .file("src/lib.rs", "") | |
1e682848 AC |
984 | .file( |
985 | "b/Cargo.toml", | |
986 | r#" | |
6f8c7d5a EH |
987 | [package] |
988 | name = "b" | |
989 | version = "0.1.0" | |
990 | authors = [] | |
40d1c10a | 991 | |
6f8c7d5a EH |
992 | [dependencies] |
993 | a = { path = "../a", features = ["f1"], default-features = false } | |
994 | "#, | |
fecb7246 AC |
995 | ) |
996 | .file("b/src/lib.rs", "") | |
1e682848 AC |
997 | .file( |
998 | "a/Cargo.toml", | |
999 | r#" | |
6f8c7d5a EH |
1000 | [package] |
1001 | name = "a" | |
1002 | version = "0.1.0" | |
1003 | authors = [] | |
40d1c10a | 1004 | |
6f8c7d5a EH |
1005 | [features] |
1006 | default = ["f1"] | |
1007 | f1 = [] | |
1008 | "#, | |
fecb7246 AC |
1009 | ) |
1010 | .file("a/src/lib.rs", "") | |
d43ee1dd | 1011 | .build(); |
40d1c10a | 1012 | |
85984a87 DW |
1013 | p.cargo("build").run(); |
1014 | p.cargo("build").with_stdout("").run(); | |
1015 | p.cargo("build").with_stdout("").run(); | |
6950bbb0 | 1016 | } |
0ba5a7a2 | 1017 | |
0e0d9688 | 1018 | #[cargo_test] |
6950bbb0 | 1019 | fn unions_work_with_no_default_features() { |
7fe2fbc8 | 1020 | let p = project() |
1e682848 AC |
1021 | .file( |
1022 | "Cargo.toml", | |
1023 | r#" | |
6f8c7d5a EH |
1024 | [package] |
1025 | name = "foo" | |
1026 | version = "0.1.0" | |
1027 | authors = [] | |
0ba5a7a2 | 1028 | |
6f8c7d5a EH |
1029 | [dependencies] |
1030 | a = { path = "a" } | |
1031 | b = { path = "b" } | |
1032 | "#, | |
fecb7246 AC |
1033 | ) |
1034 | .file("src/lib.rs", "extern crate a; pub fn foo() { a::a(); }") | |
1e682848 AC |
1035 | .file( |
1036 | "b/Cargo.toml", | |
1037 | r#" | |
6f8c7d5a EH |
1038 | [package] |
1039 | name = "b" | |
1040 | version = "0.1.0" | |
1041 | authors = [] | |
0ba5a7a2 | 1042 | |
6f8c7d5a EH |
1043 | [dependencies] |
1044 | a = { path = "../a", features = [], default-features = false } | |
1045 | "#, | |
fecb7246 AC |
1046 | ) |
1047 | .file("b/src/lib.rs", "") | |
1e682848 AC |
1048 | .file( |
1049 | "a/Cargo.toml", | |
1050 | r#" | |
6f8c7d5a EH |
1051 | [package] |
1052 | name = "a" | |
1053 | version = "0.1.0" | |
1054 | authors = [] | |
0ba5a7a2 | 1055 | |
6f8c7d5a EH |
1056 | [features] |
1057 | default = ["f1"] | |
1058 | f1 = [] | |
1059 | "#, | |
fecb7246 AC |
1060 | ) |
1061 | .file("a/src/lib.rs", r#"#[cfg(feature = "f1")] pub fn a() {}"#) | |
d43ee1dd | 1062 | .build(); |
0ba5a7a2 | 1063 | |
85984a87 DW |
1064 | p.cargo("build").run(); |
1065 | p.cargo("build").with_stdout("").run(); | |
1066 | p.cargo("build").with_stdout("").run(); | |
6950bbb0 | 1067 | } |
70152d80 | 1068 | |
0e0d9688 | 1069 | #[cargo_test] |
6950bbb0 | 1070 | fn optional_and_dev_dep() { |
7fe2fbc8 | 1071 | let p = project() |
1e682848 AC |
1072 | .file( |
1073 | "Cargo.toml", | |
1074 | r#" | |
6f8c7d5a EH |
1075 | [package] |
1076 | name = "test" | |
1077 | version = "0.1.0" | |
1078 | authors = [] | |
70152d80 | 1079 | |
6f8c7d5a EH |
1080 | [dependencies] |
1081 | foo = { path = "foo", optional = true } | |
1082 | [dev-dependencies] | |
1083 | foo = { path = "foo" } | |
1084 | "#, | |
fecb7246 AC |
1085 | ) |
1086 | .file("src/lib.rs", "") | |
ab19c483 | 1087 | .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) |
d43ee1dd NK |
1088 | .file("foo/src/lib.rs", "") |
1089 | .build(); | |
70152d80 | 1090 | |
85984a87 DW |
1091 | p.cargo("build") |
1092 | .with_stderr( | |
1e682848 | 1093 | "\ |
29cdad4f | 1094 | [COMPILING] test v0.1.0 ([..]) |
34628b65 | 1095 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 1096 | ", |
fecb7246 AC |
1097 | ) |
1098 | .run(); | |
6950bbb0 | 1099 | } |
e2e1751a | 1100 | |
0e0d9688 | 1101 | #[cargo_test] |
6950bbb0 | 1102 | fn activating_feature_activates_dep() { |
7fe2fbc8 | 1103 | let p = project() |
1e682848 AC |
1104 | .file( |
1105 | "Cargo.toml", | |
1106 | r#" | |
6f8c7d5a EH |
1107 | [package] |
1108 | name = "test" | |
1109 | version = "0.1.0" | |
1110 | authors = [] | |
e2e1751a | 1111 | |
6f8c7d5a EH |
1112 | [dependencies] |
1113 | foo = { path = "foo", optional = true } | |
e2e1751a | 1114 | |
6f8c7d5a EH |
1115 | [features] |
1116 | a = ["foo/a"] | |
1117 | "#, | |
fecb7246 AC |
1118 | ) |
1119 | .file( | |
85984a87 DW |
1120 | "src/lib.rs", |
1121 | "extern crate foo; pub fn bar() { foo::bar(); }", | |
fecb7246 AC |
1122 | ) |
1123 | .file( | |
1e682848 AC |
1124 | "foo/Cargo.toml", |
1125 | r#" | |
6f8c7d5a EH |
1126 | [package] |
1127 | name = "foo" | |
1128 | version = "0.1.0" | |
1129 | authors = [] | |
e2e1751a | 1130 | |
6f8c7d5a EH |
1131 | [features] |
1132 | a = [] | |
1133 | "#, | |
fecb7246 AC |
1134 | ) |
1135 | .file("foo/src/lib.rs", r#"#[cfg(feature = "a")] pub fn bar() {}"#) | |
d43ee1dd | 1136 | .build(); |
e2e1751a | 1137 | |
85984a87 | 1138 | p.cargo("build --features a -v").run(); |
6950bbb0 | 1139 | } |
6f28ef2d | 1140 | |
0e0d9688 | 1141 | #[cargo_test] |
6f28ef2d | 1142 | fn dep_feature_in_cmd_line() { |
7fe2fbc8 | 1143 | let p = project() |
1e682848 AC |
1144 | .file( |
1145 | "Cargo.toml", | |
1146 | r#" | |
6f8c7d5a EH |
1147 | [project] |
1148 | name = "foo" | |
1149 | version = "0.0.1" | |
1150 | authors = [] | |
6f28ef2d | 1151 | |
6f8c7d5a EH |
1152 | [dependencies.derived] |
1153 | path = "derived" | |
1154 | "#, | |
fecb7246 AC |
1155 | ) |
1156 | .file( | |
1e682848 AC |
1157 | "src/main.rs", |
1158 | r#" | |
6f8c7d5a EH |
1159 | extern crate derived; |
1160 | fn main() { derived::test(); } | |
1161 | "#, | |
fecb7246 AC |
1162 | ) |
1163 | .file( | |
1e682848 AC |
1164 | "derived/Cargo.toml", |
1165 | r#" | |
6f8c7d5a EH |
1166 | [package] |
1167 | name = "derived" | |
1168 | version = "0.0.1" | |
1169 | authors = [] | |
6f28ef2d | 1170 | |
6f8c7d5a EH |
1171 | [dependencies.bar] |
1172 | path = "../bar" | |
6f28ef2d | 1173 | |
6f8c7d5a EH |
1174 | [features] |
1175 | default = [] | |
1176 | derived-feat = ["bar/some-feat"] | |
1177 | "#, | |
fecb7246 AC |
1178 | ) |
1179 | .file("derived/src/lib.rs", "extern crate bar; pub use bar::test;") | |
1e682848 AC |
1180 | .file( |
1181 | "bar/Cargo.toml", | |
1182 | r#" | |
6f8c7d5a EH |
1183 | [package] |
1184 | name = "bar" | |
1185 | version = "0.0.1" | |
1186 | authors = [] | |
6f28ef2d | 1187 | |
6f8c7d5a EH |
1188 | [features] |
1189 | some-feat = [] | |
1190 | "#, | |
fecb7246 AC |
1191 | ) |
1192 | .file( | |
1e682848 AC |
1193 | "bar/src/lib.rs", |
1194 | r#" | |
6f8c7d5a EH |
1195 | #[cfg(feature = "some-feat")] |
1196 | pub fn test() { print!("test"); } | |
1197 | "#, | |
fecb7246 AC |
1198 | ) |
1199 | .build(); | |
6f28ef2d BF |
1200 | |
1201 | // The foo project requires that feature "some-feat" in "bar" is enabled. | |
1202 | // Building without any features enabled should fail: | |
f58d107e EH |
1203 | p.cargo("build") |
1204 | .with_status(101) | |
1205 | .with_stderr_contains("[..]unresolved import `bar::test`") | |
1206 | .run(); | |
6f28ef2d BF |
1207 | |
1208 | // We should be able to enable the feature "derived-feat", which enables "some-feat", | |
1209 | // on the command line. The feature is enabled, thus building should be successful: | |
85984a87 | 1210 | p.cargo("build --features derived/derived-feat").run(); |
6f28ef2d BF |
1211 | |
1212 | // Trying to enable features of transitive dependencies is an error | |
85984a87 DW |
1213 | p.cargo("build --features bar/some-feat") |
1214 | .with_status(101) | |
bcfdf9fb | 1215 | .with_stderr("error: package `foo v0.0.1 ([..])` does not have a dependency named `bar`") |
85984a87 | 1216 | .run(); |
6f28ef2d BF |
1217 | |
1218 | // Hierarchical feature specification should still be disallowed | |
85984a87 DW |
1219 | p.cargo("build --features derived/bar/some-feat") |
1220 | .with_status(101) | |
85854b18 | 1221 | .with_stderr("[ERROR] multiple slashes in feature `derived/bar/some-feat` is not allowed") |
85984a87 | 1222 | .run(); |
1f88ad53 | 1223 | } |
1f8b3988 | 1224 | |
0e0d9688 | 1225 | #[cargo_test] |
1f8b3988 | 1226 | fn all_features_flag_enables_all_features() { |
7fe2fbc8 | 1227 | let p = project() |
1e682848 AC |
1228 | .file( |
1229 | "Cargo.toml", | |
1230 | r#" | |
6f8c7d5a EH |
1231 | [project] |
1232 | name = "foo" | |
1233 | version = "0.0.1" | |
1234 | authors = [] | |
1f8b3988 | 1235 | |
6f8c7d5a EH |
1236 | [features] |
1237 | foo = [] | |
1238 | bar = [] | |
1f8b3988 | 1239 | |
6f8c7d5a EH |
1240 | [dependencies.baz] |
1241 | path = "baz" | |
1242 | optional = true | |
1243 | "#, | |
fecb7246 AC |
1244 | ) |
1245 | .file( | |
1e682848 AC |
1246 | "src/main.rs", |
1247 | r#" | |
6f8c7d5a EH |
1248 | #[cfg(feature = "foo")] |
1249 | pub fn foo() {} | |
1f8b3988 | 1250 | |
6f8c7d5a EH |
1251 | #[cfg(feature = "bar")] |
1252 | pub fn bar() { | |
1253 | extern crate baz; | |
1254 | baz::baz(); | |
1255 | } | |
1f8b3988 | 1256 | |
6f8c7d5a EH |
1257 | fn main() { |
1258 | foo(); | |
1259 | bar(); | |
1260 | } | |
1261 | "#, | |
fecb7246 AC |
1262 | ) |
1263 | .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) | |
d43ee1dd NK |
1264 | .file("baz/src/lib.rs", "pub fn baz() {}") |
1265 | .build(); | |
1f8b3988 | 1266 | |
85984a87 | 1267 | p.cargo("build --all-features").run(); |
1f8b3988 | 1268 | } |
72f84271 | 1269 | |
0e0d9688 | 1270 | #[cargo_test] |
72f84271 | 1271 | fn many_cli_features_comma_delimited() { |
7fe2fbc8 | 1272 | let p = project() |
1e682848 AC |
1273 | .file( |
1274 | "Cargo.toml", | |
1275 | r#" | |
6f8c7d5a EH |
1276 | [project] |
1277 | name = "foo" | |
1278 | version = "0.0.1" | |
1279 | authors = [] | |
72f84271 | 1280 | |
6f8c7d5a EH |
1281 | [dependencies.bar] |
1282 | path = "bar" | |
1283 | optional = true | |
72f84271 | 1284 | |
6f8c7d5a EH |
1285 | [dependencies.baz] |
1286 | path = "baz" | |
1287 | optional = true | |
1288 | "#, | |
fecb7246 AC |
1289 | ) |
1290 | .file( | |
1e682848 AC |
1291 | "src/main.rs", |
1292 | r#" | |
6f8c7d5a EH |
1293 | #[allow(unused_extern_crates)] |
1294 | extern crate bar; | |
1295 | #[allow(unused_extern_crates)] | |
1296 | extern crate baz; | |
1297 | fn main() {} | |
1298 | "#, | |
fecb7246 AC |
1299 | ) |
1300 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) | |
72f84271 | 1301 | .file("bar/src/lib.rs", "pub fn bar() {}") |
ab19c483 | 1302 | .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) |
d43ee1dd NK |
1303 | .file("baz/src/lib.rs", "pub fn baz() {}") |
1304 | .build(); | |
72f84271 | 1305 | |
85984a87 | 1306 | p.cargo("build --features bar,baz") |
2cd9cce6 | 1307 | .with_stderr( |
1e682848 | 1308 | "\ |
89f43938 ZL |
1309 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) |
1310 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) | |
1311 | [COMPILING] foo v0.0.1 ([CWD]) | |
72f84271 | 1312 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 1313 | ", |
fecb7246 AC |
1314 | ) |
1315 | .run(); | |
72f84271 RV |
1316 | } |
1317 | ||
0e0d9688 | 1318 | #[cargo_test] |
72f84271 | 1319 | fn many_cli_features_comma_and_space_delimited() { |
7fe2fbc8 | 1320 | let p = project() |
1e682848 AC |
1321 | .file( |
1322 | "Cargo.toml", | |
1323 | r#" | |
6f8c7d5a EH |
1324 | [project] |
1325 | name = "foo" | |
1326 | version = "0.0.1" | |
1327 | authors = [] | |
72f84271 | 1328 | |
6f8c7d5a EH |
1329 | [dependencies.bar] |
1330 | path = "bar" | |
1331 | optional = true | |
72f84271 | 1332 | |
6f8c7d5a EH |
1333 | [dependencies.baz] |
1334 | path = "baz" | |
1335 | optional = true | |
72f84271 | 1336 | |
6f8c7d5a EH |
1337 | [dependencies.bam] |
1338 | path = "bam" | |
1339 | optional = true | |
72f84271 | 1340 | |
6f8c7d5a EH |
1341 | [dependencies.bap] |
1342 | path = "bap" | |
1343 | optional = true | |
1344 | "#, | |
fecb7246 AC |
1345 | ) |
1346 | .file( | |
1e682848 AC |
1347 | "src/main.rs", |
1348 | r#" | |
6f8c7d5a EH |
1349 | #[allow(unused_extern_crates)] |
1350 | extern crate bar; | |
1351 | #[allow(unused_extern_crates)] | |
1352 | extern crate baz; | |
1353 | #[allow(unused_extern_crates)] | |
1354 | extern crate bam; | |
1355 | #[allow(unused_extern_crates)] | |
1356 | extern crate bap; | |
1357 | fn main() {} | |
1358 | "#, | |
fecb7246 AC |
1359 | ) |
1360 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) | |
72f84271 | 1361 | .file("bar/src/lib.rs", "pub fn bar() {}") |
ab19c483 | 1362 | .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) |
72f84271 | 1363 | .file("baz/src/lib.rs", "pub fn baz() {}") |
ab19c483 | 1364 | .file("bam/Cargo.toml", &basic_manifest("bam", "0.0.1")) |
72f84271 | 1365 | .file("bam/src/lib.rs", "pub fn bam() {}") |
ab19c483 | 1366 | .file("bap/Cargo.toml", &basic_manifest("bap", "0.0.1")) |
d43ee1dd NK |
1367 | .file("bap/src/lib.rs", "pub fn bap() {}") |
1368 | .build(); | |
72f84271 | 1369 | |
85984a87 DW |
1370 | p.cargo("build --features") |
1371 | .arg("bar,baz bam bap") | |
2cd9cce6 | 1372 | .with_stderr( |
1e682848 | 1373 | "\ |
89f43938 ZL |
1374 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) |
1375 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) | |
1376 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) | |
1377 | [COMPILING] ba[..] v0.0.1 ([CWD]/ba[..]) | |
1378 | [COMPILING] foo v0.0.1 ([CWD]) | |
72f84271 | 1379 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
1e682848 | 1380 | ", |
fecb7246 AC |
1381 | ) |
1382 | .run(); | |
72f84271 | 1383 | } |
8d0b31b9 | 1384 | |
0e0d9688 | 1385 | #[cargo_test] |
02b0dba3 AC |
1386 | fn only_dep_is_optional() { |
1387 | Package::new("bar", "0.1.0").publish(); | |
1388 | ||
7fe2fbc8 | 1389 | let p = project() |
02b0dba3 AC |
1390 | .file( |
1391 | "Cargo.toml", | |
1392 | r#" | |
1393 | [project] | |
1394 | name = "foo" | |
1395 | version = "0.0.1" | |
1396 | authors = [] | |
1397 | ||
1398 | [features] | |
1399 | foo = ['bar'] | |
1400 | ||
1401 | [dependencies] | |
1402 | bar = { version = "0.1", optional = true } | |
1403 | ||
1404 | [dev-dependencies] | |
1405 | bar = "0.1" | |
1406 | "#, | |
fecb7246 AC |
1407 | ) |
1408 | .file("src/main.rs", "fn main() {}") | |
02b0dba3 AC |
1409 | .build(); |
1410 | ||
85984a87 | 1411 | p.cargo("build").run(); |
02b0dba3 | 1412 | } |
a70d5197 | 1413 | |
0e0d9688 | 1414 | #[cargo_test] |
a70d5197 AC |
1415 | fn all_features_all_crates() { |
1416 | Package::new("bar", "0.1.0").publish(); | |
1417 | ||
7fe2fbc8 | 1418 | let p = project() |
a70d5197 AC |
1419 | .file( |
1420 | "Cargo.toml", | |
1421 | r#" | |
1422 | [project] | |
1423 | name = "foo" | |
1424 | version = "0.0.1" | |
1425 | authors = [] | |
1426 | ||
1427 | [workspace] | |
1428 | members = ['bar'] | |
1429 | "#, | |
fecb7246 AC |
1430 | ) |
1431 | .file("src/main.rs", "fn main() {}") | |
a70d5197 AC |
1432 | .file( |
1433 | "bar/Cargo.toml", | |
1434 | r#" | |
1435 | [project] | |
1436 | name = "bar" | |
1437 | version = "0.0.1" | |
1438 | authors = [] | |
1439 | ||
1440 | [features] | |
1441 | foo = [] | |
1442 | "#, | |
fecb7246 AC |
1443 | ) |
1444 | .file("bar/src/main.rs", "#[cfg(feature = \"foo\")] fn main() {}") | |
a70d5197 AC |
1445 | .build(); |
1446 | ||
ecf824f7 | 1447 | p.cargo("build --all-features --workspace").run(); |
a70d5197 | 1448 | } |
b29d4d48 | 1449 | |
0e0d9688 | 1450 | #[cargo_test] |
b29d4d48 EH |
1451 | fn feature_off_dylib() { |
1452 | let p = project() | |
1453 | .file( | |
1454 | "Cargo.toml", | |
1455 | r#" | |
6f8c7d5a EH |
1456 | [workspace] |
1457 | members = ["bar"] | |
b29d4d48 | 1458 | |
6f8c7d5a EH |
1459 | [package] |
1460 | name = "foo" | |
1461 | version = "0.0.1" | |
b29d4d48 | 1462 | |
6f8c7d5a EH |
1463 | [lib] |
1464 | crate-type = ["dylib"] | |
b29d4d48 | 1465 | |
6f8c7d5a EH |
1466 | [features] |
1467 | f1 = [] | |
1468 | "#, | |
b29d4d48 EH |
1469 | ) |
1470 | .file( | |
1471 | "src/lib.rs", | |
1472 | r#" | |
6f8c7d5a EH |
1473 | pub fn hello() -> &'static str { |
1474 | if cfg!(feature = "f1") { | |
1475 | "f1" | |
1476 | } else { | |
1477 | "no f1" | |
1478 | } | |
b29d4d48 | 1479 | } |
6f8c7d5a | 1480 | "#, |
b29d4d48 EH |
1481 | ) |
1482 | .file( | |
1483 | "bar/Cargo.toml", | |
1484 | r#" | |
6f8c7d5a EH |
1485 | [package] |
1486 | name = "bar" | |
1487 | version = "0.0.1" | |
b29d4d48 | 1488 | |
6f8c7d5a EH |
1489 | [dependencies] |
1490 | foo = { path = ".." } | |
1491 | "#, | |
b29d4d48 EH |
1492 | ) |
1493 | .file( | |
1494 | "bar/src/main.rs", | |
1495 | r#" | |
6f8c7d5a | 1496 | extern crate foo; |
b29d4d48 | 1497 | |
6f8c7d5a EH |
1498 | fn main() { |
1499 | assert_eq!(foo::hello(), "no f1"); | |
1500 | } | |
1501 | "#, | |
b29d4d48 EH |
1502 | ) |
1503 | .build(); | |
1504 | ||
1505 | // Build the dylib with `f1` feature. | |
1506 | p.cargo("build --features f1").run(); | |
1507 | // Check that building without `f1` uses a dylib without `f1`. | |
1508 | p.cargo("run -p bar").run(); | |
1509 | } | |
86037b8a | 1510 | |
0e0d9688 | 1511 | #[cargo_test] |
86037b8a FB |
1512 | fn warn_if_default_features() { |
1513 | let p = project() | |
1514 | .file( | |
1515 | "Cargo.toml", | |
1516 | r#" | |
6f8c7d5a EH |
1517 | [project] |
1518 | name = "foo" | |
1519 | version = "0.0.1" | |
1520 | authors = [] | |
86037b8a | 1521 | |
6f8c7d5a EH |
1522 | [dependencies.bar] |
1523 | path = "bar" | |
1524 | optional = true | |
86037b8a | 1525 | |
6f8c7d5a EH |
1526 | [features] |
1527 | default-features = ["bar"] | |
1528 | "#, | |
fecb7246 AC |
1529 | ) |
1530 | .file("src/main.rs", "fn main() {}") | |
1531 | .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) | |
86037b8a FB |
1532 | .file("bar/src/lib.rs", "pub fn bar() {}") |
1533 | .build(); | |
1534 | ||
1535 | p.cargo("build") | |
d522344f FB |
1536 | .with_stderr( |
1537 | r#" | |
1538 | [WARNING] `default-features = [".."]` was found in [features]. Did you mean to use `default = [".."]`? | |
86037b8a FB |
1539 | [COMPILING] foo v0.0.1 ([CWD]) |
1540 | [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] | |
d522344f | 1541 | "#.trim(), |
86037b8a FB |
1542 | ).run(); |
1543 | } | |
dbc2c2b5 | 1544 | |
0e0d9688 | 1545 | #[cargo_test] |
dbc2c2b5 AC |
1546 | fn no_feature_for_non_optional_dep() { |
1547 | let p = project() | |
1548 | .file( | |
1549 | "Cargo.toml", | |
1550 | r#" | |
1551 | [project] | |
1552 | name = "foo" | |
1553 | version = "0.0.1" | |
1554 | authors = [] | |
1555 | ||
1556 | [dependencies] | |
1557 | bar = { path = "bar" } | |
6f8c7d5a | 1558 | "#, |
dbc2c2b5 AC |
1559 | ) |
1560 | .file( | |
1561 | "src/main.rs", | |
1562 | r#" | |
1563 | #[cfg(not(feature = "bar"))] | |
1564 | fn main() { | |
1565 | } | |
1566 | "#, | |
1567 | ) | |
1568 | .file( | |
1569 | "bar/Cargo.toml", | |
1570 | r#" | |
1571 | [project] | |
1572 | name = "bar" | |
1573 | version = "0.0.1" | |
1574 | authors = [] | |
1575 | ||
1576 | [features] | |
1577 | a = [] | |
6f8c7d5a | 1578 | "#, |
dbc2c2b5 AC |
1579 | ) |
1580 | .file("bar/src/lib.rs", "pub fn bar() {}") | |
1581 | .build(); | |
1582 | ||
1583 | p.cargo("build --features bar/a").run(); | |
1584 | } | |
51c26b67 WVM |
1585 | |
1586 | #[cargo_test] | |
1587 | fn features_option_given_twice() { | |
1588 | let p = project() | |
1589 | .file( | |
1590 | "Cargo.toml", | |
1591 | r#" | |
1592 | [project] | |
1593 | name = "foo" | |
1594 | version = "0.0.1" | |
1595 | authors = [] | |
1596 | ||
1597 | [features] | |
1598 | a = [] | |
1599 | b = [] | |
6f8c7d5a | 1600 | "#, |
51c26b67 WVM |
1601 | ) |
1602 | .file( | |
1603 | "src/main.rs", | |
1604 | r#" | |
1605 | #[cfg(all(feature = "a", feature = "b"))] | |
1606 | fn main() {} | |
1607 | "#, | |
1608 | ) | |
1609 | .build(); | |
1610 | ||
1611 | p.cargo("build --features a --features b").run(); | |
1612 | } | |
1613 | ||
1614 | #[cargo_test] | |
1615 | fn multi_multi_features() { | |
1616 | let p = project() | |
1617 | .file( | |
1618 | "Cargo.toml", | |
1619 | r#" | |
1620 | [project] | |
1621 | name = "foo" | |
1622 | version = "0.0.1" | |
1623 | authors = [] | |
1624 | ||
1625 | [features] | |
1626 | a = [] | |
1627 | b = [] | |
1628 | c = [] | |
1629 | "#, | |
1630 | ) | |
1631 | .file( | |
1632 | "src/main.rs", | |
1633 | r#" | |
1634 | #[cfg(all(feature = "a", feature = "b", feature = "c"))] | |
1635 | fn main() {} | |
1636 | "#, | |
1637 | ) | |
1638 | .build(); | |
1639 | ||
1640 | p.cargo("build --features a --features").arg("b c").run(); | |
1641 | } | |
1fa02e77 AC |
1642 | |
1643 | #[cargo_test] | |
1644 | fn cli_parse_ok() { | |
1645 | let p = project() | |
1646 | .file( | |
1647 | "Cargo.toml", | |
1648 | r#" | |
1649 | [project] | |
1650 | name = "foo" | |
1651 | version = "0.0.1" | |
1652 | authors = [] | |
1653 | ||
1654 | [features] | |
1655 | a = [] | |
1656 | "#, | |
1657 | ) | |
1658 | .file( | |
1659 | "src/main.rs", | |
1660 | r#" | |
1661 | #[cfg(feature = "a")] | |
1662 | fn main() { | |
1663 | assert_eq!(std::env::args().nth(1).unwrap(), "b"); | |
1664 | } | |
1665 | "#, | |
1666 | ) | |
1667 | .build(); | |
1668 | ||
1669 | p.cargo("run --features a b").run(); | |
1670 | } | |
bf474ba5 EH |
1671 | |
1672 | #[cargo_test] | |
4d524ea5 EH |
1673 | fn all_features_virtual_ws() { |
1674 | // What happens with `--all-features` in the root of a virtual workspace. | |
1675 | // Some of this behavior is a little strange (member dependencies also | |
1676 | // have all features enabled, one might expect `f4` to be disabled). | |
1677 | let p = project() | |
1678 | .file( | |
1679 | "Cargo.toml", | |
1680 | r#" | |
1681 | [workspace] | |
1682 | members = ["a", "b"] | |
1683 | "#, | |
1684 | ) | |
1685 | .file( | |
1686 | "a/Cargo.toml", | |
1687 | r#" | |
1688 | [package] | |
1689 | name = "a" | |
1690 | version = "0.1.0" | |
1691 | edition = "2018" | |
1692 | ||
1693 | [dependencies] | |
1694 | b = {path="../b", optional=true} | |
1695 | ||
1696 | [features] | |
1697 | default = ["f1"] | |
1698 | f1 = [] | |
1699 | f2 = [] | |
1700 | "#, | |
1701 | ) | |
1702 | .file( | |
1703 | "a/src/main.rs", | |
1704 | r#" | |
1705 | fn main() { | |
1706 | if cfg!(feature="f1") { | |
1707 | println!("f1"); | |
1708 | } | |
1709 | if cfg!(feature="f2") { | |
1710 | println!("f2"); | |
1711 | } | |
1712 | #[cfg(feature="b")] | |
1713 | b::f(); | |
1714 | } | |
1715 | "#, | |
1716 | ) | |
1717 | .file( | |
1718 | "b/Cargo.toml", | |
1719 | r#" | |
1720 | [package] | |
1721 | name = "b" | |
1722 | version = "0.1.0" | |
1723 | ||
1724 | [features] | |
1725 | default = ["f3"] | |
1726 | f3 = [] | |
1727 | f4 = [] | |
1728 | "#, | |
1729 | ) | |
1730 | .file( | |
1731 | "b/src/lib.rs", | |
1732 | r#" | |
1733 | pub fn f() { | |
1734 | if cfg!(feature="f3") { | |
1735 | println!("f3"); | |
1736 | } | |
1737 | if cfg!(feature="f4") { | |
1738 | println!("f4"); | |
1739 | } | |
1740 | } | |
1741 | "#, | |
1742 | ) | |
1743 | .build(); | |
1744 | ||
1745 | p.cargo("run").with_stdout("f1\n").run(); | |
1746 | p.cargo("run --all-features") | |
1747 | .with_stdout("f1\nf2\nf3\nf4\n") | |
1748 | .run(); | |
1749 | // In `a`, it behaves differently. :( | |
1750 | p.cargo("run --all-features") | |
1751 | .cwd("a") | |
1752 | .with_stdout("f1\nf2\nf3\n") | |
1753 | .run(); | |
1754 | } | |
7caa1612 EH |
1755 | |
1756 | #[cargo_test] | |
1757 | fn slash_optional_enables() { | |
1758 | // --features dep/feat will enable `dep` and set its feature. | |
1759 | let p = project() | |
1760 | .file( | |
1761 | "Cargo.toml", | |
1762 | r#" | |
1763 | [package] | |
1764 | name = "foo" | |
1765 | version = "0.1.0" | |
1766 | ||
1767 | [dependencies] | |
1768 | dep = {path="dep", optional=true} | |
1769 | "#, | |
1770 | ) | |
1771 | .file( | |
1772 | "src/lib.rs", | |
1773 | r#" | |
1774 | #[cfg(not(feature="dep"))] | |
1775 | compile_error!("dep not set"); | |
1776 | "#, | |
1777 | ) | |
1778 | .file( | |
1779 | "dep/Cargo.toml", | |
1780 | r#" | |
1781 | [package] | |
1782 | name = "dep" | |
1783 | version = "0.1.0" | |
1784 | ||
1785 | [features] | |
1786 | feat = [] | |
1787 | "#, | |
1788 | ) | |
1789 | .file( | |
1790 | "dep/src/lib.rs", | |
1791 | r#" | |
1792 | #[cfg(not(feature="feat"))] | |
1793 | compile_error!("feat not set"); | |
1794 | "#, | |
1795 | ) | |
1796 | .build(); | |
1797 | ||
1798 | p.cargo("check") | |
1799 | .with_status(101) | |
1800 | .with_stderr_contains("[..]dep not set[..]") | |
1801 | .run(); | |
1802 | ||
1803 | p.cargo("check --features dep/feat").run(); | |
1804 | } | |
ab73b2c3 EH |
1805 | |
1806 | #[cargo_test] | |
1807 | fn registry_summary_order_doesnt_matter() { | |
1808 | // Checks for an issue where the resolver depended on the order of entries | |
1809 | // in the registry summary. If there was a non-optional dev-dependency | |
1810 | // that appeared before an optional normal dependency, then the resolver | |
1811 | // would not activate the optional dependency with a pkg/featname feature | |
1812 | // syntax. | |
1813 | Package::new("dep", "0.1.0") | |
1814 | .feature("feat1", &[]) | |
1815 | .file( | |
1816 | "src/lib.rs", | |
1817 | r#" | |
1818 | #[cfg(feature="feat1")] | |
1819 | pub fn work() { | |
1820 | println!("it works"); | |
1821 | } | |
1822 | "#, | |
1823 | ) | |
1824 | .publish(); | |
1825 | Package::new("bar", "0.1.0") | |
1826 | .feature("bar_feat", &["dep/feat1"]) | |
1827 | .add_dep(Dependency::new("dep", "0.1.0").dev()) | |
1828 | .add_dep(Dependency::new("dep", "0.1.0").optional(true)) | |
1829 | .file( | |
1830 | "src/lib.rs", | |
1831 | r#" | |
1832 | // This will fail to compile without `dep` optional dep activated. | |
1833 | extern crate dep; | |
1834 | ||
1835 | pub fn doit() { | |
1836 | dep::work(); | |
1837 | } | |
1838 | "#, | |
1839 | ) | |
1840 | .publish(); | |
1841 | ||
1842 | let p = project() | |
1843 | .file( | |
1844 | "Cargo.toml", | |
1845 | r#" | |
1846 | [package] | |
1847 | name = "foo" | |
1848 | version = "0.1.0" | |
1849 | edition = "2018" | |
1850 | ||
1851 | [dependencies] | |
1852 | bar = { version="0.1", features = ["bar_feat"] } | |
1853 | "#, | |
1854 | ) | |
1855 | .file( | |
1856 | "src/main.rs", | |
1857 | r#" | |
1858 | fn main() { | |
1859 | bar::doit(); | |
1860 | } | |
1861 | "#, | |
1862 | ) | |
1863 | .build(); | |
1864 | ||
1865 | p.cargo("run") | |
1866 | .with_stderr( | |
1867 | "\ | |
1868 | [UPDATING] [..] | |
1869 | [DOWNLOADING] crates ... | |
1870 | [DOWNLOADED] [..] | |
1871 | [DOWNLOADED] [..] | |
1872 | [COMPILING] dep v0.1.0 | |
1873 | [COMPILING] bar v0.1.0 | |
1874 | [COMPILING] foo v0.1.0 [..] | |
1875 | [FINISHED] [..] | |
1876 | [RUNNING] `target/debug/foo[EXE]` | |
1877 | ", | |
1878 | ) | |
1879 | .with_stdout("it works") | |
1880 | .run(); | |
1881 | } | |
19a95790 AT |
1882 | |
1883 | #[cargo_test] | |
1884 | fn nonexistent_required_features() { | |
1885 | Package::new("required_dependency", "0.1.0") | |
1886 | .feature("simple", &[]) | |
1887 | .publish(); | |
1888 | Package::new("optional_dependency", "0.2.0") | |
1889 | .feature("optional", &[]) | |
1890 | .publish(); | |
1891 | let p = project() | |
1892 | .file( | |
1893 | "Cargo.toml", | |
1894 | r#" | |
1895 | [project] | |
1896 | name = "foo" | |
1897 | version = "0.1.0" | |
1898 | [features] | |
1899 | existing = [] | |
1900 | fancy = ["optional_dependency"] | |
1901 | [dependencies] | |
1902 | required_dependency = { version = "0.1", optional = false} | |
1903 | optional_dependency = { version = "0.2", optional = true} | |
1904 | [[example]] | |
1905 | name = "ololo" | |
1906 | required-features = ["not_present", | |
1907 | "existing", | |
1908 | "fancy", | |
1909 | "required_dependency/not_existing", | |
1910 | "required_dependency/simple", | |
1911 | "optional_dependency/optional", | |
6f8c7d5a EH |
1912 | "not_specified_dependency/some_feature"] |
1913 | "#, | |
19a95790 AT |
1914 | ) |
1915 | .file("src/main.rs", "fn main() {}") | |
1916 | .file("examples/ololo.rs", "fn main() {}") | |
1917 | .build(); | |
1918 | ||
1919 | p.cargo("build --examples") | |
1920 | .with_stderr_contains( | |
bcfdf9fb EH |
1921 | "\ |
1922 | [WARNING] invalid feature `not_present` in required-features of target `ololo`: \ | |
1923 | `not_present` is not present in [features] section | |
1924 | [WARNING] invalid feature `required_dependency/not_existing` in required-features \ | |
1925 | of target `ololo`: feature `not_existing` does not exist in package \ | |
1926 | `required_dependency v0.1.0` | |
1927 | [WARNING] invalid feature `not_specified_dependency/some_feature` in required-features \ | |
1928 | of target `ololo`: dependency `not_specified_dependency` does not exist | |
6f8c7d5a | 1929 | ", |
19a95790 AT |
1930 | ) |
1931 | .run(); | |
1932 | } | |
b731190d EH |
1933 | |
1934 | #[cargo_test] | |
85854b18 | 1935 | fn invalid_feature_names_warning() { |
b731190d EH |
1936 | // Warnings for more restricted feature syntax. |
1937 | let p = project() | |
1938 | .file( | |
1939 | "Cargo.toml", | |
1940 | r#" | |
1941 | [package] | |
1942 | name = "foo" | |
1943 | version = "0.1.0" | |
1944 | ||
1945 | [features] | |
1946 | # Some valid, but unusual names, shouldn't warn. | |
1947 | "c++17" = [] | |
1948 | "128bit" = [] | |
1949 | "_foo" = [] | |
1950 | "feat-name" = [] | |
1951 | "feat_name" = [] | |
ea1a73a1 | 1952 | "foo.bar" = [] |
b731190d EH |
1953 | |
1954 | # Invalid names. | |
1955 | "+foo" = [] | |
1956 | "-foo" = [] | |
1957 | ".foo" = [] | |
b731190d | 1958 | "foo:bar" = [] |
b731190d EH |
1959 | "foo?" = [] |
1960 | "?foo" = [] | |
1961 | "ⒶⒷⒸ" = [] | |
1962 | "a¼" = [] | |
1963 | "#, | |
1964 | ) | |
1965 | .file("src/lib.rs", "") | |
1966 | .build(); | |
1967 | ||
1968 | // Unfortunately the warnings are duplicated due to the Summary being | |
1969 | // loaded twice (once in the Workspace, and once in PackageRegistry) and | |
1970 | // Cargo does not have a de-duplication system. This should probably be | |
1971 | // OK, since I'm not expecting this to affect anyone. | |
1972 | p.cargo("check") | |
1973 | .with_stderr("\ | |
1974 | [WARNING] invalid character `+` in feature `+foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
1975 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
1976 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
1977 | [WARNING] invalid character `-` in feature `-foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
1978 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
1979 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
1980 | [WARNING] invalid character `.` in feature `.foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
1981 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
1982 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
1983 | [WARNING] invalid character `?` in feature `?foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
1984 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
1985 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 1986 | [WARNING] invalid character `¼` in feature `a¼` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
1987 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
1988 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 1989 | [WARNING] invalid character `:` in feature `foo:bar` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
1990 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
1991 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 1992 | [WARNING] invalid character `?` in feature `foo?` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
1993 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
1994 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
1995 | [WARNING] invalid character `Ⓐ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
1996 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
1997 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 1998 | [WARNING] invalid character `Ⓑ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
1999 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
2000 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 2001 | [WARNING] invalid character `Ⓒ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
2002 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
2003 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
2004 | [WARNING] invalid character `+` in feature `+foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
2005 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
2006 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
2007 | [WARNING] invalid character `-` in feature `-foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
2008 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
2009 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
2010 | [WARNING] invalid character `.` in feature `.foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
2011 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
2012 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
2013 | [WARNING] invalid character `?` in feature `?foo` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
2014 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
2015 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 2016 | [WARNING] invalid character `¼` in feature `a¼` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
2017 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
2018 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 2019 | [WARNING] invalid character `:` in feature `foo:bar` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
2020 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
2021 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 2022 | [WARNING] invalid character `?` in feature `foo?` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
2023 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
2024 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
2025 | [WARNING] invalid character `Ⓐ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), the first character must be a Unicode XID start character or digit (most letters or `_` or `0` to `9`) | |
2026 | This was previously accepted but is being phased out; it will become a hard error in a future release. | |
2027 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 2028 | [WARNING] invalid character `Ⓑ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
2029 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
2030 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
ea1a73a1 | 2031 | [WARNING] invalid character `Ⓒ` in feature `ⒶⒷⒸ` in package foo v0.1.0 ([ROOT]/foo), characters must be Unicode XID characters, `+`, or `.` (numbers, `+`, `-`, `_`, `.`, or most letters) |
b731190d EH |
2032 | This was previously accepted but is being phased out; it will become a hard error in a future release. |
2033 | For more information, see issue #8813 <https://github.com/rust-lang/cargo/issues/8813>, and please leave a comment if this will be a problem for your project. | |
2034 | [CHECKING] foo v0.1.0 [..] | |
2035 | [FINISHED] [..] | |
2036 | ") | |
2037 | .run(); | |
2038 | } | |
85854b18 EH |
2039 | |
2040 | #[cargo_test] | |
2041 | fn invalid_feature_names_error() { | |
2042 | // Errors for more restricted feature syntax. | |
2043 | let p = project() | |
2044 | .file( | |
2045 | "Cargo.toml", | |
2046 | r#" | |
2047 | [package] | |
2048 | name = "foo" | |
2049 | version = "0.1.0" | |
2050 | ||
2051 | [features] | |
2052 | "foo/bar" = [] | |
2053 | "#, | |
2054 | ) | |
2055 | .file("src/lib.rs", "") | |
2056 | .build(); | |
2057 | ||
2058 | p.cargo("check") | |
2059 | .with_status(101) | |
2060 | .with_stderr( | |
2061 | "\ | |
2062 | error: failed to parse manifest at `[CWD]/Cargo.toml` | |
2063 | ||
2064 | Caused by: | |
2065 | feature named `foo/bar` is not allowed to contain slashes | |
2066 | ", | |
2067 | ) | |
2068 | .run(); | |
2069 | } |