use std::{fs::create_dir_all, path::PathBuf, time::Duration};
use anyhow::Result;
use crate::{
compile::{compile, Language},
config::{JudgeOptions, TestCase},
exec::execute,
judge::{JudgeResult, JudgeStatus},
};
pub async fn run_test_cases<B, C>(
language: Language,
workspace: B,
source_file_path: B,
options: JudgeOptions,
test_cases: Vec<(C, C)>,
clean: bool,
) -> Result<Vec<JudgeResult>>
where
B: Into<PathBuf>,
C: Into<PathBuf>,
{
let workspace: PathBuf = workspace.into();
if !workspace.exists() {
create_dir_all(&workspace)?;
}
let source_file_path = Into::<PathBuf>::into(source_file_path)
.to_string_lossy()
.to_string();
let exec_path = match &language {
Language::Python => PathBuf::from("python"),
_ => workspace.join("out"),
};
if let Err(e) = compile(
language,
workspace.clone(),
&source_file_path,
exec_path.to_string_lossy(),
)
.await
{
return Ok(vec![JudgeResult {
status: JudgeStatus::CompileError {
message: e.to_string(),
},
time_used: Duration::default(),
memory_used: 0,
}]);
};
let args = vec![source_file_path.as_str()];
let args = match language {
Language::Python => Some(&args),
_ => None,
}
.map(|v| &**v);
let mut results = vec![];
for (input_file, expected_output_file) in test_cases {
results.push(
execute(
&workspace,
exec_path.to_string_lossy(),
args,
&options,
TestCase {
input_file: input_file.into(),
expected_output_file: expected_output_file.into(),
},
workspace.join("test.out"),
)
.await?,
);
}
if clean {
if let Err(e) = std::fs::remove_dir_all(workspace) {
anyhow::bail!("Failed to remove workspace: {}", e);
}
}
Ok(results)
}