1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
extern crate rayon;

use rayon::prelude::*;
use rayon::par_iter::collect;

mod types;
pub use types::TestResult;

pub trait Runnable {
    fn run(&self) -> TestResult;
}

mod reporters;
use reporters::{Reporter, CompositeReporter, ProgressReporter, StatisticsReporter};

pub struct TestRunner {
    parallelism: bool,
}

impl TestRunner {
    pub fn new(parallelism: bool) -> TestRunner {
        TestRunner { parallelism: parallelism }
    }

    pub fn run<'run>(&self, tests: &Vec<Box<Runnable + Sync + 'run>>) {
        let reporters: Vec<Box<Reporter>> = vec![Box::new(ProgressReporter::new()),
                                                 Box::new(StatisticsReporter::new())];
        let mut reporter = CompositeReporter::new(reporters);
        reporter.start();

        if self.parallelism {
            let mut results = Vec::with_capacity(tests.len());
            collect::collect_into(tests.into_par_iter()
                                      .map(move |test| test.run()),
                                  &mut results);

            for result in results {
                reporter.record(&result);
            }
        } else {
            for result in tests.into_iter().map(|test| test.run()) {
                reporter.record(&result);
            }
        }

        reporter.report();
    }
}