use std::cell::RefCell; use std::io::stdin; use std::path::PathBuf; use std::rc::Rc; use rlox2_frontend::lexer::TokenType; use rlox2_interpreter::{run, Runtime}; fn run_test(path: impl Into) { let path = &path.into(); // path.insert_str(0, "./tests/lox/"); let source = std::fs::read_to_string(path).unwrap(); let tokens = rlox2_frontend::lexer::scan_tokens(&source).unwrap(); let comments: Vec = tokens .into_iter() .filter_map(|token| { if let TokenType::Comment(s) = token.token_type { if s.starts_with(" expect: ") { Some(s.strip_prefix(" expect: ").unwrap().trim().to_owned()) } else if s.starts_with(" Error") || s.contains("error") { Some(s.trim().into()) } else { None } } else { None } }) .collect(); for comment in comments.iter() { println!("Comment: \"{comment}\"") } print!("\n\n"); let output: Vec = Vec::new(); let output = Rc::new(RefCell::new(output)); { let output: Rc>> = Rc::clone(&output); let mut runtime = Runtime::new(Rc::new(RefCell::new(stdin())), output); match run(&source, &mut runtime) { Ok(()) => (), Err(e) => { println!("{e}"); assert_eq!(comments.len(), 1); let comment = &*comments[0]; assert!(comment.to_lowercase().contains("error")); return; } } } let mut output = output.as_ref().borrow_mut(); let output = String::from_utf8(std::mem::take(&mut *output)).unwrap(); println!("output: len = {}\n---", output.len()); println!("{output}"); println!("---"); let lines: Vec = output .split_terminator('\n') .map(|s| s.to_owned()) .collect(); assert_eq!(lines.len(), comments.len()); for (line, comment) in std::iter::zip(lines.into_iter(), comments.into_iter()) { assert_eq!(line, comment); } } #[test] fn run_all_tests() { for lox_file in glob::glob("tests/lox/**/*.lox").unwrap() { let lox_file = lox_file.unwrap(); print!("\n\n\n"); println!( "================================================================================\n" ); println!("Running test for file {}\n", lox_file.display()); run_test(lox_file); } }