From a50337a118c3fe9e0f32aa5cf4209b856d1f7bfc Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Sat, 2 May 2015 16:50:33 +0200 Subject: [PATCH] first step to a non-panicking idem_check function --- tests/idem.rs | 75 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/tests/idem.rs b/tests/idem.rs index a82d326087e..72f3277f594 100644 --- a/tests/idem.rs +++ b/tests/idem.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(std_misc)] + extern crate rustfmt; use std::collections::HashMap; use std::fs; use std::io::Read; -use std::sync::atomic; use rustfmt::*; // For now, the only supported regression tests are idempotent tests - the input and @@ -22,52 +23,86 @@ #[test] fn idempotent_tests() { println!("Idempotent tests:"); - FAILURES.store(0, atomic::Ordering::Relaxed); // Get all files in the tests/idem directory let files = fs::read_dir("tests/idem").unwrap(); + let files2 = fs::read_dir("tests").unwrap(); + let files3 = fs::read_dir("src/bin").unwrap(); // For each file, run rustfmt and collect the output + let mut count = 0; - for entry in files { + let mut fails = 0; + for entry in files.chain(files2).chain(files3) { let path = entry.unwrap().path(); let file_name = path.to_str().unwrap(); + if !file_name.ends_with(".rs") { + continue; + } println!("Testing '{}'...", file_name); - run(vec!["rustfmt".to_owned(), file_name.to_owned()], WriteMode::Return(HANDLE_RESULT)); + match idempotent_check(vec!["rustfmt".to_owned(), file_name.to_owned()]) { + Ok(()) => {}, + Err(m) => { + print_mismatches(m); + fails += 1; + }, + } count += 1; } - // And also dogfood ourselves! + // And also dogfood rustfmt! println!("Testing 'src/lib.rs'..."); - run(vec!["rustfmt".to_string(), "src/lib.rs".to_string()], - WriteMode::Return(HANDLE_RESULT)); + match idempotent_check(vec!["rustfmt".to_owned(), "src/lib.rs".to_owned()]) { + Ok(()) => {}, + Err(m) => { + print_mismatches(m); + fails += 1; + }, + } count += 1; // Display results - let fails = FAILURES.load(atomic::Ordering::Relaxed); println!("Ran {} idempotent tests; {} failures.", count, fails); assert!(fails == 0, "{} idempotent tests failed", fails); } -// 'global' used by sys_tests and handle_result. -static FAILURES: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT; +// Compare output to input. +fn print_mismatches(result: HashMap) { + for (file_name, fmt_text) in result { + println!("Mismatch in {}.", file_name); + println!("{}", fmt_text); + } +} + // Ick, just needed to get a &'static to handle_result. static HANDLE_RESULT: &'static Fn(HashMap) = &handle_result; +pub fn idempotent_check(args: Vec) -> Result<(), HashMap> { + use std::thread; + use std::fs; + use std::io::Read; + thread::spawn(move || { + run(args, WriteMode::Return(HANDLE_RESULT)); + }).join().map_err(|mut any| + any.downcast_mut::>() + .unwrap() // i know it is a hashmap + .drain() // i only get a reference :( + .collect() // so i need to turn it into an iter and then back + ) +} + // Compare output to input. fn handle_result(result: HashMap) { - let mut fails = 0; + let mut failures = HashMap::new(); - for file_name in result.keys() { - let mut f = fs::File::open(file_name).unwrap(); + for (file_name, fmt_text) in result { + let mut f = fs::File::open(&file_name).unwrap(); let mut text = String::new(); + // TODO: speedup by running through bytes iterator f.read_to_string(&mut text).unwrap(); - if result[file_name] != text { - fails += 1; - println!("Mismatch in {}.", file_name); - println!("{}", result[file_name]); + if fmt_text != text { + failures.insert(file_name, fmt_text); } } - - if fails > 0 { - FAILURES.fetch_add(1, atomic::Ordering::Relaxed); + if !failures.is_empty() { + panic!(failures); } } \ No newline at end of file -- 2.44.0