]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/features_namespaced.rs
Stabilize namespaced and weak dependency features.
[cargo.git] / tests / testsuite / features_namespaced.rs
CommitLineData
2611f5c7
EH
1//! Tests for namespaced features.
2
85854b18 3use super::features2::switch_to_resolver_2;
bcfdf9fb 4use cargo_test_support::registry::{Dependency, Package};
2a07061b 5use cargo_test_support::{project, publish};
2611f5c7 6
bcfdf9fb
EH
7#[cargo_test]
8fn dependency_with_crate_syntax() {
f4ac82a0 9 // Registry dependency uses dep: syntax.
bcfdf9fb
EH
10 Package::new("baz", "1.0.0").publish();
11 Package::new("bar", "1.0.0")
12 .add_dep(Dependency::new("baz", "1.0").optional(true))
f4ac82a0 13 .feature("feat", &["dep:baz"])
bcfdf9fb
EH
14 .publish();
15 let p = project()
16 .file(
17 "Cargo.toml",
18 r#"
19 [package]
20 name = "foo"
21 version = "0.1.0"
22
23 [dependencies]
24 bar = {version="1.0", features=["feat"]}
25 "#,
26 )
27 .file("src/lib.rs", "")
28 .build();
29
43a063c8 30 p.cargo("check")
bcfdf9fb
EH
31 .with_stderr(
32 "\
33[UPDATING] [..]
34[DOWNLOADING] crates ...
35[DOWNLOADED] [..]
36[DOWNLOADED] [..]
37[CHECKING] baz v1.0.0
38[CHECKING] bar v1.0.0
39[CHECKING] foo v0.1.0 [..]
40[FINISHED] [..]
41",
42 )
43 .run();
44}
45
46#[cargo_test]
47fn namespaced_invalid_feature() {
48 // Specifies a feature that doesn't exist.
49 let p = project()
50 .file(
51 "Cargo.toml",
52 r#"
53 [package]
2611f5c7
EH
54 name = "foo"
55 version = "0.0.1"
56 authors = []
2611f5c7
EH
57
58 [features]
59 bar = ["baz"]
60 "#,
61 )
62 .file("src/main.rs", "")
63 .build();
64
43a063c8 65 p.cargo("build")
2611f5c7
EH
66 .with_status(101)
67 .with_stderr(
68 "\
69[ERROR] failed to parse manifest at `[..]`
70
71Caused by:
bcfdf9fb 72 feature `bar` includes `baz` which is neither a dependency nor another feature
2611f5c7
EH
73",
74 )
75 .run();
76}
77
78#[cargo_test]
79fn namespaced_invalid_dependency() {
f4ac82a0 80 // Specifies a dep:name that doesn't exist.
2611f5c7
EH
81 let p = project()
82 .file(
83 "Cargo.toml",
84 r#"
bcfdf9fb 85 [package]
2611f5c7
EH
86 name = "foo"
87 version = "0.0.1"
2611f5c7
EH
88
89 [features]
f4ac82a0 90 bar = ["dep:baz"]
2611f5c7
EH
91 "#,
92 )
93 .file("src/main.rs", "")
94 .build();
95
43a063c8 96 p.cargo("build")
2611f5c7
EH
97 .with_status(101)
98 .with_stderr(
99 "\
100[ERROR] failed to parse manifest at `[..]`
101
102Caused by:
f4ac82a0 103 feature `bar` includes `dep:baz`, but `baz` is not listed as a dependency
2611f5c7
EH
104",
105 )
106 .run();
107}
108
109#[cargo_test]
110fn namespaced_non_optional_dependency() {
f4ac82a0 111 // Specifies a dep:name for a dependency that is not optional.
2611f5c7
EH
112 let p = project()
113 .file(
114 "Cargo.toml",
115 r#"
bcfdf9fb 116 [package]
2611f5c7
EH
117 name = "foo"
118 version = "0.0.1"
2611f5c7
EH
119
120 [features]
f4ac82a0 121 bar = ["dep:baz"]
2611f5c7
EH
122
123 [dependencies]
124 baz = "0.1"
125 "#,
126 )
127 .file("src/main.rs", "")
128 .build();
129
43a063c8
EH
130 p.cargo("build")
131
2611f5c7
EH
132 .with_status(101)
133 .with_stderr(
134 "\
135[ERROR] failed to parse manifest at `[..]`
136
137Caused by:
f4ac82a0 138 feature `bar` includes `dep:baz`, but `baz` is not an optional dependency
bcfdf9fb 139 A non-optional dependency of the same name is defined; consider adding `optional = true` to its definition.
2611f5c7
EH
140",
141 )
142 .run();
143}
144
145#[cargo_test]
146fn namespaced_implicit_feature() {
bcfdf9fb
EH
147 // Backwards-compatible with old syntax.
148 Package::new("baz", "0.1.0").publish();
149
2611f5c7
EH
150 let p = project()
151 .file(
152 "Cargo.toml",
153 r#"
bcfdf9fb 154 [package]
2611f5c7
EH
155 name = "foo"
156 version = "0.0.1"
2611f5c7
EH
157
158 [features]
159 bar = ["baz"]
160
161 [dependencies]
162 baz = { version = "0.1", optional = true }
163 "#,
164 )
165 .file("src/main.rs", "fn main() {}")
166 .build();
167
43a063c8 168 p.cargo("check")
bcfdf9fb
EH
169 .with_stderr(
170 "\
171[UPDATING] [..]
172[CHECKING] foo v0.0.1 [..]
173[FINISHED] [..]
174",
175 )
176 .run();
43a063c8 177 p.cargo("check --features baz")
bcfdf9fb
EH
178 .with_stderr(
179 "\
180[DOWNLOADING] crates ...
181[DOWNLOADED] baz v0.1.0 [..]
182[CHECKING] baz v0.1.0
183[CHECKING] foo v0.0.1 [..]
184[FINISHED] [..]
185",
186 )
187 .run();
2611f5c7
EH
188}
189
190#[cargo_test]
191fn namespaced_shadowed_dep() {
bcfdf9fb
EH
192 // An optional dependency is not listed in the features table, and its
193 // implicit feature is overridden.
2611f5c7
EH
194 let p = project()
195 .file(
196 "Cargo.toml",
197 r#"
bcfdf9fb 198 [package]
2611f5c7
EH
199 name = "foo"
200 version = "0.0.1"
2611f5c7
EH
201
202 [features]
203 baz = []
204
205 [dependencies]
206 baz = { version = "0.1", optional = true }
207 "#,
208 )
209 .file("src/main.rs", "fn main() {}")
210 .build();
211
43a063c8 212 p.cargo("build")
bcfdf9fb
EH
213 .with_status(101)
214 .with_stderr(
215 "\
2611f5c7
EH
216[ERROR] failed to parse manifest at `[..]`
217
218Caused by:
bcfdf9fb 219 optional dependency `baz` is not included in any feature
f4ac82a0 220 Make sure that `dep:baz` is included in one of features in the [features] table.
2611f5c7 221",
bcfdf9fb 222 )
2611f5c7
EH
223 .run();
224}
225
226#[cargo_test]
227fn namespaced_shadowed_non_optional() {
bcfdf9fb
EH
228 // Able to specify a feature with the same name as a required dependency.
229 Package::new("baz", "0.1.0").publish();
2611f5c7
EH
230 let p = project()
231 .file(
232 "Cargo.toml",
233 r#"
bcfdf9fb 234 [package]
2611f5c7
EH
235 name = "foo"
236 version = "0.0.1"
2611f5c7
EH
237
238 [features]
239 baz = []
240
241 [dependencies]
242 baz = "0.1"
243 "#,
244 )
bcfdf9fb 245 .file("src/lib.rs", "")
2611f5c7
EH
246 .build();
247
43a063c8 248 p.cargo("check").run();
2611f5c7
EH
249}
250
251#[cargo_test]
252fn namespaced_implicit_non_optional() {
bcfdf9fb 253 // Includes a non-optional dependency in [features] table.
2611f5c7
EH
254 let p = project()
255 .file(
256 "Cargo.toml",
257 r#"
bcfdf9fb 258 [package]
2611f5c7
EH
259 name = "foo"
260 version = "0.0.1"
2611f5c7
EH
261
262 [features]
263 bar = ["baz"]
264
265 [dependencies]
266 baz = "0.1"
267 "#,
268 )
269 .file("src/main.rs", "fn main() {}")
270 .build();
271
43a063c8 272 p.cargo("build").with_status(101).with_stderr(
2611f5c7
EH
273 "\
274[ERROR] failed to parse manifest at `[..]`
275
276Caused by:
bcfdf9fb
EH
277 feature `bar` includes `baz`, but `baz` is not an optional dependency
278 A non-optional dependency of the same name is defined; consider adding `optional = true` to its definition.
2611f5c7
EH
279",
280 ).run();
281}
282
283#[cargo_test]
284fn namespaced_same_name() {
bcfdf9fb
EH
285 // Explicitly listing an optional dependency in the [features] table.
286 Package::new("baz", "0.1.0").publish();
287
2611f5c7
EH
288 let p = project()
289 .file(
290 "Cargo.toml",
291 r#"
bcfdf9fb 292 [package]
2611f5c7
EH
293 name = "foo"
294 version = "0.0.1"
2611f5c7
EH
295
296 [features]
f4ac82a0 297 baz = ["dep:baz"]
2611f5c7
EH
298
299 [dependencies]
300 baz = { version = "0.1", optional = true }
301 "#,
302 )
bcfdf9fb
EH
303 .file(
304 "src/main.rs",
305 r#"
306 fn main() {
307 if cfg!(feature="baz") { println!("baz"); }
308 }
309 "#,
310 )
311 .build();
312
43a063c8 313 p.cargo("run")
bcfdf9fb
EH
314 .with_stderr(
315 "\
316[UPDATING] [..]
317[COMPILING] foo v0.0.1 [..]
318[FINISHED] [..]
319[RUNNING] [..]
320",
321 )
322 .with_stdout("")
323 .run();
324
43a063c8 325 p.cargo("run --features baz")
bcfdf9fb
EH
326 .with_stderr(
327 "\
328[DOWNLOADING] crates ...
329[DOWNLOADED] baz v0.1.0 [..]
330[COMPILING] baz v0.1.0
331[COMPILING] foo v0.0.1 [..]
332[FINISHED] [..]
333[RUNNING] [..]
334",
335 )
336 .with_stdout("baz")
337 .run();
338}
339
340#[cargo_test]
341fn no_implicit_feature() {
f4ac82a0 342 // Using `dep:` will not create an implicit feature.
bcfdf9fb
EH
343 Package::new("regex", "1.0.0").publish();
344 Package::new("lazy_static", "1.0.0").publish();
345
346 let p = project()
347 .file(
348 "Cargo.toml",
349 r#"
350 [package]
351 name = "foo"
352 version = "0.1.0"
353
354 [dependencies]
355 regex = { version = "1.0", optional = true }
356 lazy_static = { version = "1.0", optional = true }
357
358 [features]
f4ac82a0 359 regex = ["dep:regex", "dep:lazy_static"]
bcfdf9fb
EH
360 "#,
361 )
362 .file(
363 "src/main.rs",
364 r#"
365 fn main() {
366 if cfg!(feature = "regex") { println!("regex"); }
367 if cfg!(feature = "lazy_static") { println!("lazy_static"); }
368 }
369 "#,
370 )
371 .build();
372
43a063c8 373 p.cargo("run")
bcfdf9fb
EH
374 .with_stderr(
375 "\
376[UPDATING] [..]
377[COMPILING] foo v0.1.0 [..]
378[FINISHED] [..]
379[RUNNING] `target/debug/foo[EXE]`
380",
381 )
382 .with_stdout("")
383 .run();
384
43a063c8 385 p.cargo("run --features regex")
bcfdf9fb
EH
386 .with_stderr_unordered(
387 "\
388[DOWNLOADING] crates ...
389[DOWNLOADED] regex v1.0.0 [..]
390[DOWNLOADED] lazy_static v1.0.0 [..]
391[COMPILING] regex v1.0.0
392[COMPILING] lazy_static v1.0.0
393[COMPILING] foo v0.1.0 [..]
394[FINISHED] [..]
395[RUNNING] `target/debug/foo[EXE]`
396",
397 )
398 .with_stdout("regex")
399 .run();
400
43a063c8 401 p.cargo("run --features lazy_static")
bcfdf9fb
EH
402 .with_stderr(
403 "\
404[ERROR] Package `foo v0.1.0 [..]` does not have feature `lazy_static`. \
f4ac82a0 405It has an optional dependency with that name, but that dependency uses the \"dep:\" \
bcfdf9fb
EH
406syntax in the features table, so it does not have an implicit feature with that name.
407",
408 )
409 .with_status(101)
410 .run();
411}
412
bcfdf9fb
EH
413#[cargo_test]
414fn crate_syntax_bad_name() {
f4ac82a0 415 // "dep:bar" = []
bcfdf9fb
EH
416 Package::new("bar", "1.0.0").publish();
417 let p = project()
418 .file(
419 "Cargo.toml",
420 r#"
421 [package]
422 name = "foo"
423 version = "0.1.0"
424
425 [dependencies]
426 bar = { version="1.0", optional=true }
427
428 [features]
f4ac82a0 429 "dep:bar" = []
bcfdf9fb
EH
430 "#,
431 )
432 .file("src/lib.rs", "")
433 .build();
434
43a063c8 435 p.cargo("check --features dep:bar")
bcfdf9fb
EH
436 .with_status(101)
437 .with_stderr(
438 "\
439[ERROR] failed to parse manifest at [..]/foo/Cargo.toml`
440
441Caused by:
f4ac82a0 442 feature named `dep:bar` is not allowed to start with `dep:`
bcfdf9fb
EH
443",
444 )
445 .run();
446}
447
448#[cargo_test]
449fn crate_syntax_in_dep() {
f4ac82a0 450 // features = ["dep:baz"]
bcfdf9fb
EH
451 Package::new("baz", "1.0.0").publish();
452 Package::new("bar", "1.0.0")
453 .add_dep(Dependency::new("baz", "1.0").optional(true))
454 .publish();
455 let p = project()
456 .file(
457 "Cargo.toml",
458 r#"
459 [package]
460 name = "foo"
461 version = "0.1.0"
462
463 [dependencies]
f4ac82a0 464 bar = { version = "1.0", features = ["dep:baz"] }
bcfdf9fb
EH
465 "#,
466 )
467 .file("src/lib.rs", "")
468 .build();
469
43a063c8 470 p.cargo("check")
bcfdf9fb
EH
471 .with_status(101)
472 .with_stderr(
473 "\
85854b18
EH
474error: failed to parse manifest at `[CWD]/Cargo.toml`
475
476Caused by:
477 feature `dep:baz` in dependency `bar` is not allowed to use explicit `dep:` syntax
478 If you want to enable [..]
bcfdf9fb
EH
479",
480 )
481 .run();
482}
483
484#[cargo_test]
485fn crate_syntax_cli() {
f4ac82a0 486 // --features dep:bar
bcfdf9fb
EH
487 Package::new("bar", "1.0.0").publish();
488 let p = project()
489 .file(
490 "Cargo.toml",
491 r#"
492 [package]
493 name = "foo"
494 version = "0.1.0"
495
496 [dependencies]
497 bar = { version = "1.0", optional=true }
498 "#,
499 )
500 .file("src/lib.rs", "")
501 .build();
502
43a063c8 503 p.cargo("check --features dep:bar")
bcfdf9fb
EH
504 .with_status(101)
505 .with_stderr(
506 "\
85854b18
EH
507[ERROR] feature `dep:bar` is not allowed to use explicit `dep:` syntax
508",
509 )
510 .run();
511
512 switch_to_resolver_2(&p);
43a063c8 513 p.cargo("check --features dep:bar")
85854b18
EH
514 .with_status(101)
515 .with_stderr(
516 "\
517[ERROR] feature `dep:bar` is not allowed to use explicit `dep:` syntax
bcfdf9fb
EH
518",
519 )
520 .run();
521}
522
523#[cargo_test]
524fn crate_required_features() {
f4ac82a0 525 // required-features = ["dep:bar"]
bcfdf9fb
EH
526 Package::new("bar", "1.0.0").publish();
527 let p = project()
528 .file(
529 "Cargo.toml",
530 r#"
531 [package]
532 name = "foo"
533 version = "0.1.0"
534
535 [dependencies]
536 bar = { version = "1.0", optional=true }
537
538 [[bin]]
539 name = "foo"
f4ac82a0 540 required-features = ["dep:bar"]
bcfdf9fb
EH
541 "#,
542 )
2611f5c7
EH
543 .file("src/main.rs", "fn main() {}")
544 .build();
545
43a063c8 546 p.cargo("check")
bcfdf9fb
EH
547 .with_status(101)
548 .with_stderr(
549 "\
550[UPDATING] [..]
f4ac82a0
EH
551[ERROR] invalid feature `dep:bar` in required-features of target `foo`: \
552`dep:` prefixed feature values are not allowed in required-features
bcfdf9fb
EH
553",
554 )
555 .run();
556}
557
558#[cargo_test]
b2cceaf7 559fn json_exposed() {
f4ac82a0 560 // Checks that the implicit dep: values are exposed in JSON.
bcfdf9fb
EH
561 Package::new("bar", "1.0.0").publish();
562 let p = project()
563 .file(
564 "Cargo.toml",
565 r#"
566 [package]
567 name = "foo"
568 version = "0.1.0"
569
570 [dependencies]
571 bar = { version = "1.0", optional=true }
572 "#,
573 )
574 .file("src/lib.rs", "")
575 .build();
576
43a063c8 577 p.cargo("metadata --no-deps")
b2cceaf7
EH
578 .with_json(
579 r#"
580 {
581 "packages": [
582 {
583 "name": "foo",
584 "version": "0.1.0",
585 "id": "foo 0.1.0 [..]",
586 "license": null,
587 "license_file": null,
588 "description": null,
589 "homepage": null,
590 "documentation": null,
591 "source": null,
592 "dependencies": "{...}",
593 "targets": "{...}",
594 "features": {
f4ac82a0 595 "bar": ["dep:bar"]
b2cceaf7
EH
596 },
597 "manifest_path": "[..]foo/Cargo.toml",
598 "metadata": null,
599 "publish": null,
600 "authors": [],
601 "categories": [],
f9a56257 602 "default_run": null,
b2cceaf7
EH
603 "keywords": [],
604 "readme": null,
605 "repository": null,
390af271 606 "rust_version": null,
b2cceaf7
EH
607 "edition": "2015",
608 "links": null
609 }
610 ],
611 "workspace_members": "{...}",
612 "resolve": null,
613 "target_directory": "[..]foo/target",
614 "version": 1,
615 "workspace_root": "[..]foo",
616 "metadata": null
617 }
618 "#,
619 )
bcfdf9fb
EH
620 .run();
621}
622
623#[cargo_test]
624fn crate_feature_with_explicit() {
625 // crate_name/feat_name syntax where crate_name already has a feature defined.
626 // NOTE: I don't know if this is actually ideal behavior.
627 Package::new("bar", "1.0.0")
628 .feature("bar_feat", &[])
629 .file(
630 "src/lib.rs",
631 r#"
632 #[cfg(not(feature="bar_feat"))]
633 compile_error!("bar_feat is not enabled");
634 "#,
635 )
636 .publish();
637 let p = project()
638 .file(
639 "Cargo.toml",
640 r#"
641 [package]
642 name = "foo"
643 version = "0.1.0"
644
645 [dependencies]
646 bar = { version="1.0", optional = true }
647
648 [features]
649 f1 = ["bar/bar_feat"]
f4ac82a0 650 bar = ["dep:bar", "f2"]
bcfdf9fb
EH
651 f2 = []
652 "#,
653 )
654 .file(
655 "src/lib.rs",
656 r#"
657 #[cfg(not(feature="bar"))]
658 compile_error!("bar should be enabled");
659
660 #[cfg(not(feature="f2"))]
661 compile_error!("f2 should be enabled");
662 "#,
663 )
664 .build();
665
43a063c8 666 p.cargo("check --features f1")
bcfdf9fb
EH
667 .with_stderr(
668 "\
669[UPDATING] [..]
670[DOWNLOADING] crates ...
671[DOWNLOADED] bar v1.0.0 [..]
672[CHECKING] bar v1.0.0
673[CHECKING] foo v0.1.0 [..]
674[FINISHED] [..]
675",
676 )
677 .run();
678}
679
680#[cargo_test]
681fn optional_explicit_without_crate() {
682 // "feat" syntax when there is no implicit "feat" feature because it is
683 // explicitly listed elsewhere.
684 Package::new("bar", "1.0.0").publish();
685 let p = project()
686 .file(
687 "Cargo.toml",
688 r#"
689 [package]
690 name = "foo"
691 version = "0.1.0"
692
693 [dependencies]
694 bar = { version = "1.0", optional = true }
695
696 [features]
f4ac82a0 697 feat1 = ["dep:bar"]
bcfdf9fb
EH
698 feat2 = ["bar"]
699 "#,
700 )
701 .file("src/lib.rs", "")
702 .build();
703
43a063c8 704 p.cargo("build")
bcfdf9fb
EH
705 .with_status(101)
706 .with_stderr(
707 "\
708[ERROR] failed to parse manifest at [..]
709
710Caused by:
711 feature `feat2` includes `bar`, but `bar` is an optional dependency without an implicit feature
f4ac82a0 712 Use `dep:bar` to enable the dependency.
bcfdf9fb
EH
713",
714 )
715 .run();
716}
717
718#[cargo_test]
719fn tree() {
720 Package::new("baz", "1.0.0").publish();
721 Package::new("bar", "1.0.0")
722 .add_dep(Dependency::new("baz", "1.0").optional(true))
f4ac82a0 723 .feature("feat1", &["dep:baz"])
bcfdf9fb
EH
724 .feature("feat2", &[])
725 .publish();
726 let p = project()
727 .file(
728 "Cargo.toml",
729 r#"
730 [package]
731 name = "foo"
732 version = "0.1.0"
733
734 [dependencies]
735 bar = { version = "1.0", features = ["feat1"], optional=true }
736
737 [features]
738 a = ["bar/feat2"]
f4ac82a0 739 bar = ["dep:bar"]
bcfdf9fb
EH
740 "#,
741 )
742 .file("src/lib.rs", "")
743 .build();
744
43a063c8 745 p.cargo("tree -e features")
bcfdf9fb
EH
746 .with_stdout("foo v0.1.0 ([ROOT]/foo)")
747 .run();
748
43a063c8 749 p.cargo("tree -e features --features a")
bcfdf9fb
EH
750 .with_stdout(
751 "\
752foo v0.1.0 ([ROOT]/foo)
753├── bar feature \"default\"
754│ └── bar v1.0.0
755│ └── baz feature \"default\"
756│ └── baz v1.0.0
757└── bar feature \"feat1\"
758 └── bar v1.0.0 (*)
759",
760 )
761 .run();
762
43a063c8 763 p.cargo("tree -e features --features a -i bar")
bcfdf9fb
EH
764 .with_stdout(
765 "\
766bar v1.0.0
767├── bar feature \"default\"
768│ └── foo v0.1.0 ([ROOT]/foo)
769│ ├── foo feature \"a\" (command-line)
770│ ├── foo feature \"bar\"
771│ │ └── foo feature \"a\" (command-line)
772│ └── foo feature \"default\" (command-line)
773├── bar feature \"feat1\"
774│ └── foo v0.1.0 ([ROOT]/foo) (*)
775└── bar feature \"feat2\"
776 └── foo feature \"a\" (command-line)
777",
778 )
779 .run();
780
43a063c8 781 p.cargo("tree -e features --features bar")
bcfdf9fb
EH
782 .with_stdout(
783 "\
784foo v0.1.0 ([ROOT]/foo)
785├── bar feature \"default\"
786│ └── bar v1.0.0
787│ └── baz feature \"default\"
788│ └── baz v1.0.0
789└── bar feature \"feat1\"
790 └── bar v1.0.0 (*)
791",
792 )
793 .run();
794
43a063c8 795 p.cargo("tree -e features --features bar -i bar")
bcfdf9fb
EH
796 .with_stdout(
797 "\
798bar v1.0.0
799├── bar feature \"default\"
800│ └── foo v0.1.0 ([ROOT]/foo)
801│ ├── foo feature \"bar\" (command-line)
802│ └── foo feature \"default\" (command-line)
803└── bar feature \"feat1\"
804 └── foo v0.1.0 ([ROOT]/foo) (*)
805",
806 )
807 .run();
2611f5c7 808}
2a07061b 809
85854b18
EH
810#[cargo_test]
811fn tree_no_implicit() {
812 // tree without an implicit feature
813 Package::new("bar", "1.0.0").publish();
814 let p = project()
815 .file(
816 "Cargo.toml",
817 r#"
818 [package]
819 name = "foo"
820 version = "0.1.0"
821
822 [dependencies]
823 bar = { version = "1.0", optional=true }
824
825 [features]
826 a = ["dep:bar"]
827 "#,
828 )
829 .file("src/lib.rs", "")
830 .build();
831
43a063c8 832 p.cargo("tree -e features")
85854b18
EH
833 .with_stdout("foo v0.1.0 ([ROOT]/foo)")
834 .run();
835
43a063c8 836 p.cargo("tree -e features --all-features")
85854b18
EH
837 .with_stdout(
838 "\
839foo v0.1.0 ([ROOT]/foo)
840└── bar feature \"default\"
841 └── bar v1.0.0
842",
843 )
844 .run();
845
43a063c8 846 p.cargo("tree -e features -i bar --all-features")
85854b18
EH
847 .with_stdout(
848 "\
849bar v1.0.0
850└── bar feature \"default\"
851 └── foo v0.1.0 ([ROOT]/foo)
852 └── foo feature \"a\" (command-line)
853",
854 )
855 .run();
856}
857
2a07061b
EH
858#[cargo_test]
859fn publish_no_implicit() {
860 // Does not include implicit features or dep: syntax on publish.
861 Package::new("opt-dep1", "1.0.0").publish();
862 Package::new("opt-dep2", "1.0.0").publish();
863
864 let p = project()
865 .file(
866 "Cargo.toml",
867 r#"
868 [package]
869 name = "foo"
870 version = "0.1.0"
871 description = "foo"
872 license = "MIT"
873 homepage = "https://example.com/"
874
875 [dependencies]
876 opt-dep1 = { version = "1.0", optional = true }
877 opt-dep2 = { version = "1.0", optional = true }
878
879 [features]
880 feat = ["opt-dep1"]
881 "#,
882 )
883 .file("src/lib.rs", "")
884 .build();
885
886 p.cargo("publish --no-verify --token sekrit")
887 .with_stderr(
888 "\
889[UPDATING] [..]
890[PACKAGING] foo v0.1.0 [..]
891[UPLOADING] foo v0.1.0 [..]
892",
893 )
894 .run();
895
896 publish::validate_upload_with_contents(
897 r#"
898 {
899 "authors": [],
900 "badges": {},
901 "categories": [],
902 "deps": [
903 {
904 "default_features": true,
905 "features": [],
906 "kind": "normal",
907 "name": "opt-dep1",
908 "optional": true,
909 "registry": "https://github.com/rust-lang/crates.io-index",
910 "target": null,
911 "version_req": "^1.0"
912 },
913 {
914 "default_features": true,
915 "features": [],
916 "kind": "normal",
917 "name": "opt-dep2",
918 "optional": true,
919 "registry": "https://github.com/rust-lang/crates.io-index",
920 "target": null,
921 "version_req": "^1.0"
922 }
923 ],
924 "description": "foo",
925 "documentation": null,
926 "features": {
927 "feat": ["opt-dep1"]
928 },
929 "homepage": "https://example.com/",
930 "keywords": [],
931 "license": "MIT",
932 "license_file": null,
933 "links": null,
934 "name": "foo",
935 "readme": null,
936 "readme_file": null,
937 "repository": null,
938 "vers": "0.1.0"
939 }
940 "#,
941 "foo-0.1.0.crate",
942 &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"],
943 &[(
944 "Cargo.toml",
b73e3d4f
EH
945 &format!(
946 r#"{}
2a07061b
EH
947[package]
948name = "foo"
949version = "0.1.0"
950description = "foo"
951homepage = "https://example.com/"
952license = "MIT"
953[dependencies.opt-dep1]
954version = "1.0"
955optional = true
956
957[dependencies.opt-dep2]
958version = "1.0"
959optional = true
960
961[features]
962feat = ["opt-dep1"]
963"#,
b73e3d4f
EH
964 cargo::core::package::MANIFEST_PREAMBLE
965 ),
2a07061b
EH
966 )],
967 );
968}
be28b58b
EH
969
970#[cargo_test]
971fn publish() {
972 // Publish behavior with explicit dep: syntax.
973 Package::new("bar", "1.0.0").publish();
974 let p = project()
975 .file(
976 "Cargo.toml",
977 r#"
978 [package]
979 name = "foo"
980 version = "0.1.0"
981 description = "foo"
982 license = "MIT"
983 homepage = "https://example.com/"
984
985 [dependencies]
986 bar = { version = "1.0", optional = true }
987
988 [features]
989 feat1 = []
990 feat2 = ["dep:bar"]
991 feat3 = ["feat2"]
992 "#,
993 )
994 .file("src/lib.rs", "")
995 .build();
996
43a063c8 997 p.cargo("publish --token sekrit")
be28b58b
EH
998 .with_stderr(
999 "\
1000[UPDATING] [..]
1001[PACKAGING] foo v0.1.0 [..]
1002[VERIFYING] foo v0.1.0 [..]
1003[COMPILING] foo v0.1.0 [..]
1004[FINISHED] [..]
1005[UPLOADING] foo v0.1.0 [..]
1006",
1007 )
1008 .run();
1009
1010 publish::validate_upload_with_contents(
1011 r#"
1012 {
1013 "authors": [],
1014 "badges": {},
1015 "categories": [],
1016 "deps": [
1017 {
1018 "default_features": true,
1019 "features": [],
1020 "kind": "normal",
1021 "name": "bar",
1022 "optional": true,
1023 "registry": "https://github.com/rust-lang/crates.io-index",
1024 "target": null,
1025 "version_req": "^1.0"
1026 }
1027 ],
1028 "description": "foo",
1029 "documentation": null,
1030 "features": {
1031 "feat1": [],
1032 "feat2": ["dep:bar"],
1033 "feat3": ["feat2"]
1034 },
1035 "homepage": "https://example.com/",
1036 "keywords": [],
1037 "license": "MIT",
1038 "license_file": null,
1039 "links": null,
1040 "name": "foo",
1041 "readme": null,
1042 "readme_file": null,
1043 "repository": null,
1044 "vers": "0.1.0"
1045 }
1046 "#,
1047 "foo-0.1.0.crate",
1048 &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"],
1049 &[(
1050 "Cargo.toml",
b73e3d4f
EH
1051 &format!(
1052 r#"{}
be28b58b
EH
1053[package]
1054name = "foo"
1055version = "0.1.0"
1056description = "foo"
1057homepage = "https://example.com/"
1058license = "MIT"
1059[dependencies.bar]
1060version = "1.0"
1061optional = true
1062
1063[features]
1064feat1 = []
1065feat2 = ["dep:bar"]
1066feat3 = ["feat2"]
1067"#,
b73e3d4f
EH
1068 cargo::core::package::MANIFEST_PREAMBLE
1069 ),
be28b58b
EH
1070 )],
1071 );
1072}