use mun_compiler::{Config, DisplayColor, PathOrInline, RelativePathBuf};
use mun_runtime::Runtime;
#[derive(Copy, Clone)]
pub enum TestMode {
CompileAndRun,
Compile,
ShouldNotCompile,
}
impl TestMode {
fn should_compile(self) -> bool {
matches!(self, TestMode::CompileAndRun | TestMode::Compile)
}
fn should_run(self) -> bool {
matches!(self, TestMode::CompileAndRun)
}
}
#[allow(clippy::let_unit_value)]
pub fn run_test(code: &str, mode: TestMode) {
let out_dir = tempdir::TempDir::new("mun_test_")
.expect("could not create temporary directory for test output");
let (mut driver, file_id) = mun_compiler::Driver::with_file(
Config {
out_dir: Some(out_dir.path().to_path_buf()),
..Config::default()
},
PathOrInline::Inline {
rel_path: RelativePathBuf::from("mod.mun"),
contents: code.to_owned(),
},
)
.expect("unable to create driver from test input");
let compiler_errors = driver
.emit_diagnostics_to_string(DisplayColor::Auto)
.expect("error emitting errors");
match (compiler_errors, mode.should_compile()) {
(Some(errors), true) => {
panic!("code contains compiler errors:\n{}", errors);
}
(None, false) => {
panic!("Code that should have caused the error compiled successfully");
}
_ => (),
};
if !mode.should_run() {
return;
}
driver
.write_all_assemblies(true)
.expect("error emitting assemblies");
let assembly_path = driver.assembly_output_path_from_file(file_id);
let builder = Runtime::builder(assembly_path);
let runtime = unsafe { builder.finish() }.expect("error creating runtime for test assembly");
if runtime.get_function_definition("main").is_none() {
panic!("Could not find `main` function");
}
let _: () = runtime
.invoke("main", ())
.expect("error calling main function");
}