use std::fs; use std::fs::File; use std::io::Write; use std::path::Path; fn main() { let paths = fs::read_dir("src/integration_tests/test_cases/").unwrap(); let mod_file_path = Path::new("src/integration_tests/mod.rs"); let mut mod_file = File::create(mod_file_path).unwrap(); write!( mod_file, r#"//////////////////////////// // Automatically Generated// ////////////////////////////"# ) .unwrap(); for path_opt in paths { if let Err(..) = path_opt { continue; } let path = path_opt.unwrap(); if !path.file_type().unwrap().is_dir() { continue; } let p = path.path(); let mut script_path = p.clone(); script_path.push("script.ses"); if !script_path.exists() { continue; } let script = fs::read_to_string(script_path).unwrap(); let test_name = p.file_stem().unwrap().to_str().unwrap(); writeln!(mod_file, "mod {name};", name = test_name).unwrap(); let testfile_path = format!("src/integration_tests/{}.rs", test_name); let mut testfile = File::create(Path::new(&testfile_path)).unwrap(); write!( testfile, r#"//////////////////////////// // Automatically Generated// //////////////////////////// use crate::logger::messages::Message; use crate::parsing::lexer::lex; use crate::parsing::lexer::lex_tokens::LexToken; use crate::parsing::parser::parse; use crate::parsing::parser::parsed_statement::ParsedStatement; use crate::span::Span; fn ignore_error(_msg: Message, _: Span) {{ }} fn panic_on_error(msg: Message, _: Span) {{ std::panic::panic_any(msg.stringify()); }}"# ) .unwrap(); write!( testfile, r#" #[test] fn integration_{name}() {{ let script = "{script}"; let lexed_tokens = lex(script, &mut panic_on_error); println!("{{}}", serde_json::to_string(&lexed_tokens).unwrap()); "#, name = test_name, script = script.as_str() ) .unwrap(); let mut tokens_file_path = p.clone(); tokens_file_path.push("lex_tokens.json"); if tokens_file_path.exists() { let tokens_json = fs::read_to_string(tokens_file_path).unwrap(); write!( testfile, r##" let expected_tokens: Vec = serde_json::from_str(r#"{tokens}"#).unwrap(); assert_eq!(lexed_tokens, expected_tokens); "##, tokens = tokens_json.as_str() ) .unwrap(); } write!( testfile, r##" let parsed_tree = parse(lexed_tokens, &mut panic_on_error); println!("{{}}", serde_json::to_string(&parsed_tree).unwrap()); "## ) .unwrap(); let mut parsed_tree_path = p.clone(); parsed_tree_path.push("parsed_tree.json"); if parsed_tree_path.exists() { let parsed_tree_json = fs::read_to_string(parsed_tree_path).unwrap(); write!( testfile, r##" let expected_tree: Box = serde_json::from_str(r#"{expected_tree}"#).unwrap(); assert_eq!(parsed_tree, expected_tree); "##, expected_tree = parsed_tree_json.as_str() ) .unwrap(); } write!(testfile, "}}").unwrap(); write!( testfile, r##" // A substring of a script should never panic, even though it might be completely invalid. #[test] fn integration_{name}_substring() {{ let mut script = "{script}".to_string(); for _ in 0..script.len() {{ script.pop(); let lexed_tokens = lex(script.as_str(), &mut ignore_error); let _parsed_tree = parse(lexed_tokens, &mut ignore_error); }} }} "##, name = test_name, script = script ) .unwrap(); } }