]> git.proxmox.com Git - cargo.git/blob - tests/internal.rs
store jobs priorities in the pending queue
[cargo.git] / tests / internal.rs
1 //! Tests for internal code checks.
2
3 #![allow(clippy::all)]
4
5 use std::fs;
6
7 #[test]
8 fn check_forbidden_code() {
9 // Do not use certain macros, functions, etc.
10 if !cargo_util::is_ci() {
11 // Only check these on CI, otherwise it could be annoying.
12 use std::io::Write;
13 writeln!(
14 std::io::stderr(),
15 "\nSkipping check_forbidden_code test, set CI=1 to enable"
16 )
17 .unwrap();
18 return;
19 }
20 let root_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
21 for entry in walkdir::WalkDir::new(&root_path)
22 .into_iter()
23 .filter_entry(|e| e.path() != root_path.join("doc"))
24 .filter_map(|e| e.ok())
25 {
26 let path = entry.path();
27 if !entry
28 .file_name()
29 .to_str()
30 .map(|s| s.ends_with(".rs"))
31 .unwrap_or(false)
32 {
33 continue;
34 }
35 eprintln!("checking {}", path.display());
36 let c = fs::read_to_string(path).unwrap();
37 for (line_index, line) in c.lines().enumerate() {
38 if line.trim().starts_with("//") {
39 continue;
40 }
41 if line_has_print(line) {
42 if entry.file_name().to_str().unwrap() == "cargo_new.rs" && line.contains("Hello") {
43 // An exception.
44 continue;
45 }
46 panic!(
47 "found print macro in {}:{}\n\n{}\n\n\
48 print! macros should not be used in Cargo because they can panic.\n\
49 Use one of the drop_print macros instead.\n\
50 ",
51 path.display(),
52 line_index,
53 line
54 );
55 }
56 if line_has_macro(line, "dbg") {
57 panic!(
58 "found dbg! macro in {}:{}\n\n{}\n\n\
59 dbg! should not be used outside of debugging.",
60 path.display(),
61 line_index,
62 line
63 );
64 }
65 }
66 }
67 }
68
69 fn line_has_print(line: &str) -> bool {
70 line_has_macro(line, "print")
71 || line_has_macro(line, "eprint")
72 || line_has_macro(line, "println")
73 || line_has_macro(line, "eprintln")
74 }
75
76 #[test]
77 fn line_has_print_works() {
78 assert!(line_has_print("print!"));
79 assert!(line_has_print("println!"));
80 assert!(line_has_print("eprint!"));
81 assert!(line_has_print("eprintln!"));
82 assert!(line_has_print("(print!(\"hi!\"))"));
83 assert!(!line_has_print("print"));
84 assert!(!line_has_print("i like to print things"));
85 assert!(!line_has_print("drop_print!"));
86 assert!(!line_has_print("drop_println!"));
87 assert!(!line_has_print("drop_eprint!"));
88 assert!(!line_has_print("drop_eprintln!"));
89 }
90
91 fn line_has_macro(line: &str, mac: &str) -> bool {
92 for (i, _) in line.match_indices(mac) {
93 if line.get(i + mac.len()..i + mac.len() + 1) != Some("!") {
94 continue;
95 }
96 if i == 0 {
97 return true;
98 }
99 // Check for identifier boundary start.
100 let prev1 = line.get(i - 1..i).unwrap().chars().next().unwrap();
101 if prev1.is_alphanumeric() || prev1 == '_' {
102 continue;
103 }
104 return true;
105 }
106 false
107 }