2023-11-13 14:13:29 +03:00
|
|
|
use hvml::{
|
2024-02-20 20:39:10 +03:00
|
|
|
compile_book, desugar_book,
|
2024-03-11 19:19:03 +03:00
|
|
|
diagnostics::{Diagnostics, DiagnosticsConfig, Severity, ToStringVerbose},
|
2023-11-10 20:08:18 +03:00
|
|
|
net::{hvmc_to_net::hvmc_to_net, net_to_hvmc::net_to_hvmc},
|
2023-09-07 22:26:20 +03:00
|
|
|
run_book,
|
2023-10-12 17:59:57 +03:00
|
|
|
term::{
|
2024-03-11 19:19:03 +03:00
|
|
|
load_book::do_parse_book, net_to_term::net_to_term, parser::parse_term, term_to_compat_net,
|
|
|
|
term_to_net::Labels, AdtEncoding, Book, Ctx, Name, Term,
|
2023-10-12 17:59:57 +03:00
|
|
|
},
|
2024-03-11 19:19:03 +03:00
|
|
|
CompileOpts, RunOpts,
|
2023-09-01 17:52:58 +03:00
|
|
|
};
|
2023-11-10 22:19:06 +03:00
|
|
|
use insta::assert_snapshot;
|
2023-09-08 19:31:32 +03:00
|
|
|
use itertools::Itertools;
|
2023-10-05 23:16:34 +03:00
|
|
|
use std::{
|
2024-01-27 07:34:20 +03:00
|
|
|
collections::HashMap,
|
2024-02-07 18:19:07 +03:00
|
|
|
fmt::Write,
|
2024-03-06 15:41:58 +03:00
|
|
|
io::Read,
|
2024-01-27 07:34:20 +03:00
|
|
|
path::{Path, PathBuf},
|
2024-02-22 20:57:58 +03:00
|
|
|
str::FromStr,
|
2023-10-05 23:16:34 +03:00
|
|
|
};
|
|
|
|
use stdext::function_name;
|
2023-08-31 23:11:19 +03:00
|
|
|
use walkdir::WalkDir;
|
|
|
|
|
2024-03-07 23:51:29 +03:00
|
|
|
fn format_output(output: std::process::Output) -> String {
|
2024-03-11 19:19:03 +03:00
|
|
|
format!("{}{}", String::from_utf8_lossy(&output.stderr), String::from_utf8_lossy(&output.stdout))
|
2024-03-07 23:51:29 +03:00
|
|
|
}
|
|
|
|
|
2023-11-10 20:08:18 +03:00
|
|
|
fn do_parse_term(code: &str) -> Result<Term, String> {
|
|
|
|
parse_term(code).map_err(|errs| errs.into_iter().map(|e| e.to_string()).join("\n"))
|
2023-11-09 21:32:39 +03:00
|
|
|
}
|
|
|
|
|
2023-11-10 20:08:18 +03:00
|
|
|
fn do_parse_net(code: &str) -> Result<hvmc::ast::Net, String> {
|
2024-02-22 20:57:58 +03:00
|
|
|
hvmc::ast::Net::from_str(code)
|
2023-11-09 21:32:39 +03:00
|
|
|
}
|
|
|
|
|
2023-11-13 18:35:00 +03:00
|
|
|
const TESTS_PATH: &str = "/tests/golden_tests/";
|
2023-11-10 22:41:33 +03:00
|
|
|
|
2024-03-12 22:59:30 +03:00
|
|
|
type RunFn = dyn Fn(&str, &Path) -> Result<String, Diagnostics>;
|
|
|
|
|
|
|
|
fn run_single_golden_test(path: &Path, run: &[&RunFn]) -> Result<(), String> {
|
2024-03-11 19:19:03 +03:00
|
|
|
let code = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
|
2023-11-10 22:41:33 +03:00
|
|
|
let file_name = path.to_str().and_then(|path| path.rsplit_once(TESTS_PATH)).unwrap().1;
|
2023-11-10 22:19:06 +03:00
|
|
|
|
2024-01-31 19:50:10 +03:00
|
|
|
// unfortunately we need to do this
|
|
|
|
let file_path = format!("{}{}", &TESTS_PATH[1 ..], file_name);
|
|
|
|
let file_path = Path::new(&file_path);
|
|
|
|
|
2024-03-08 21:28:43 +03:00
|
|
|
let mut results: HashMap<&Path, Vec<String>> = HashMap::new();
|
|
|
|
for fun in run {
|
|
|
|
let result = fun(&code, file_path).unwrap_or_else(|err| err.to_string());
|
|
|
|
results.entry(file_path).or_default().push(result);
|
|
|
|
}
|
|
|
|
let results = results.into_values().map(|v| v.join("\n")).collect_vec();
|
2023-11-13 18:35:00 +03:00
|
|
|
|
|
|
|
let mut settings = insta::Settings::clone_current();
|
|
|
|
settings.set_prepend_module_to_snapshot(false);
|
|
|
|
settings.set_omit_expression(true);
|
|
|
|
settings.set_input_file(path);
|
|
|
|
|
|
|
|
settings.bind(|| {
|
2024-02-22 20:57:58 +03:00
|
|
|
for result in results {
|
|
|
|
assert_snapshot!(file_name, result);
|
|
|
|
}
|
2023-11-13 18:35:00 +03:00
|
|
|
});
|
|
|
|
|
2023-11-10 22:19:06 +03:00
|
|
|
Ok(())
|
2023-08-31 23:11:19 +03:00
|
|
|
}
|
|
|
|
|
2024-03-12 22:59:30 +03:00
|
|
|
fn run_golden_test_dir(test_name: &str, run: &RunFn) {
|
2024-02-22 20:57:58 +03:00
|
|
|
run_golden_test_dir_multiple(test_name, &[run])
|
|
|
|
}
|
|
|
|
|
2024-03-12 22:59:30 +03:00
|
|
|
fn run_golden_test_dir_multiple(test_name: &str, run: &[&RunFn]) {
|
2023-10-05 23:16:34 +03:00
|
|
|
let root = PathBuf::from(format!(
|
2023-11-10 22:41:33 +03:00
|
|
|
"{}{TESTS_PATH}{}",
|
2023-10-05 23:16:34 +03:00
|
|
|
env!("CARGO_MANIFEST_DIR"),
|
2023-11-10 22:19:06 +03:00
|
|
|
test_name.rsplit_once(':').unwrap().1
|
2023-10-05 23:16:34 +03:00
|
|
|
));
|
2023-11-10 22:19:06 +03:00
|
|
|
|
2023-10-05 23:16:34 +03:00
|
|
|
let walker = WalkDir::new(&root).sort_by_file_name().max_depth(2).into_iter().filter_entry(|e| {
|
2023-09-25 18:33:55 +03:00
|
|
|
let path = e.path();
|
2024-03-06 17:54:24 +03:00
|
|
|
path == root || path.is_dir() || (path.is_file() && path.extension().is_some_and(|x| x == "hvm"))
|
2023-09-25 18:33:55 +03:00
|
|
|
});
|
2023-11-10 22:19:06 +03:00
|
|
|
|
2023-09-25 18:33:55 +03:00
|
|
|
for entry in walker {
|
2023-08-31 23:11:19 +03:00
|
|
|
let entry = entry.unwrap();
|
|
|
|
let path = entry.path();
|
2023-09-25 18:33:55 +03:00
|
|
|
if path.is_file() {
|
2024-01-31 14:56:02 +03:00
|
|
|
eprintln!("Testing {}", path.display());
|
2023-08-31 23:11:19 +03:00
|
|
|
run_single_golden_test(path, run).unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2023-11-08 22:26:14 +03:00
|
|
|
fn compile_term() {
|
2024-01-31 19:50:10 +03:00
|
|
|
run_golden_test_dir(function_name!(), &|code, _| {
|
2023-11-09 21:32:39 +03:00
|
|
|
let mut term = do_parse_term(code)?;
|
2024-02-20 16:30:40 +03:00
|
|
|
let mut vec = Vec::new();
|
|
|
|
term.check_unbound_vars(&mut HashMap::new(), &mut vec);
|
|
|
|
|
|
|
|
if !vec.is_empty() {
|
2024-03-11 19:19:03 +03:00
|
|
|
return Err(vec.into_iter().map(|e| e.to_string_verbose(true)).join("\n").into());
|
2024-02-20 16:30:40 +03:00
|
|
|
}
|
|
|
|
|
2023-10-12 22:44:01 +03:00
|
|
|
term.make_var_names_unique();
|
2023-11-10 20:08:18 +03:00
|
|
|
term.linearize_vars();
|
2024-02-22 20:57:58 +03:00
|
|
|
let compat_net = term_to_compat_net(&term, &mut Default::default());
|
2024-03-11 19:19:03 +03:00
|
|
|
let net = net_to_hvmc(&compat_net).map_err(|e| e.to_string_verbose(true))?;
|
2023-11-14 00:25:39 +03:00
|
|
|
|
2024-02-22 20:57:58 +03:00
|
|
|
Ok(format!("{}", net))
|
2023-08-31 23:11:19 +03:00
|
|
|
})
|
|
|
|
}
|
2023-09-01 17:52:58 +03:00
|
|
|
|
|
|
|
#[test]
|
2024-01-19 17:02:22 +03:00
|
|
|
fn compile_file_o_all() {
|
2024-01-31 19:50:10 +03:00
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Warning, true);
|
2024-02-22 20:57:58 +03:00
|
|
|
let mut book = do_parse_book(code, path)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
let res = compile_book(&mut book, CompileOpts::heavy(), diagnostics_cfg, None)?;
|
|
|
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
2023-12-06 21:22:52 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
#[test]
|
2024-01-19 17:02:22 +03:00
|
|
|
fn compile_file() {
|
2024-01-31 19:50:10 +03:00
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Warning, true);
|
2024-02-22 20:57:58 +03:00
|
|
|
let mut book = do_parse_book(code, path)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
let res = compile_book(&mut book, CompileOpts::light(), diagnostics_cfg, None)?;
|
|
|
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
2023-09-05 21:23:23 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2024-02-22 20:57:58 +03:00
|
|
|
fn linear_readback() {
|
2024-01-31 19:50:10 +03:00
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Error, true);
|
2024-01-31 19:50:10 +03:00
|
|
|
let book = do_parse_book(code, path)?;
|
2024-02-22 20:57:58 +03:00
|
|
|
let (res, info) = run_book(
|
|
|
|
book,
|
2024-03-21 14:56:02 +03:00
|
|
|
None,
|
2024-02-22 20:57:58 +03:00
|
|
|
RunOpts { linear: true, ..Default::default() },
|
|
|
|
CompileOpts::heavy(),
|
2024-03-11 19:19:03 +03:00
|
|
|
diagnostics_cfg,
|
2024-02-29 17:26:30 +03:00
|
|
|
None,
|
2024-02-22 20:57:58 +03:00
|
|
|
)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
Ok(format!("{}{}", info.diagnostics, res))
|
2024-02-22 20:57:58 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
fn run_file() {
|
|
|
|
run_golden_test_dir_multiple(function_name!(), &[
|
2024-03-07 23:41:37 +03:00
|
|
|
(&|_code, path| {
|
|
|
|
let output = std::process::Command::new(env!("CARGO_BIN_EXE_hvml"))
|
|
|
|
.args(["run", path.to_str().unwrap(), "-Dall", "-Oall", "-L"])
|
|
|
|
.output()
|
|
|
|
.expect("Run process");
|
|
|
|
|
2024-03-08 21:28:43 +03:00
|
|
|
Ok(format!("Lazy mode:\n{}", format_output(output)))
|
2024-02-22 20:57:58 +03:00
|
|
|
}),
|
2024-03-07 23:41:37 +03:00
|
|
|
(&|_code, path| {
|
|
|
|
let output = std::process::Command::new(env!("CARGO_BIN_EXE_hvml"))
|
|
|
|
.args(["run", path.to_str().unwrap(), "-Dall", "-Oall"])
|
|
|
|
.output()
|
|
|
|
.expect("Run process");
|
|
|
|
|
2024-03-08 21:28:43 +03:00
|
|
|
Ok(format!("Strict mode:\n{}", format_output(output)))
|
2024-02-22 20:57:58 +03:00
|
|
|
}),
|
|
|
|
])
|
2024-02-02 19:43:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn run_lazy() {
|
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig {
|
|
|
|
mutual_recursion_cycle: Severity::Allow,
|
|
|
|
..DiagnosticsConfig::new(Severity::Error, true)
|
|
|
|
};
|
2024-02-02 19:43:14 +03:00
|
|
|
let book = do_parse_book(code, path)?;
|
|
|
|
|
2024-02-02 21:36:26 +03:00
|
|
|
let mut desugar_opts = CompileOpts::heavy();
|
2024-02-02 19:43:14 +03:00
|
|
|
let run_opts = RunOpts::lazy();
|
|
|
|
desugar_opts.lazy_mode();
|
|
|
|
|
|
|
|
// 1 million nodes for the test runtime. Smaller doesn't seem to make it any faster
|
2024-03-21 14:56:02 +03:00
|
|
|
let (res, info) = run_book(book, None, run_opts, desugar_opts, diagnostics_cfg, None)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
Ok(format!("{}{}", info.diagnostics, res))
|
2023-09-18 18:09:59 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn readback_lnet() {
|
2024-01-31 19:50:10 +03:00
|
|
|
run_golden_test_dir(function_name!(), &|code, _| {
|
2023-11-09 21:32:39 +03:00
|
|
|
let net = do_parse_net(code)?;
|
2023-10-24 19:28:59 +03:00
|
|
|
let book = Book::default();
|
2024-02-22 20:57:58 +03:00
|
|
|
let compat_net = hvmc_to_net(&net);
|
2024-03-11 19:19:03 +03:00
|
|
|
let mut diags = Diagnostics::default();
|
|
|
|
let term = net_to_term(&compat_net, &book, &Labels::default(), false, &mut diags);
|
|
|
|
Ok(format!("{}{}", diags, term))
|
2023-09-01 17:52:58 +03:00
|
|
|
})
|
|
|
|
}
|
2023-09-29 22:57:41 +03:00
|
|
|
|
2023-10-27 14:21:19 +03:00
|
|
|
#[test]
|
2024-02-13 22:34:32 +03:00
|
|
|
fn simplify_matches() {
|
2024-01-31 19:50:10 +03:00
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Error, true);
|
2024-02-22 20:57:58 +03:00
|
|
|
let mut book = do_parse_book(code, path)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
|
2024-02-20 20:39:10 +03:00
|
|
|
ctx.check_shared_names();
|
2024-02-29 20:39:30 +03:00
|
|
|
ctx.set_entrypoint();
|
2024-02-13 22:34:32 +03:00
|
|
|
ctx.book.encode_adts(AdtEncoding::TaggedScott);
|
2024-02-20 20:39:10 +03:00
|
|
|
ctx.book.encode_builtins();
|
|
|
|
ctx.book.resolve_ctrs_in_pats();
|
2024-02-13 22:34:32 +03:00
|
|
|
ctx.resolve_refs()?;
|
|
|
|
ctx.check_match_arity()?;
|
|
|
|
ctx.check_unbound_pats()?;
|
|
|
|
ctx.book.convert_match_def_to_term();
|
2024-02-20 20:39:10 +03:00
|
|
|
ctx.book.desugar_let_destructors();
|
|
|
|
ctx.book.desugar_implicit_match_binds();
|
2024-02-13 22:34:32 +03:00
|
|
|
ctx.check_ctrs_arities()?;
|
|
|
|
ctx.check_unbound_vars()?;
|
|
|
|
ctx.simplify_matches()?;
|
2024-03-11 19:19:03 +03:00
|
|
|
ctx.book.linearize_simple_matches(true);
|
2024-02-13 22:34:32 +03:00
|
|
|
ctx.check_unbound_vars()?;
|
|
|
|
ctx.book.make_var_names_unique();
|
|
|
|
ctx.book.linearize_vars();
|
2024-02-20 20:39:10 +03:00
|
|
|
ctx.prune(false, AdtEncoding::TaggedScott);
|
|
|
|
Ok(ctx.book.to_string())
|
2023-10-27 14:21:19 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-01-17 17:40:18 +03:00
|
|
|
#[test]
|
|
|
|
fn parse_file() {
|
2024-01-31 19:50:10 +03:00
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
|
|
|
let book = do_parse_book(code, path)?;
|
2024-01-17 17:40:18 +03:00
|
|
|
Ok(book.to_string())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-11-09 15:30:33 +03:00
|
|
|
#[test]
|
2023-11-23 23:20:02 +03:00
|
|
|
fn encode_pattern_match() {
|
2024-01-31 19:50:10 +03:00
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-02-07 18:19:07 +03:00
|
|
|
let mut result = String::new();
|
|
|
|
for adt_encoding in [AdtEncoding::TaggedScott, AdtEncoding::Scott] {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Error, true);
|
2024-02-22 20:57:58 +03:00
|
|
|
let mut book = do_parse_book(code, path)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
|
2024-02-20 20:39:10 +03:00
|
|
|
ctx.check_shared_names();
|
2024-02-29 20:39:30 +03:00
|
|
|
ctx.set_entrypoint();
|
2024-02-20 20:39:10 +03:00
|
|
|
ctx.book.encode_adts(adt_encoding);
|
|
|
|
ctx.book.encode_builtins();
|
2024-02-13 22:34:32 +03:00
|
|
|
ctx.book.resolve_ctrs_in_pats();
|
|
|
|
ctx.resolve_refs()?;
|
|
|
|
ctx.check_match_arity()?;
|
|
|
|
ctx.check_unbound_pats()?;
|
|
|
|
ctx.book.convert_match_def_to_term();
|
|
|
|
ctx.book.desugar_let_destructors();
|
|
|
|
ctx.book.desugar_implicit_match_binds();
|
|
|
|
ctx.check_ctrs_arities()?;
|
|
|
|
ctx.check_unbound_vars()?;
|
|
|
|
ctx.simplify_matches()?;
|
2024-03-11 19:19:03 +03:00
|
|
|
ctx.book.linearize_simple_matches(true);
|
2024-02-13 22:34:32 +03:00
|
|
|
ctx.book.encode_simple_matches(adt_encoding);
|
|
|
|
ctx.check_unbound_vars()?;
|
|
|
|
ctx.book.make_var_names_unique();
|
|
|
|
ctx.book.linearize_vars();
|
2024-02-20 20:39:10 +03:00
|
|
|
ctx.prune(false, adt_encoding);
|
2024-02-07 18:19:07 +03:00
|
|
|
|
|
|
|
writeln!(result, "{adt_encoding:?}:").unwrap();
|
2024-02-20 20:39:10 +03:00
|
|
|
writeln!(result, "{}\n", ctx.book).unwrap();
|
2024-02-07 18:19:07 +03:00
|
|
|
}
|
|
|
|
Ok(result)
|
2023-11-09 15:30:33 +03:00
|
|
|
})
|
|
|
|
}
|
2024-01-30 17:57:03 +03:00
|
|
|
|
2024-02-02 03:49:46 +03:00
|
|
|
#[test]
|
|
|
|
fn desugar_file() {
|
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Error, true);
|
2024-02-22 20:57:58 +03:00
|
|
|
let mut book = do_parse_book(code, path)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
desugar_book(&mut book, CompileOpts::light(), diagnostics_cfg, None)?;
|
2024-02-02 03:49:46 +03:00
|
|
|
Ok(book.to_string())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-01-30 17:57:03 +03:00
|
|
|
#[test]
|
2024-02-07 18:19:07 +03:00
|
|
|
#[ignore = "to not delay golden tests execution"]
|
2024-01-30 17:57:03 +03:00
|
|
|
fn hangs() {
|
2024-03-06 20:43:32 +03:00
|
|
|
let expected_normalization_time = 5;
|
2024-01-30 17:57:03 +03:00
|
|
|
|
2024-03-12 22:59:30 +03:00
|
|
|
run_golden_test_dir(function_name!(), &move |code, path| {
|
2024-03-12 22:45:31 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Warning, true);
|
2024-01-31 19:50:10 +03:00
|
|
|
let book = do_parse_book(code, path)?;
|
2024-01-30 17:57:03 +03:00
|
|
|
|
2024-03-12 22:45:31 +03:00
|
|
|
let thread = std::thread::spawn(move || {
|
2024-03-21 14:56:02 +03:00
|
|
|
run_book(book, None, RunOpts::default(), CompileOpts::heavy(), diagnostics_cfg, None)
|
2024-01-30 17:57:03 +03:00
|
|
|
});
|
|
|
|
std::thread::sleep(std::time::Duration::from_secs(expected_normalization_time));
|
|
|
|
|
2024-03-12 22:45:31 +03:00
|
|
|
if !thread.is_finished() { Ok("Hangs".into()) } else { Err("Doesn't hang".to_string().into()) }
|
2024-01-30 17:57:03 +03:00
|
|
|
})
|
|
|
|
}
|
2024-02-08 22:14:46 +03:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn compile_entrypoint() {
|
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Error, true);
|
2024-02-08 22:14:46 +03:00
|
|
|
let mut book = do_parse_book(code, path)?;
|
2024-02-22 18:12:26 +03:00
|
|
|
book.entrypoint = Some(Name::from("foo"));
|
2024-03-11 19:19:03 +03:00
|
|
|
let res = compile_book(&mut book, CompileOpts::light(), diagnostics_cfg, None)?;
|
|
|
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
2024-02-08 22:14:46 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn run_entrypoint() {
|
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig::new(Severity::Error, true);
|
2024-02-20 16:30:40 +03:00
|
|
|
let mut book = do_parse_book(code, path)?;
|
2024-02-22 18:12:26 +03:00
|
|
|
book.entrypoint = Some(Name::from("foo"));
|
2024-03-21 14:56:02 +03:00
|
|
|
let (res, info) = run_book(book, None, RunOpts::default(), CompileOpts::heavy(), diagnostics_cfg, None)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
Ok(format!("{}{}", info.diagnostics, res))
|
2024-02-08 22:14:46 +03:00
|
|
|
})
|
|
|
|
}
|
2024-03-06 15:41:58 +03:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn cli() {
|
|
|
|
run_golden_test_dir(function_name!(), &|_code, path| {
|
|
|
|
let mut args_path = PathBuf::from(path);
|
|
|
|
assert!(args_path.set_extension("args"));
|
|
|
|
|
|
|
|
let mut args_buf = String::with_capacity(16);
|
2024-03-11 19:19:03 +03:00
|
|
|
let mut args_file = std::fs::File::open(args_path).expect("File exists");
|
2024-03-06 15:41:58 +03:00
|
|
|
args_file.read_to_string(&mut args_buf).expect("Read args");
|
|
|
|
let args = args_buf.lines();
|
|
|
|
|
2024-03-06 17:54:24 +03:00
|
|
|
let output =
|
2024-03-07 23:41:37 +03:00
|
|
|
std::process::Command::new(env!("CARGO_BIN_EXE_hvml")).args(args).output().expect("Run command");
|
2024-03-06 15:41:58 +03:00
|
|
|
|
2024-03-07 23:51:29 +03:00
|
|
|
Ok(format_output(output))
|
2024-03-06 15:41:58 +03:00
|
|
|
})
|
|
|
|
}
|
2024-03-12 16:10:43 +03:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn mutual_recursion() {
|
|
|
|
run_golden_test_dir(function_name!(), &|code, path| {
|
2024-03-11 19:19:03 +03:00
|
|
|
let diagnostics_cfg = DiagnosticsConfig {
|
|
|
|
mutual_recursion_cycle: Severity::Error,
|
|
|
|
..DiagnosticsConfig::new(Severity::Allow, true)
|
|
|
|
};
|
2024-03-12 16:10:43 +03:00
|
|
|
let mut book = do_parse_book(code, path)?;
|
2024-03-25 20:21:47 +03:00
|
|
|
let mut opts = CompileOpts::light();
|
|
|
|
opts.merge = true;
|
|
|
|
let res = compile_book(&mut book, opts, diagnostics_cfg, None)?;
|
2024-03-11 19:19:03 +03:00
|
|
|
Ok(format!("{}{}", res.diagnostics, res.core_book))
|
2024-03-12 16:10:43 +03:00
|
|
|
})
|
|
|
|
}
|