atcoder_util/tester/
run_test.rs

1extern crate colored;
2
3use crate::sample_cases::SampleCases;
4use colored::Colorize;
5use std::io::Write;
6use std::process::{Command, Stdio};
7
8
9/// Code test status.
10#[derive(PartialEq)]
11enum JudgeStatus {
12    AC,
13    WA,
14}
15
16/// This struct represents code test result.
17struct ExecResult {
18    status: JudgeStatus,
19    expected_output: String,
20    actual_output: String,
21}
22
23impl ExecResult {
24    /// Print whether accepted or wrong for each sample cases.
25    fn print_judge_status(&self, case_number: usize) {
26        println!("Case: {}", case_number + 1);
27        print!("Expected Output: {}", self.expected_output);
28        print!("Actual Output:   {}", self.actual_output);
29        if self.status == JudgeStatus::AC {
30            println!("{}", "AC".green());
31        } else {
32            println!("{}", "WA".red());
33        }
34        println!("");
35    }
36}
37
38/// Run a program and validate answer for each sample cases.
39pub fn run_test_all(problem_id: &str) {
40    let program_to_execute = format!("./{}.exe", problem_id);
41    let sc = SampleCases::new_from_files(problem_id);
42
43    for i in 0..sc.input.len() {
44        let result = run_test(
45            &program_to_execute,
46            sc.input.iter().nth(i).unwrap(),
47            sc.output.iter().nth(i).unwrap(),
48        );
49        result.print_judge_status(i);
50    }
51}
52
53/// Run program and check if its output is correct in one sample case.
54fn run_test(program: &str, expected_input: &str, expected_output: &str) -> ExecResult {
55    let mut process = Command::new(program)
56        .stdin(Stdio::piped())
57        .stdout(Stdio::piped())
58        .spawn()
59        .expect("Failed to run program.");
60
61    let process_stdin = process.stdin.as_mut().unwrap();
62    process_stdin.write_all(expected_input.as_bytes()).unwrap();
63    let mut actual_output = String::from_utf8(process.wait_with_output().unwrap().stdout).unwrap();
64    actual_output.retain(|c| c != '\r');
65
66    let status = if *expected_output == actual_output {
67        JudgeStatus::AC
68    }
69    else {
70        JudgeStatus::WA
71    };
72    ExecResult {
73        status,
74        expected_output: expected_output.to_string(),
75        actual_output: actual_output,
76    }
77}