use crate::{CliArgs, Compiler, ModulePath, SourceCode};
use rand::Rng;
use std::fs;
use std::path;
#[derive(Clone, Debug)]
pub(crate) struct TestSourceCode {
pub(crate) input_file: path::PathBuf,
pub(crate) output_file: path::PathBuf,
in_dir: bool,
}
impl From<&TestSourceCode> for Compiler {
fn from(test_file: &TestSourceCode) -> Self {
Self::try_from(&CliArgs {
input_filename: test_file.input_file.clone(),
output_filename: Some(test_file.output_file.clone()),
..Default::default()
})
.unwrap()
}
}
impl From<&TestSourceCode> for ModulePath {
fn from(tsc: &TestSourceCode) -> Self {
ModulePath::try_from(tsc.input_file.clone()).unwrap()
}
}
impl From<&TestSourceCode> for SourceCode {
fn from(test_file: &TestSourceCode) -> Self {
Self::new(test_file.read_input(), test_file.input_file.clone())
}
}
impl TestSourceCode {
pub(crate) fn new(output_extension: &str, input: &str) -> Self {
let mut rng = rand::thread_rng();
let input_filename = format!("unit_test_input_{}.csvpp", rng.gen::<u64>());
let source_path = path::Path::new(&input_filename);
fs::write(source_path, input).unwrap();
let output_filename = format!("unit_test_output_{}.{output_extension}", rng.gen::<u64>());
let output_path = path::Path::new(&output_filename);
Self {
input_file: source_path.to_path_buf(),
output_file: output_path.to_path_buf(),
in_dir: false,
}
}
pub(crate) fn new_in_dir(output_extension: &str, input: &str) -> Self {
let mut rng = rand::thread_rng();
let dir = rng.gen::<u64>().to_string();
fs::create_dir(&dir).unwrap();
let input_filename = format!("{dir}/unit_test_input_{}.csvpp", rng.gen::<u64>());
let source_path = path::Path::new(&input_filename);
fs::write(source_path, input).unwrap();
let output_filename = format!(
"{dir}/unit_test_output_{}.{output_extension}",
rng.gen::<u64>()
);
let output_path = path::Path::new(&output_filename);
Self {
input_file: source_path.to_path_buf(),
output_file: output_path.to_path_buf(),
in_dir: true,
}
}
#[allow(dead_code)]
pub(crate) fn read_output(&self) -> String {
fs::read_to_string(&self.output_file).unwrap()
}
fn object_code_filename(&self) -> path::PathBuf {
let mut f = self.input_file.clone();
f.set_extension("csvpo");
f
}
fn read_input(&self) -> String {
fs::read_to_string(&self.input_file).unwrap()
}
}
#[allow(unused_must_use)]
impl Drop for TestSourceCode {
fn drop(&mut self) {
fs::remove_file(self.object_code_filename());
fs::remove_file(&self.input_file);
fs::remove_file(&self.output_file);
if self.in_dir {
fs::remove_dir(self.input_file.parent().unwrap()).unwrap();
}
}
}