1 extern crate libtest_mimic;
2
3 use libtest_mimic::{Arguments, Trial, Failed};
4
5 use std::{
6 env,
7 error::Error,
8 ffi::OsStr,
9 fs,
10 path::Path,
11 };
12
13
main() -> Result<(), Box<dyn Error>>14 fn main() -> Result<(), Box<dyn Error>> {
15 let args = Arguments::from_args();
16 let tests = collect_tests()?;
17 libtest_mimic::run(&args, tests).exit();
18 }
19
20 /// Creates one test for each `.rs` file in the current directory or
21 /// sub-directories of the current directory.
collect_tests() -> Result<Vec<Trial>, Box<dyn Error>>22 fn collect_tests() -> Result<Vec<Trial>, Box<dyn Error>> {
23 fn visit_dir(path: &Path, tests: &mut Vec<Trial>) -> Result<(), Box<dyn Error>> {
24 for entry in fs::read_dir(path)? {
25 let entry = entry?;
26 let file_type = entry.file_type()?;
27
28 // Handle files
29 let path = entry.path();
30 if file_type.is_file() {
31 if path.extension() == Some(OsStr::new("rs")) {
32 let name = path
33 .strip_prefix(env::current_dir()?)?
34 .display()
35 .to_string();
36
37 let test = Trial::test(name, move || check_file(&path))
38 .with_kind("tidy");
39 tests.push(test);
40 }
41 } else if file_type.is_dir() {
42 // Handle directories
43 visit_dir(&path, tests)?;
44 }
45 }
46
47 Ok(())
48 }
49
50 // We recursively look for `.rs` files, starting from the current
51 // directory.
52 let mut tests = Vec::new();
53 let current_dir = env::current_dir()?;
54 visit_dir(¤t_dir, &mut tests)?;
55
56 Ok(tests)
57 }
58
59 /// Performs a couple of tidy tests.
check_file(path: &Path) -> Result<(), Failed>60 fn check_file(path: &Path) -> Result<(), Failed> {
61 let content = fs::read(path).map_err(|e| format!("Cannot read file: {e}"))?;
62
63 // Check that the file is valid UTF-8
64 let content = String::from_utf8(content)
65 .map_err(|_| "The file's contents are not a valid UTF-8 string!")?;
66
67 // Check for `\r`: we only want `\n` line breaks!
68 if content.contains('\r') {
69 return Err("Contains '\\r' chars. Please use ' \\n' line breaks only!".into());
70 }
71
72 // Check for tab characters `\t`
73 if content.contains('\t') {
74 return Err("Contains tab characters ('\\t'). Indent with four spaces!".into());
75 }
76
77 // Check for too long lines
78 if content.lines().any(|line| line.chars().count() > 100) {
79 return Err("Contains lines longer than 100 codepoints!".into());
80 }
81
82 Ok(())
83 }
84