diff options
Diffstat (limited to 'rust/src/tester.rs')
| -rw-r--r-- | rust/src/tester.rs | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/rust/src/tester.rs b/rust/src/tester.rs index 15ca468..019989b 100644 --- a/rust/src/tester.rs +++ b/rust/src/tester.rs @@ -1,15 +1,21 @@ use std::{ - fs, - path::{Path, PathBuf}, + fs::{self, read_to_string, File}, + path::PathBuf, + process::{Command, Stdio}, + time::Instant, }; pub fn main() { - let args: Vec<String> = std::env::args().collect(); + let mut args: Vec<String> = std::env::args().collect(); + // name of the process to run + let proc = args.remove(1); if args.len() > 1 { let run = traverse(&args) - .and_then(|paths| run_test(&paths)) + .and_then(|paths| run_test(&proc, &paths)) .expect("Failed to traverse directory"); println!("{:?}", run) + } else { + println!("Usage: tester <process> <directory>+"); } } @@ -29,20 +35,26 @@ fn traverse(args: &[String]) -> Result<Vec<PathBuf>, String> { } #[derive(Debug)] -struct TestRun { +pub enum TestResult { + TestSucceeded, + TestFailed(String, String), +} + +#[derive(Debug)] +pub struct TestRun { file: String, - test_result: bool, - duration: u64, + test_result: TestResult, + duration: u128, } -fn run_test(files: &Vec<PathBuf>) -> Result<Vec<TestRun>, String> { +fn run_test(proc: &str, files: &Vec<PathBuf>) -> Result<Vec<TestRun>, String> { let mut result = Vec::new(); for file in files { let mut inp = file.clone(); let mut outp = file.clone(); inp.push("input"); outp.push("output"); - let (test_result, duration) = run_test_case(&inp, &outp); + let (test_result, duration) = run_test_case(proc, &inp, &outp)?; result.push(TestRun { file: inp.as_path().to_str().unwrap().to_string(), test_result, @@ -52,6 +64,25 @@ fn run_test(files: &Vec<PathBuf>) -> Result<Vec<TestRun>, String> { Ok(result) } -fn run_test_case(inp: &std::path::PathBuf, outp: &std::path::PathBuf) -> (bool, u64) { - (true, 1) +fn run_test_case( + proc: &str, + inp: &std::path::PathBuf, + outp: &std::path::PathBuf, +) -> Result<(TestResult, u128), String> { + let input = File::open(inp).map_err(|e| e.to_string())?; + let expected = read_to_string(outp).map_err(|e| e.to_string())?; + let start = Instant::now(); + + let actual = Command::new(proc) + .stdin(Stdio::from(input)) + .output() + .map_err(|e| e.to_string())?; + + let duration = (Instant::now() - start).as_millis(); + if expected.as_bytes() == actual.stdout { + Ok((TestResult::TestSucceeded, duration)) + } else { + let actual_string = String::from_utf8(actual.stdout).map_err(|e| e.to_string())?; + Ok((TestResult::TestFailed(expected, actual_string), duration)) + } } |
