]> git.lizzy.rs Git - rust.git/blob - tests/idem.rs
pass single filename instead of full argument list to idem_check
[rust.git] / tests / idem.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![feature(std_misc)]
12
13 extern crate rustfmt;
14
15 use std::collections::HashMap;
16 use std::fs;
17 use std::io::Read;
18 use rustfmt::*;
19
20 // For now, the only supported regression tests are idempotent tests - the input and
21 // output must match exactly.
22 // FIXME(#28) would be good to check for error messages and fail on them, or at least report.
23 #[test]
24 fn idempotent_tests() {
25     println!("Idempotent tests:");
26
27     // Get all files in the tests/idem directory
28     let files = fs::read_dir("tests/idem").unwrap();
29     let files2 = fs::read_dir("tests").unwrap();
30     let files3 = fs::read_dir("src/bin").unwrap();
31     // For each file, run rustfmt and collect the output
32
33     let mut count = 0;
34     let mut fails = 0;
35     for entry in files.chain(files2).chain(files3) {
36         let path = entry.unwrap().path();
37         let file_name = path.to_str().unwrap();
38         if !file_name.ends_with(".rs") {
39             continue;
40         }
41         println!("Testing '{}'...", file_name);
42         match idempotent_check(file_name.to_owned()) {
43             Ok(()) => {},
44             Err(m) => {
45                 print_mismatches(m);
46                 fails += 1;
47             },
48         }
49         count += 1;
50     }
51     // And also dogfood rustfmt!
52     println!("Testing 'src/lib.rs'...");
53     match idempotent_check("src/lib.rs".to_owned()) {
54         Ok(()) => {},
55         Err(m) => {
56             print_mismatches(m);
57             fails += 1;
58         },
59     }
60     count += 1;
61
62     // Display results
63     println!("Ran {} idempotent tests; {} failures.", count, fails);
64     assert!(fails == 0, "{} idempotent tests failed", fails);
65 }
66
67 // Compare output to input.
68 fn print_mismatches(result: HashMap<String, String>) {
69     for (file_name, fmt_text) in result {
70         println!("Mismatch in {}.", file_name);
71         println!("{}", fmt_text);
72     }
73 }
74
75 // Ick, just needed to get a &'static to handle_result.
76 static HANDLE_RESULT: &'static Fn(HashMap<String, String>) = &handle_result;
77
78 pub fn idempotent_check(filename: String) -> Result<(), HashMap<String, String>> {
79     use std::thread;
80     use std::fs;
81     use std::io::Read;
82         let args = vec!["rustfmt".to_owned(), filename];
83     thread::spawn(move || {
84         run(args, WriteMode::Return(HANDLE_RESULT));
85     }).join().map_err(|mut any|
86         any.downcast_mut::<HashMap<String, String>>()
87            .unwrap() // i know it is a hashmap
88            .drain() // i only get a reference :(
89            .collect() // so i need to turn it into an iter and then back
90     )
91 }
92
93 // Compare output to input.
94 fn handle_result(result: HashMap<String, String>) {
95     let mut failures = HashMap::new();
96
97     for (file_name, fmt_text) in result {
98         let mut f = fs::File::open(&file_name).unwrap();
99         let mut text = String::new();
100         // TODO: speedup by running through bytes iterator
101         f.read_to_string(&mut text).unwrap();
102         if fmt_text != text {
103             failures.insert(file_name, fmt_text);
104         }
105     }
106     if !failures.is_empty() {
107         panic!(failures);
108     }
109 }