autogenerate test suite

This commit is contained in:
Moritz Gmeiner 2024-09-02 15:35:28 +02:00
commit 274faf1e0a
7 changed files with 332 additions and 1732 deletions

View file

@ -8,7 +8,7 @@ edition = "2021"
[dependencies.rlox2-frontend] [dependencies.rlox2-frontend]
path = "../frontend" path = "../frontend"
[dev-dependencies] [build-dependencies]
glob = "0.3" glob = "0.3"
[dependencies] [dependencies]

48
interpreter/build.rs Normal file
View file

@ -0,0 +1,48 @@
use std::path::PathBuf;
use glob::glob;
fn main() {
generate_tests();
}
fn build_test_case(path: PathBuf) -> String {
let mut test_name = path.clone();
test_name.set_extension("");
let mut components = test_name.components();
components.next();
components.next();
let mut test_name = components.as_path().to_str().unwrap().to_owned();
test_name = test_name.replace('/', "_");
format!(
"\n\n#[test]
fn test_{}() {{
run_test(\"{}\");
}}",
test_name,
path.to_str().unwrap()
)
}
fn generate_tests() {
let preamble = "mod common;\n\nuse common::run_test;";
let mut output = preamble.to_owned();
for lox_file in glob("tests/lox/**/*.lox").unwrap() {
let lox_file = lox_file.unwrap();
println!("found lox file: {}", lox_file.to_str().unwrap());
output += &build_test_case(lox_file);
}
println!("{output}");
std::fs::write("tests/all_tests.rs", output).unwrap();
}

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,8 @@ use rlox2_interpreter::{run, Runtime};
#[cfg(test)] #[cfg(test)]
pub fn run_test(path: impl Into<PathBuf>) { pub fn run_test(path: impl Into<PathBuf>) {
use smol_str::SmolStr;
let path = &path.into(); let path = &path.into();
// path.insert_str(0, "./tests/lox/"); // path.insert_str(0, "./tests/lox/");
@ -15,26 +17,30 @@ pub fn run_test(path: impl Into<PathBuf>) {
let tokens = rlox2_frontend::lexer::scan_tokens(&source).unwrap(); let tokens = rlox2_frontend::lexer::scan_tokens(&source).unwrap();
let comments: Vec<String> = tokens let comments: Result<Vec<String>, SmolStr> =
.into_iter() tokens.into_iter().try_fold(Vec::new(), |mut acc, token| {
.filter_map(|token| {
if let TokenType::Comment(s) = token.token_type { if let TokenType::Comment(s) = token.token_type {
if s.starts_with(" expect: ") { if s.contains("Error") || s.contains("error") {
Some(s.strip_prefix(" expect: ").unwrap().trim().to_owned()) return Err(s);
} else if s.contains("Error") || s.contains("error") { } else if s.starts_with(" expect: ") {
Some(s.trim().into()) acc.push(s.trim().strip_prefix("expect:").unwrap().trim().to_owned());
} else {
None
} }
} else {
None
} }
})
.collect();
Ok(acc)
});
match comments {
Ok(ref comments) => {
println!("Expecting positive result");
for comment in comments.iter() { for comment in comments.iter() {
println!("Comment: \"{comment}\"") println!("Comment: \"{comment}\"")
} }
}
Err(ref e) => {
println!("Expecting error: {e}");
}
}
print!("\n\n"); print!("\n\n");
@ -51,17 +57,17 @@ pub fn run_test(path: impl Into<PathBuf>) {
Err(e) => { Err(e) => {
println!("{e}"); println!("{e}");
assert_eq!(comments.len(), 1); assert!(comments.is_err());
let comment = &*comments[0];
assert!(comment.to_lowercase().contains("error"));
return; return;
} }
} }
} }
let Ok(comments) = comments else {
panic!("Positive outcome, but expected error");
};
let mut output = output.as_ref().borrow_mut(); let mut output = output.as_ref().borrow_mut();
let output = String::from_utf8(std::mem::take(&mut *output)).unwrap(); let output = String::from_utf8(std::mem::take(&mut *output)).unwrap();

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
// [line 3] Error: Unexpected character.
// [java line 3] Error at 'b': Expect ')' after arguments.
foo(a | b);

View file

@ -1,3 +1,3 @@
fun foo(a) { fun foo(a) {
var a; // Error at 'a': Already a variable with this name in this scope. var a;
} }