This repository has been archived on 2023-04-04. You can view files and clone it, but cannot push or open issues or pull requests.
p3l/integration/main.rs

117 lines
2.8 KiB
Rust
Raw Normal View History

2022-10-16 18:14:55 +00:00
#![warn(rust_2018_idioms)]
#![deny(elided_lifetimes_in_paths)]
#![forbid(unsafe_code)]
use compiler::{
compile::{compile, CompileResult},
diagnostic::{Diagnostic, Source}
};
use lazy_regex::regex_replace_all;
use libtest::{run_tests, Arguments, Outcome, Test};
use std::{
fs::{self, File},
io::{Read as _, Write as _},
panic::catch_unwind,
path::{Path, PathBuf}
};
struct TestData {
path: PathBuf
}
fn run_test(data: &TestData) -> anyhow::Result<()> {
let mut file = File::open(&data.path)?;
let mut input = String::new();
file.read_to_string(&mut input)?;
drop(file);
let compile_result = match catch_unwind(|| compile(&input)) {
Ok(result) => result,
Err(e) => match e.downcast_ref::<String>() {
Some(str) => anyhow::bail!("The compiler paniced: {str}"),
None => match e.downcast_ref::<&str>() {
Some(str) => anyhow::bail!("The compiler paniced: {str}"),
None => anyhow::bail!("The compiler paniced")
}
}
};
let msg = match compile_result {
Ok(CompileResult::Ok { .. }) => anyhow::bail!("Code compiled successfully"),
Ok(CompileResult::InternalErr(code, err)) => {
let mut buf = Vec::new();
Diagnostic::ice(err).write(Source::new(&code), &mut buf)?;
String::from_utf8(buf).unwrap()
},
Err(err) => {
let filename = data.path.file_name().unwrap().to_str().unwrap();
let mut buf = Vec::new();
err.write(Source::new(&input).with_filename(filename), &mut buf)?;
String::from_utf8(buf).unwrap()
}
};
// remove colors from the msg
let msg = regex_replace_all!("\x1B\\[[^m]+m", &msg, |_| "");
let mut path = data.path.clone();
path.set_extension("out");
if !path.exists() {
let mut file = File::create(&path)?;
write!(file, "{msg}")?;
Ok(())
} else {
let mut file = File::open(&path)?;
let mut buf = String::new();
file.read_to_string(&mut buf)?;
drop(file);
if msg == buf {
Ok(())
} else {
Err(anyhow::anyhow!(
"Error: Expected output\n\n{buf}\n\nActual output\n\n{msg}"
))
}
}
}
fn add_tests_from_dir<P>(tests: &mut Vec<Test<TestData>>, path: P) -> anyhow::Result<()>
where
P: AsRef<Path>
{
for file in fs::read_dir(path)? {
let file = file?;
let path = file.path();
let ty = file.file_type()?;
if ty.is_dir() {
add_tests_from_dir(tests, &path)?;
} else if ty.is_file()
&& path.extension().map(|ext| ext == "txt").unwrap_or(false)
{
tests.push(Test {
name: path.display().to_string(),
kind: "".into(),
is_ignored: false,
is_bench: false,
data: TestData { path }
});
}
}
Ok(())
}
fn main() -> anyhow::Result<()> {
let args = Arguments::from_args();
let mut tests = Vec::new();
add_tests_from_dir(&mut tests, "integration/fail")?;
run_tests(&args, tests, |test| match run_test(&test.data) {
Ok(()) => Outcome::Passed,
Err(err) => Outcome::Failed {
msg: Some(format!("{err:?}"))
}
})
.exit();
}