133 lines
3.9 KiB
Rust
133 lines
3.9 KiB
Rust
#![allow(missing_docs)]
|
|
|
|
use std::collections::HashMap;
|
|
use std::path::Path;
|
|
|
|
use nomo::Context;
|
|
use nomo::functions::FunctionMap;
|
|
|
|
test_each_file::test_each_path! { for ["nomo"] in "./tests/cases/" as cases => check_for_input }
|
|
|
|
test_each_file::test_each_path! { for ["nomo"] in "./tests/errors/" as error_cases => check_errors }
|
|
|
|
#[derive(serde::Serialize)]
|
|
struct Info {
|
|
input: String,
|
|
context: HashMap<String, serde_json::Value>,
|
|
}
|
|
|
|
fn check_for_input([path]: [&Path; 1]) {
|
|
let mut settings = insta::Settings::clone_current();
|
|
settings.set_snapshot_path("cases");
|
|
settings.set_prepend_module_to_snapshot(false);
|
|
|
|
let basename = path.file_stem().unwrap().to_string_lossy();
|
|
let input = std::fs::read_to_string(path).unwrap();
|
|
|
|
let (context, input) = input.split_once("\n---\n").unwrap_or_else(|| ("", &input));
|
|
|
|
let map = if !context.is_empty() {
|
|
serde_json::from_str::<HashMap<String, serde_json::Value>>(context).unwrap()
|
|
} else {
|
|
HashMap::new()
|
|
};
|
|
|
|
settings.set_info(&Info {
|
|
input: input.to_string(),
|
|
context: map.clone(),
|
|
});
|
|
|
|
let mut context = Context::new();
|
|
|
|
for (k, v) in map {
|
|
context.try_insert(k, v).unwrap();
|
|
}
|
|
|
|
let parsed = nomo::lexer::parse(input.into()).unwrap();
|
|
|
|
let _guard = settings.bind_to_scope();
|
|
|
|
insta::assert_debug_snapshot!(format!("{basename}.1-parsed"), parsed);
|
|
|
|
let ast = match nomo::parser::parse(parsed.tokens()) {
|
|
Ok(ast) => ast,
|
|
Err(err) => {
|
|
eprintln!("{}", err.to_report(input));
|
|
panic!("Could not evaluate ast");
|
|
}
|
|
};
|
|
|
|
insta::assert_debug_snapshot!(format!("{basename}.2-ast"), ast);
|
|
|
|
let emit = nomo::compiler::emit_machine(ast);
|
|
|
|
insta::assert_debug_snapshot!(format!("{basename}.3-instructions"), emit);
|
|
|
|
let output = nomo::eval::execute(&FunctionMap::default(), &emit, &context).unwrap();
|
|
|
|
insta::assert_debug_snapshot!(format!("{basename}.4-output"), output);
|
|
}
|
|
|
|
fn check_errors([path]: [&Path; 1]) {
|
|
let mut settings = insta::Settings::clone_current();
|
|
settings.set_snapshot_path("errors");
|
|
settings.set_prepend_module_to_snapshot(false);
|
|
|
|
let basename = path.file_stem().unwrap().to_string_lossy();
|
|
let input = std::fs::read_to_string(path).unwrap();
|
|
|
|
let (context, input) = input.split_once("\n---\n").unwrap_or_else(|| ("", &input));
|
|
|
|
let map = if !context.is_empty() {
|
|
serde_json::from_str::<HashMap<String, serde_json::Value>>(context).unwrap()
|
|
} else {
|
|
HashMap::new()
|
|
};
|
|
|
|
settings.set_info(&Info {
|
|
input: input.to_string(),
|
|
context: map.clone(),
|
|
});
|
|
|
|
let mut context = Context::new();
|
|
|
|
for (k, v) in map {
|
|
context.try_insert(k, v).unwrap();
|
|
}
|
|
|
|
let _guard = settings.bind_to_scope();
|
|
|
|
let parsed = nomo::lexer::parse(input.into()).map_err(|err| err.to_report());
|
|
|
|
match &parsed {
|
|
Ok(parsed) => insta::assert_debug_snapshot!(format!("{basename}.1-parsed"), parsed),
|
|
Err(parsed) => insta::assert_snapshot!(format!("{basename}.1-parsed"), parsed),
|
|
}
|
|
|
|
let Ok(parsed) = parsed else {
|
|
return;
|
|
};
|
|
|
|
let ast = nomo::parser::parse(parsed.tokens()).map_err(|err| err.to_report(input));
|
|
|
|
match &ast {
|
|
Ok(ast) => insta::assert_debug_snapshot!(format!("{basename}.2-ast"), ast),
|
|
Err(ast) => insta::assert_snapshot!(format!("{basename}.2-ast"), ast),
|
|
}
|
|
|
|
let Ok(ast) = ast else {
|
|
return;
|
|
};
|
|
|
|
let emit = nomo::compiler::emit_machine(ast);
|
|
|
|
insta::assert_debug_snapshot!(format!("{basename}.3-instructions"), emit);
|
|
|
|
let output = nomo::eval::execute(&FunctionMap::default(), &emit, &context)
|
|
.map_err(|err| err.to_string());
|
|
|
|
match &output {
|
|
Ok(output) => insta::assert_debug_snapshot!(format!("{basename}.4-output"), output),
|
|
Err(output) => insta::assert_snapshot!(format!("{basename}.4-output"), output),
|
|
}
|
|
}
|