]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/fix.rs
Stabilize `edition` key and add `cargo new --edition`
[cargo.git] / tests / testsuite / fix.rs
CommitLineData
6cdee674
AC
1use std::fs::File;
2
3use git2;
4
43b42d6f 5use support::git;
b5ee3635 6use support::is_nightly;
85984a87 7use support::{basic_manifest, project};
b02ba377 8
2bbbca31
JJ
9use std::io::Write;
10
b02ba377
AC
11#[test]
12fn do_not_fix_broken_builds() {
7fe2fbc8 13 let p = project()
b02ba377
AC
14 .file(
15 "src/lib.rs",
16 r#"
17 pub fn foo() {
18 let mut x = 3;
19 drop(x);
20 }
21
22 pub fn foo2() {
23 let _x: u32 = "a";
24 }
25 "#,
85984a87 26 ).build();
b02ba377 27
85984a87
DW
28 p.cargo("fix --allow-no-vcs")
29 .env("__CARGO_FIX_YOLO", "1")
30 .with_status(101)
31 .run();
b02ba377
AC
32 assert!(p.read_file("src/lib.rs").contains("let mut x = 3;"));
33}
34
35#[test]
36fn fix_broken_if_requested() {
7fe2fbc8 37 let p = project()
b02ba377
AC
38 .file(
39 "src/lib.rs",
40 r#"
41 fn foo(a: &u32) -> u32 { a + 1 }
42 pub fn bar() {
43 foo(1);
44 }
45 "#,
85984a87 46 ).build();
b02ba377 47
85984a87
DW
48 p.cargo("fix --allow-no-vcs --broken-code")
49 .env("__CARGO_FIX_YOLO", "1")
50 .run();
b02ba377
AC
51}
52
53#[test]
54fn broken_fixes_backed_out() {
7fe2fbc8 55 let p = project()
b02ba377
AC
56 .file(
57 "foo/Cargo.toml",
58 r#"
59 [package]
60 name = 'foo'
61 version = '0.1.0'
62 [workspace]
63 "#,
85984a87 64 ).file(
b02ba377
AC
65 "foo/src/main.rs",
66 r##"
67 use std::env;
68 use std::fs;
69 use std::io::Write;
70 use std::path::{Path, PathBuf};
71 use std::process::{self, Command};
72
73 fn main() {
74 let is_lib_rs = env::args_os()
75 .map(PathBuf::from)
76 .any(|l| l == Path::new("src/lib.rs"));
77 if is_lib_rs {
78 let path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
79 let path = path.join("foo");
80 if path.exists() {
81 fs::File::create("src/lib.rs")
82 .unwrap()
83 .write_all(b"not rust code")
84 .unwrap();
85 } else {
86 fs::File::create(&path).unwrap();
87 }
88 }
89
90 let status = Command::new("rustc")
91 .args(env::args().skip(1))
92 .status()
93 .expect("failed to run rustc");
94 process::exit(status.code().unwrap_or(2));
95 }
96 "##,
85984a87 97 ).file(
b02ba377
AC
98 "bar/Cargo.toml",
99 r#"
100 [package]
101 name = 'bar'
102 version = '0.1.0'
103 [workspace]
104 "#,
85984a87 105 ).file("bar/build.rs", "fn main() {}")
b02ba377
AC
106 .file(
107 "bar/src/lib.rs",
108 r#"
109 pub fn foo() {
110 let mut x = 3;
111 drop(x);
112 }
113 "#,
85984a87 114 ).build();
b02ba377
AC
115
116 // Build our rustc shim
85984a87 117 p.cargo("build").cwd(p.root().join("foo")).run();
b02ba377
AC
118
119 // Attempt to fix code, but our shim will always fail the second compile
85984a87
DW
120 p.cargo("fix --allow-no-vcs")
121 .cwd(p.root().join("bar"))
122 .env("__CARGO_FIX_YOLO", "1")
123 .env("RUSTC", p.root().join("foo/target/debug/foo"))
124 .with_status(101)
125 .with_stderr_contains("[..]not rust code[..]")
126 .with_stderr_contains(
127 "\
128 warning: failed to automatically apply fixes suggested by rustc \
129 to crate `bar`\n\
130 \n\
131 after fixes were automatically applied the compiler reported \
132 errors within these files:\n\
133 \n \
134 * src/lib.rs\n\
135 \n\
136 This likely indicates a bug in either rustc or cargo itself,\n\
137 and we would appreciate a bug report! You're likely to see \n\
138 a number of compiler warnings after this message which cargo\n\
139 attempted to fix but failed. If you could open an issue at\n\
140 https://github.com/rust-lang/cargo/issues\n\
141 quoting the full output of this command we'd be very appreciative!\
142 ",
143 ).with_stderr_does_not_contain("[..][FIXING][..]")
144 .run();
b02ba377
AC
145}
146
147#[test]
148fn fix_path_deps() {
7fe2fbc8 149 let p = project()
b02ba377
AC
150 .file(
151 "Cargo.toml",
152 r#"
153 [package]
154 name = "foo"
155 version = "0.1.0"
156
157 [dependencies]
158 bar = { path = 'bar' }
159
160 [workspace]
161 "#,
85984a87 162 ).file(
b02ba377
AC
163 "src/lib.rs",
164 r#"
165 extern crate bar;
166
167 pub fn foo() -> u32 {
168 let mut x = 3;
169 x
170 }
171 "#,
85984a87 172 ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
b02ba377
AC
173 .file(
174 "bar/src/lib.rs",
175 r#"
176 pub fn foo() -> u32 {
177 let mut x = 3;
178 x
179 }
180 "#,
85984a87 181 ).build();
b02ba377 182
85984a87
DW
183 p.cargo("fix --allow-no-vcs -p foo -p bar")
184 .env("__CARGO_FIX_YOLO", "1")
185 .with_stdout("")
186 .with_stderr(
187 "\
b02ba377 188[CHECKING] bar v0.1.0 ([..])
05400b80 189[FIXING] bar/src/lib.rs (1 fix)
b02ba377 190[CHECKING] foo v0.1.0 ([..])
05400b80 191[FIXING] src/lib.rs (1 fix)
b02ba377 192[FINISHED] [..]
85984a87
DW
193",
194 ).run();
b02ba377
AC
195}
196
197#[test]
198fn do_not_fix_non_relevant_deps() {
7fe2fbc8 199 let p = project()
252f6e8e 200 .no_manifest()
b02ba377
AC
201 .file(
202 "foo/Cargo.toml",
203 r#"
204 [package]
205 name = "foo"
206 version = "0.1.0"
207
208 [dependencies]
209 bar = { path = '../bar' }
210
211 [workspace]
212 "#,
85984a87 213 ).file("foo/src/lib.rs", "")
ab19c483 214 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
b02ba377
AC
215 .file(
216 "bar/src/lib.rs",
217 r#"
218 pub fn foo() -> u32 {
219 let mut x = 3;
220 x
221 }
222 "#,
85984a87 223 ).build();
b02ba377 224
85984a87
DW
225 p.cargo("fix --allow-no-vcs")
226 .env("__CARGO_FIX_YOLO", "1")
227 .cwd(p.root().join("foo"))
228 .run();
b02ba377
AC
229
230 assert!(p.read_file("bar/src/lib.rs").contains("mut"));
231}
232
233#[test]
234fn prepare_for_2018() {
235 if !is_nightly() {
85984a87 236 return;
b02ba377 237 }
7fe2fbc8 238 let p = project()
b02ba377
AC
239 .file(
240 "src/lib.rs",
241 r#"
242 #![allow(unused)]
243 #![feature(rust_2018_preview)]
244
245 mod foo {
246 pub const FOO: &str = "fooo";
247 }
248
249 mod bar {
250 use ::foo::FOO;
251 }
252
253 fn main() {
254 let x = ::foo::FOO;
255 }
256 "#,
85984a87 257 ).build();
b02ba377
AC
258
259 let stderr = "\
081e7930 260[CHECKING] foo v0.0.1 ([..])
05400b80 261[FIXING] src/lib.rs (2 fixes)
b02ba377
AC
262[FINISHED] [..]
263";
85984a87
DW
264 p.cargo("fix --edition --allow-no-vcs")
265 .with_stderr(stderr)
266 .with_stdout("")
267 .run();
b02ba377
AC
268
269 println!("{}", p.read_file("src/lib.rs"));
270 assert!(p.read_file("src/lib.rs").contains("use crate::foo::FOO;"));
85984a87
DW
271 assert!(
272 p.read_file("src/lib.rs")
273 .contains("let x = crate::foo::FOO;")
274 );
b02ba377
AC
275}
276
277#[test]
278fn local_paths() {
279 if !is_nightly() {
85984a87 280 return;
b02ba377 281 }
7fe2fbc8 282 let p = project()
b02ba377
AC
283 .file(
284 "src/lib.rs",
285 r#"
286 #![feature(rust_2018_preview)]
287
288 use test::foo;
289
290 mod test {
291 pub fn foo() {}
292 }
293
294 pub fn f() {
295 foo();
296 }
297 "#,
85984a87 298 ).build();
b02ba377
AC
299
300 let stderr = "\
081e7930 301[CHECKING] foo v0.0.1 ([..])
05400b80 302[FIXING] src/lib.rs (1 fix)
b02ba377
AC
303[FINISHED] [..]
304";
305
85984a87
DW
306 p.cargo("fix --edition --allow-no-vcs")
307 .with_stderr(stderr)
308 .with_stdout("")
309 .run();
b02ba377
AC
310
311 println!("{}", p.read_file("src/lib.rs"));
312 assert!(p.read_file("src/lib.rs").contains("use crate::test::foo;"));
313}
314
315#[test]
316fn local_paths_no_fix() {
317 if !is_nightly() {
85984a87 318 return;
b02ba377 319 }
7fe2fbc8 320 let p = project()
b02ba377
AC
321 .file(
322 "src/lib.rs",
323 r#"
324 use test::foo;
325
326 mod test {
327 pub fn foo() {}
328 }
329
330 pub fn f() {
331 foo();
332 }
333 "#,
85984a87 334 ).build();
b02ba377
AC
335
336 let stderr = "\
081e7930 337[CHECKING] foo v0.0.1 ([..])
05400b80 338warning: failed to find `#![feature(rust_2018_preview)]` in `src/lib.rs`
fa7a3877
AC
339this may cause `cargo fix` to not be able to fix all
340issues in preparation for the 2018 edition
b02ba377
AC
341[FINISHED] [..]
342";
85984a87
DW
343 p.cargo("fix --edition --allow-no-vcs")
344 .with_stderr(stderr)
345 .with_stdout("")
346 .run();
b02ba377
AC
347}
348
349#[test]
350fn upgrade_extern_crate() {
351 if !is_nightly() {
85984a87 352 return;
b02ba377 353 }
7fe2fbc8 354 let p = project()
b02ba377
AC
355 .file(
356 "Cargo.toml",
357 r#"
b02ba377
AC
358 [package]
359 name = "foo"
360 version = "0.1.0"
361 edition = '2018'
362
363 [workspace]
364
365 [dependencies]
366 bar = { path = 'bar' }
367 "#,
85984a87 368 ).file(
b02ba377
AC
369 "src/lib.rs",
370 r#"
371 #![warn(rust_2018_idioms)]
372 extern crate bar;
373
374 use bar::bar;
375
376 pub fn foo() {
377 ::bar::bar();
378 bar();
379 }
380 "#,
85984a87 381 ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
b02ba377
AC
382 .file("bar/src/lib.rs", "pub fn bar() {}")
383 .build();
384
385 let stderr = "\
386[CHECKING] bar v0.1.0 ([..])
387[CHECKING] foo v0.1.0 ([..])
05400b80 388[FIXING] src/lib.rs (1 fix)
b02ba377
AC
389[FINISHED] [..]
390";
85984a87
DW
391 p.cargo("fix --allow-no-vcs")
392 .env("__CARGO_FIX_YOLO", "1")
85984a87
DW
393 .with_stderr(stderr)
394 .with_stdout("")
395 .run();
b02ba377
AC
396 println!("{}", p.read_file("src/lib.rs"));
397 assert!(!p.read_file("src/lib.rs").contains("extern crate"));
398}
399
400#[test]
401fn specify_rustflags() {
402 if !is_nightly() {
85984a87 403 return;
b02ba377 404 }
7fe2fbc8 405 let p = project()
b02ba377
AC
406 .file(
407 "src/lib.rs",
408 r#"
409 #![allow(unused)]
410 #![feature(rust_2018_preview)]
411
412 mod foo {
413 pub const FOO: &str = "fooo";
414 }
415
416 fn main() {
417 let x = ::foo::FOO;
418 }
419 "#,
85984a87 420 ).build();
b02ba377
AC
421
422 let stderr = "\
081e7930 423[CHECKING] foo v0.0.1 ([..])
05400b80 424[FIXING] src/lib.rs (1 fix)
b02ba377
AC
425[FINISHED] [..]
426";
85984a87
DW
427 p.cargo("fix --edition --allow-no-vcs")
428 .env("RUSTFLAGS", "-C target-cpu=native")
429 .with_stderr(stderr)
430 .with_stdout("")
431 .run();
b02ba377
AC
432}
433
434#[test]
435fn no_changes_necessary() {
85984a87 436 let p = project().file("src/lib.rs", "").build();
b02ba377
AC
437
438 let stderr = "\
081e7930 439[CHECKING] foo v0.0.1 ([..])
b02ba377
AC
440[FINISHED] [..]
441";
85984a87
DW
442 p.cargo("fix --allow-no-vcs")
443 .with_stderr(stderr)
444 .with_stdout("")
445 .run();
b02ba377
AC
446}
447
448#[test]
449fn fixes_extra_mut() {
7fe2fbc8 450 let p = project()
b02ba377
AC
451 .file(
452 "src/lib.rs",
453 r#"
454 pub fn foo() -> u32 {
455 let mut x = 3;
456 x
457 }
458 "#,
85984a87 459 ).build();
b02ba377
AC
460
461 let stderr = "\
081e7930 462[CHECKING] foo v0.0.1 ([..])
05400b80 463[FIXING] src/lib.rs (1 fix)
b02ba377
AC
464[FINISHED] [..]
465";
85984a87
DW
466 p.cargo("fix --allow-no-vcs")
467 .env("__CARGO_FIX_YOLO", "1")
468 .with_stderr(stderr)
469 .with_stdout("")
470 .run();
b02ba377
AC
471}
472
473#[test]
474fn fixes_two_missing_ampersands() {
7fe2fbc8 475 let p = project()
b02ba377
AC
476 .file(
477 "src/lib.rs",
478 r#"
479 pub fn foo() -> u32 {
480 let mut x = 3;
481 let mut y = 3;
482 x + y
483 }
484 "#,
85984a87 485 ).build();
b02ba377
AC
486
487 let stderr = "\
081e7930 488[CHECKING] foo v0.0.1 ([..])
05400b80 489[FIXING] src/lib.rs (2 fixes)
b02ba377
AC
490[FINISHED] [..]
491";
85984a87
DW
492 p.cargo("fix --allow-no-vcs")
493 .env("__CARGO_FIX_YOLO", "1")
494 .with_stderr(stderr)
495 .with_stdout("")
496 .run();
b02ba377
AC
497}
498
499#[test]
500fn tricky() {
7fe2fbc8 501 let p = project()
b02ba377
AC
502 .file(
503 "src/lib.rs",
504 r#"
505 pub fn foo() -> u32 {
506 let mut x = 3; let mut y = 3;
507 x + y
508 }
509 "#,
85984a87 510 ).build();
b02ba377
AC
511
512 let stderr = "\
081e7930 513[CHECKING] foo v0.0.1 ([..])
05400b80 514[FIXING] src/lib.rs (2 fixes)
b02ba377
AC
515[FINISHED] [..]
516";
85984a87
DW
517 p.cargo("fix --allow-no-vcs")
518 .env("__CARGO_FIX_YOLO", "1")
519 .with_stderr(stderr)
520 .with_stdout("")
521 .run();
b02ba377
AC
522}
523
524#[test]
525fn preserve_line_endings() {
7fe2fbc8 526 let p = project()
b02ba377
AC
527 .file(
528 "src/lib.rs",
529 "\
530 fn add(a: &u32) -> u32 { a + 1 }\r\n\
531 pub fn foo() -> u32 { let mut x = 3; add(&x) }\r\n\
532 ",
85984a87 533 ).build();
b02ba377 534
85984a87
DW
535 p.cargo("fix --allow-no-vcs")
536 .env("__CARGO_FIX_YOLO", "1")
537 .run();
b02ba377
AC
538 assert!(p.read_file("src/lib.rs").contains("\r\n"));
539}
540
541#[test]
542fn fix_deny_warnings() {
7fe2fbc8 543 let p = project()
b02ba377
AC
544 .file(
545 "src/lib.rs",
546 "\
547 #![deny(warnings)]
548 pub fn foo() { let mut x = 3; drop(x); }
549 ",
85984a87 550 ).build();
b02ba377 551
85984a87
DW
552 p.cargo("fix --allow-no-vcs")
553 .env("__CARGO_FIX_YOLO", "1")
554 .run();
b02ba377
AC
555}
556
557#[test]
558fn fix_deny_warnings_but_not_others() {
7fe2fbc8 559 let p = project()
b02ba377
AC
560 .file(
561 "src/lib.rs",
562 "
563 #![deny(warnings)]
564
565 pub fn foo() -> u32 {
566 let mut x = 3;
567 x
568 }
569
570 fn bar() {}
571 ",
85984a87 572 ).build();
b02ba377 573
85984a87
DW
574 p.cargo("fix --allow-no-vcs")
575 .env("__CARGO_FIX_YOLO", "1")
576 .run();
b02ba377
AC
577 assert!(!p.read_file("src/lib.rs").contains("let mut x = 3;"));
578 assert!(p.read_file("src/lib.rs").contains("fn bar() {}"));
579}
580
581#[test]
582fn fix_two_files() {
7fe2fbc8 583 let p = project()
b02ba377
AC
584 .file(
585 "src/lib.rs",
586 "
587 pub mod bar;
588
589 pub fn foo() -> u32 {
590 let mut x = 3;
591 x
592 }
593 ",
85984a87 594 ).file(
b02ba377
AC
595 "src/bar.rs",
596 "
597 pub fn foo() -> u32 {
598 let mut x = 3;
599 x
600 }
601
602 ",
85984a87 603 ).build();
b02ba377 604
85984a87
DW
605 p.cargo("fix --allow-no-vcs")
606 .env("__CARGO_FIX_YOLO", "1")
607 .with_stderr_contains("[FIXING] src/bar.rs (1 fix)")
608 .with_stderr_contains("[FIXING] src/lib.rs (1 fix)")
609 .run();
b02ba377
AC
610 assert!(!p.read_file("src/lib.rs").contains("let mut x = 3;"));
611 assert!(!p.read_file("src/bar.rs").contains("let mut x = 3;"));
612}
613
614#[test]
615fn fixes_missing_ampersand() {
7fe2fbc8 616 let p = project()
ca7d9ee2 617 .file("src/main.rs", "fn main() { let mut x = 3; drop(x); }")
b02ba377
AC
618 .file(
619 "src/lib.rs",
620 r#"
621 pub fn foo() { let mut x = 3; drop(x); }
622
623 #[test]
624 pub fn foo2() { let mut x = 3; drop(x); }
625 "#,
85984a87 626 ).file(
b02ba377
AC
627 "tests/a.rs",
628 r#"
629 #[test]
630 pub fn foo() { let mut x = 3; drop(x); }
631 "#,
85984a87 632 ).file("examples/foo.rs", "fn main() { let mut x = 3; drop(x); }")
ca7d9ee2 633 .file("build.rs", "fn main() { let mut x = 3; drop(x); }")
b02ba377
AC
634 .build();
635
85984a87
DW
636 p.cargo("fix --all-targets --allow-no-vcs")
637 .env("__CARGO_FIX_YOLO", "1")
b02ba377 638 .with_stdout("")
081e7930 639 .with_stderr_contains("[COMPILING] foo v0.0.1 ([..])")
b02ba377
AC
640 .with_stderr_contains("[FIXING] build.rs (1 fix)")
641 // Don't assert number of fixes for this one, as we don't know if we're
642 // fixing it once or twice! We run this all concurrently, and if we
643 // compile (and fix) in `--test` mode first, we get two fixes. Otherwise
644 // we'll fix one non-test thing, and then fix another one later in
645 // test mode.
05400b80
DW
646 .with_stderr_contains("[FIXING] src/lib.rs[..]")
647 .with_stderr_contains("[FIXING] src/main.rs (1 fix)")
648 .with_stderr_contains("[FIXING] examples/foo.rs (1 fix)")
649 .with_stderr_contains("[FIXING] tests/a.rs (1 fix)")
85984a87
DW
650 .with_stderr_contains("[FINISHED] [..]").run();
651 p.cargo("build").run();
652 p.cargo("test").run();
b02ba377
AC
653}
654
655#[test]
656fn fix_features() {
7fe2fbc8 657 let p = project()
b02ba377
AC
658 .file(
659 "Cargo.toml",
660 r#"
661 [package]
662 name = "foo"
663 version = "0.1.0"
664
665 [features]
666 bar = []
667
668 [workspace]
669 "#,
85984a87 670 ).file(
b02ba377
AC
671 "src/lib.rs",
672 r#"
673 #[cfg(feature = "bar")]
674 pub fn foo() -> u32 { let mut x = 3; x }
675 "#,
85984a87 676 ).build();
b02ba377 677
85984a87
DW
678 p.cargo("fix --allow-no-vcs").run();
679 p.cargo("build").run();
680 p.cargo("fix --features bar --allow-no-vcs").run();
681 p.cargo("build --features bar").run();
b02ba377
AC
682}
683
684#[test]
685fn shows_warnings() {
7fe2fbc8 686 let p = project()
ca7d9ee2 687 .file("src/lib.rs", "use std::default::Default; pub fn foo() {}")
b02ba377
AC
688 .build();
689
85984a87
DW
690 p.cargo("fix --allow-no-vcs")
691 .with_stderr_contains("[..]warning: unused import[..]")
692 .run();
b02ba377
AC
693}
694
695#[test]
696fn warns_if_no_vcs_detected() {
85984a87 697 let p = project().file("src/lib.rs", "pub fn foo() {}").build();
b02ba377 698
85984a87
DW
699 p.cargo("fix")
700 .with_status(101)
701 .with_stderr(
702 "\
703 error: no VCS found for this project and `cargo fix` can potentially perform \
704 destructive changes; if you'd like to suppress this error pass `--allow-no-vcs`\
705 ",
706 ).run();
707 p.cargo("fix --allow-no-vcs").run();
b02ba377
AC
708}
709
710#[test]
711fn warns_about_dirty_working_directory() {
85984a87 712 let p = project().file("src/lib.rs", "pub fn foo() {}").build();
b02ba377 713
6cdee674
AC
714 let repo = git2::Repository::init(&p.root()).unwrap();
715 let mut cfg = t!(repo.config());
716 t!(cfg.set_str("user.email", "foo@bar.com"));
717 t!(cfg.set_str("user.name", "Foo Bar"));
718 drop(cfg);
719 git::add(&repo);
720 git::commit(&repo);
721 File::create(p.root().join("src/lib.rs")).unwrap();
b02ba377 722
85984a87
DW
723 p.cargo("fix")
724 .with_status(101)
725 .with_stderr(
726 "\
4539ff21
JJ
727error: the working directory of this project has uncommitted changes, \
728and `cargo fix` can potentially perform destructive changes; if you'd \
6a616cb7
JJ
729like to suppress this error pass `--allow-dirty`, `--allow-staged`, or \
730commit the changes to these files:
b02ba377 731
4539ff21 732 * src/lib.rs (dirty)
b02ba377
AC
733
734
85984a87
DW
735",
736 ).run();
737 p.cargo("fix --allow-dirty").run();
b02ba377
AC
738}
739
2bbbca31
JJ
740#[test]
741fn warns_about_staged_working_directory() {
8c2d0dff 742 let p = project().file("src/lib.rs", "pub fn foo() {}").build();
2bbbca31
JJ
743
744 let repo = git2::Repository::init(&p.root()).unwrap();
745 let mut cfg = t!(repo.config());
746 t!(cfg.set_str("user.email", "foo@bar.com"));
747 t!(cfg.set_str("user.name", "Foo Bar"));
748 drop(cfg);
749 git::add(&repo);
750 git::commit(&repo);
751 File::create(&p.root().join("src/lib.rs"))
752 .unwrap()
753 .write_all("pub fn bar() {}".to_string().as_bytes())
754 .unwrap();
755 git::add(&repo);
756
8c2d0dff
DW
757 p.cargo("fix")
758 .with_status(101)
759 .with_stderr(
760 "\
2bbbca31
JJ
761error: the working directory of this project has uncommitted changes, \
762and `cargo fix` can potentially perform destructive changes; if you'd \
763like to suppress this error pass `--allow-dirty`, `--allow-staged`, or \
764commit the changes to these files:
765
766 * src/lib.rs (staged)
767
768
8c2d0dff
DW
769",
770 ).run();
771 p.cargo("fix --allow-staged").run();
2bbbca31
JJ
772}
773
b02ba377
AC
774#[test]
775fn does_not_warn_about_clean_working_directory() {
85984a87 776 let p = project().file("src/lib.rs", "pub fn foo() {}").build();
b02ba377
AC
777
778 let repo = git2::Repository::init(&p.root()).unwrap();
779 let mut cfg = t!(repo.config());
780 t!(cfg.set_str("user.email", "foo@bar.com"));
781 t!(cfg.set_str("user.name", "Foo Bar"));
782 drop(cfg);
783 git::add(&repo);
784 git::commit(&repo);
785
85984a87 786 p.cargo("fix").run();
b02ba377 787}
6cdee674
AC
788
789#[test]
790fn does_not_warn_about_dirty_ignored_files() {
791 let p = project()
ca7d9ee2 792 .file("src/lib.rs", "pub fn foo() {}")
064a1461 793 .file(".gitignore", "bar\n")
6cdee674
AC
794 .build();
795
796 let repo = git2::Repository::init(&p.root()).unwrap();
797 let mut cfg = t!(repo.config());
798 t!(cfg.set_str("user.email", "foo@bar.com"));
799 t!(cfg.set_str("user.name", "Foo Bar"));
800 drop(cfg);
801 git::add(&repo);
802 git::commit(&repo);
064a1461 803 File::create(p.root().join("bar")).unwrap();
6cdee674 804
85984a87 805 p.cargo("fix").run();
6cdee674 806}
ff8a95e2
AC
807
808#[test]
809fn fix_all_targets_by_default() {
810 let p = project()
811 .file("src/lib.rs", "pub fn foo() { let mut x = 3; drop(x); }")
812 .file("tests/foo.rs", "pub fn foo() { let mut x = 3; drop(x); }")
813 .build();
85984a87
DW
814 p.cargo("fix --allow-no-vcs")
815 .env("__CARGO_FIX_YOLO", "1")
816 .run();
ff8a95e2
AC
817 assert!(!p.read_file("src/lib.rs").contains("let mut x"));
818 assert!(!p.read_file("tests/foo.rs").contains("let mut x"));
819}
fa7a3877
AC
820
821#[test]
822fn prepare_for_and_enable() {
823 if !is_nightly() {
85984a87 824 return;
fa7a3877
AC
825 }
826 let p = project()
827 .file(
828 "Cargo.toml",
829 r#"
fa7a3877
AC
830 [package]
831 name = 'foo'
832 version = '0.1.0'
833 edition = '2018'
834 "#,
85984a87 835 ).file("src/lib.rs", "")
fa7a3877
AC
836 .build();
837
838 let stderr = "\
fa7a3877 839error: cannot prepare for the 2018 edition when it is enabled, so cargo cannot
05400b80 840automatically fix errors in `src/lib.rs`
fa7a3877
AC
841
842To prepare for the 2018 edition you should first remove `edition = '2018'` from
843your `Cargo.toml` and then rerun this command. Once all warnings have been fixed
844then you can re-enable the `edition` key in `Cargo.toml`. For some more
845information about transitioning to the 2018 edition see:
846
847 https://[..]
848
849";
85984a87 850 p.cargo("fix --edition --allow-no-vcs")
85984a87
DW
851 .with_stderr_contains(stderr)
852 .with_status(101)
853 .run();
fa7a3877
AC
854}
855
856#[test]
857fn prepare_for_without_feature_issues_warning() {
858 if !is_nightly() {
85984a87 859 return;
fa7a3877 860 }
85984a87 861 let p = project().file("src/lib.rs", "").build();
fa7a3877
AC
862
863 let stderr = "\
864[CHECKING] foo v0.0.1 ([..])
05400b80 865warning: failed to find `#![feature(rust_2018_preview)]` in `src/lib.rs`
fa7a3877
AC
866this may cause `cargo fix` to not be able to fix all
867issues in preparation for the 2018 edition
868[FINISHED] [..]
869";
85984a87
DW
870 p.cargo("fix --edition --allow-no-vcs")
871 .masquerade_as_nightly_cargo()
872 .with_stderr(stderr)
873 .run();
fa7a3877 874}
876a5036
AC
875
876#[test]
877fn fix_overlapping() {
878 if !is_nightly() {
85984a87 879 return;
876a5036
AC
880 }
881 let p = project()
882 .file(
883 "src/lib.rs",
884 r#"
885 #![feature(rust_2018_preview)]
886
887 pub fn foo<T>() {}
888 pub struct A;
889
890 pub mod bar {
891 pub fn baz() {
892 ::foo::<::A>();
893 }
894 }
85984a87
DW
895 "#,
896 ).build();
876a5036
AC
897
898 let stderr = "\
899[CHECKING] foo [..]
05400b80 900[FIXING] src/lib.rs (2 fixes)
876a5036
AC
901[FINISHED] dev [..]
902";
903
85984a87
DW
904 p.cargo("fix --allow-no-vcs --prepare-for 2018 --lib")
905 .with_stderr(stderr)
906 .run();
876a5036
AC
907
908 let contents = p.read_file("src/lib.rs");
909 println!("{}", contents);
910 assert!(contents.contains("crate::foo::<crate::A>()"));
911}
b2b120e9 912
80f9d318
AC
913#[test]
914fn fix_idioms() {
915 if !is_nightly() {
85984a87 916 return;
80f9d318
AC
917 }
918 let p = project()
919 .file(
920 "Cargo.toml",
921 r#"
80f9d318
AC
922 [package]
923 name = 'foo'
924 version = '0.1.0'
925 edition = '2018'
926 "#,
85984a87 927 ).file(
80f9d318
AC
928 "src/lib.rs",
929 r#"
930 use std::any::Any;
931 pub fn foo() {
932 let _x: Box<Any> = Box::new(3);
933 }
85984a87
DW
934 "#,
935 ).build();
80f9d318
AC
936
937 let stderr = "\
938[CHECKING] foo [..]
939[FIXING] src/lib.rs (1 fix)
940[FINISHED] [..]
941";
85984a87 942 p.cargo("fix --edition-idioms --allow-no-vcs")
85984a87
DW
943 .with_stderr(stderr)
944 .with_status(0)
945 .run();
80f9d318
AC
946
947 assert!(p.read_file("src/lib.rs").contains("Box<dyn Any>"));
948}
949
950#[test]
951fn idioms_2015_ok() {
85984a87 952 let p = project().file("src/lib.rs", "").build();
80f9d318 953
85984a87
DW
954 p.cargo("fix --edition-idioms --allow-no-vcs")
955 .masquerade_as_nightly_cargo()
956 .with_status(0)
957 .run();
80f9d318
AC
958}
959
b2b120e9
AC
960#[test]
961fn both_edition_migrate_flags() {
962 if !is_nightly() {
85984a87 963 return;
b2b120e9 964 }
85984a87 965 let p = project().file("src/lib.rs", "").build();
b2b120e9
AC
966
967 let stderr = "\
968error: The argument '--edition' cannot be used with '--prepare-for <prepare-for>'
969
970USAGE:
971 cargo[..] fix --edition --message-format <FMT>
972
973For more information try --help
974";
975
85984a87
DW
976 p.cargo("fix --prepare-for 2018 --edition")
977 .with_status(1)
978 .with_stderr(stderr)
979 .run();
b2b120e9 980}
616e0ad3
PH
981
982#[test]
983fn shows_warnings_on_second_run_without_changes() {
984 let p = project()
985 .file(
986 "src/lib.rs",
987 r#"
988 use std::default::Default;
989
990 pub fn foo() {
991 }
992 "#,
993 )
994 .build();
995
996 p.cargo("fix --allow-no-vcs")
997 .with_stderr_contains("[..]warning: unused import[..]")
998 .run();
999
1000 p.cargo("fix --allow-no-vcs")
1001 .with_stderr_contains("[..]warning: unused import[..]")
1002 .run();
1003}
1004
1005#[test]
1006fn shows_warnings_on_second_run_without_changes_on_multiple_targets() {
1007 let p = project()
1008 .file(
1009 "src/lib.rs",
1010 r#"
1011 use std::default::Default;
1012
1013 pub fn a() -> u32 { 3 }
1014 "#,
1015 )
1016 .file(
1017 "src/main.rs",
1018 r#"
1019 use std::default::Default;
1020 fn main() { println!("3"); }
1021 "#,
1022 )
1023 .file(
1024 "tests/foo.rs",
1025 r#"
1026 use std::default::Default;
1027 #[test]
1028 fn foo_test() {
1029 println!("3");
1030 }
1031 "#,
1032 )
1033 .file(
1034 "tests/bar.rs",
1035 r#"
1036 use std::default::Default;
1037
1038 #[test]
1039 fn foo_test() {
1040 println!("3");
1041 }
1042 "#,
1043 )
1044 .file(
1045 "examples/fooxample.rs",
1046 r#"
1047 use std::default::Default;
1048
1049 fn main() {
1050 println!("3");
1051 }
1052 "#,
1053 )
1054 .build();
1055
1056 p.cargo("fix --allow-no-vcs --all-targets")
1057 .with_stderr_contains(" --> examples/fooxample.rs:2:21")
1058 .with_stderr_contains(" --> src/lib.rs:2:21")
1059 .with_stderr_contains(" --> src/main.rs:2:21")
1060 .with_stderr_contains(" --> tests/bar.rs:2:21")
1061 .with_stderr_contains(" --> tests/foo.rs:2:21")
1062 .run();
1063
1064 p.cargo("fix --allow-no-vcs --all-targets")
1065 .with_stderr_contains(" --> examples/fooxample.rs:2:21")
1066 .with_stderr_contains(" --> src/lib.rs:2:21")
1067 .with_stderr_contains(" --> src/main.rs:2:21")
1068 .with_stderr_contains(" --> tests/bar.rs:2:21")
1069 .with_stderr_contains(" --> tests/foo.rs:2:21")
1070 .run();
1071}
b98ba8e2
DW
1072
1073#[test]
1074fn doesnt_rebuild_dependencies() {
1075 let p = project()
1076 .file(
1077 "Cargo.toml",
1078 r#"
1079 [package]
1080 name = "foo"
1081 version = "0.1.0"
1082
1083 [dependencies]
1084 bar = { path = 'bar' }
1085
1086 [workspace]
1087 "#,
1088 ).file("src/lib.rs", "extern crate bar;")
1089 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1090 .file("bar/src/lib.rs", "")
1091 .build();
1092
1093 p.cargo("fix --allow-no-vcs -p foo")
1094 .env("__CARGO_FIX_YOLO", "1")
1095 .with_stdout("")
7a42790a
DW
1096 .with_stderr("\
1097[CHECKING] bar v0.1.0 ([..])
1098[CHECKING] foo v0.1.0 ([..])
1099[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1100")
b98ba8e2
DW
1101 .run();
1102
1103 p.cargo("fix --allow-no-vcs -p foo")
1104 .env("__CARGO_FIX_YOLO", "1")
1105 .with_stdout("")
7a42790a
DW
1106 .with_stderr("\
1107[CHECKING] foo v0.1.0 ([..])
1108[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1109")
b98ba8e2
DW
1110 .run();
1111}