]>
Commit | Line | Data |
---|---|---|
6cdee674 AC |
1 | use std::fs::File; |
2 | ||
3 | use git2; | |
4 | ||
43b42d6f | 5 | use support::git; |
b5ee3635 | 6 | use support::is_nightly; |
85984a87 | 7 | use support::{basic_manifest, project}; |
b02ba377 | 8 | |
2bbbca31 JJ |
9 | use std::io::Write; |
10 | ||
b02ba377 AC |
11 | #[test] |
12 | fn 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] | |
36 | fn 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] | |
54 | fn 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] | |
148 | fn 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] | |
198 | fn 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] | |
234 | fn 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] | |
278 | fn 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] | |
316 | fn 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 | 338 | warning: failed to find `#![feature(rust_2018_preview)]` in `src/lib.rs` |
fa7a3877 AC |
339 | this may cause `cargo fix` to not be able to fix all |
340 | issues 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] | |
350 | fn 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] | |
401 | fn 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] | |
435 | fn 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] | |
449 | fn 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] | |
474 | fn 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] | |
500 | fn 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] | |
525 | fn 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] | |
542 | fn 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] | |
558 | fn 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] | |
582 | fn 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] | |
615 | fn 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] | |
656 | fn 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] | |
685 | fn 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] | |
696 | fn 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] | |
711 | fn 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 |
727 | error: the working directory of this project has uncommitted changes, \ |
728 | and `cargo fix` can potentially perform destructive changes; if you'd \ | |
6a616cb7 JJ |
729 | like to suppress this error pass `--allow-dirty`, `--allow-staged`, or \ |
730 | commit 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] |
741 | fn 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 |
761 | error: the working directory of this project has uncommitted changes, \ |
762 | and `cargo fix` can potentially perform destructive changes; if you'd \ | |
763 | like to suppress this error pass `--allow-dirty`, `--allow-staged`, or \ | |
764 | commit 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] |
775 | fn 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] | |
790 | fn 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] | |
809 | fn 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] | |
822 | fn 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 | 839 | error: cannot prepare for the 2018 edition when it is enabled, so cargo cannot |
05400b80 | 840 | automatically fix errors in `src/lib.rs` |
fa7a3877 AC |
841 | |
842 | To prepare for the 2018 edition you should first remove `edition = '2018'` from | |
843 | your `Cargo.toml` and then rerun this command. Once all warnings have been fixed | |
844 | then you can re-enable the `edition` key in `Cargo.toml`. For some more | |
845 | information 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] | |
857 | fn 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 | 865 | warning: failed to find `#![feature(rust_2018_preview)]` in `src/lib.rs` |
fa7a3877 AC |
866 | this may cause `cargo fix` to not be able to fix all |
867 | issues 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] | |
877 | fn 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] |
914 | fn 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] | |
951 | fn 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] |
961 | fn 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 = "\ | |
968 | error: The argument '--edition' cannot be used with '--prepare-for <prepare-for>' | |
969 | ||
970 | USAGE: | |
971 | cargo[..] fix --edition --message-format <FMT> | |
972 | ||
973 | For 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] | |
983 | fn 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] | |
1006 | fn 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] | |
1074 | fn 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 | } |