wip
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
use rlox::backend::interpreter::{EvaluateInterpreter, Interpreter};
|
||||
use rlox::frontend::lexer::Lexer;
|
||||
use rlox::frontend::parser::Parser;
|
||||
use rlox::frontend::source_registry::SourceRegistry;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn test_all_examples() {
|
||||
let examples_dir = Path::new("examples");
|
||||
|
||||
// Trova tutti i file .lox nella directory examples
|
||||
let entries = fs::read_dir(examples_dir).expect("Failed to read examples directory");
|
||||
|
||||
let mut test_files_passed = Vec::new();
|
||||
let mut test_files_failed = Vec::new();
|
||||
let mut fail_files_passed = Vec::new();
|
||||
let mut fail_files_failed = Vec::new();
|
||||
|
||||
for entry in entries {
|
||||
let entry = entry.expect("Failed to read directory entry");
|
||||
let path = entry.path();
|
||||
|
||||
// Controlla se è un file .lox
|
||||
if path.extension().and_then(|s| s.to_str()) == Some("lox") {
|
||||
let file_name = path.file_name().unwrap().to_str().unwrap().to_string();
|
||||
|
||||
// Ignora i file che non iniziano con test_ o fail_
|
||||
if !file_name.starts_with("test_") && !file_name.starts_with("fail_") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Leggi il contenuto del file
|
||||
let source = match fs::read_to_string(&path) {
|
||||
Ok(content) => content,
|
||||
Err(e) => {
|
||||
if file_name.starts_with("test_") {
|
||||
test_files_failed.push((file_name, format!("Failed to read file: {}", e)));
|
||||
} else {
|
||||
fail_files_failed.push((file_name, format!("Failed to read file: {}", e)));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
// Esegui il file e categorizza il risultato
|
||||
match run_lox_file(source, &file_name) {
|
||||
Ok(_) => {
|
||||
if file_name.starts_with("test_") {
|
||||
test_files_passed.push(file_name);
|
||||
} else {
|
||||
fail_files_passed.push(file_name);
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
if file_name.starts_with("test_") {
|
||||
test_files_failed.push((file_name, error));
|
||||
} else {
|
||||
fail_files_failed.push((file_name, error));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stampa i risultati
|
||||
println!("\n========== TEST RESULTS ==========");
|
||||
|
||||
// File test_ (dovrebbero passare)
|
||||
if !test_files_passed.is_empty() || !test_files_failed.is_empty() {
|
||||
println!("\n📝 TEST FILES (should pass):");
|
||||
if !test_files_passed.is_empty() {
|
||||
println!(" ✅ Passed ({}):", test_files_passed.len());
|
||||
for file in &test_files_passed {
|
||||
println!(" - {}", file);
|
||||
}
|
||||
}
|
||||
if !test_files_failed.is_empty() {
|
||||
println!(" ❌ Failed ({}):", test_files_failed.len());
|
||||
for (file, error) in &test_files_failed {
|
||||
println!("\n - {}", file);
|
||||
println!("{}", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// File fail_ (dovrebbero fallire)
|
||||
if !fail_files_failed.is_empty() || !fail_files_passed.is_empty() {
|
||||
println!("\n🚫 FAIL FILES (should fail):");
|
||||
if !fail_files_failed.is_empty() {
|
||||
println!(" ✅ Failed as expected ({}):", fail_files_failed.len());
|
||||
for (file, error) in &fail_files_failed {
|
||||
println!("\n - {}", file);
|
||||
println!("{}", error);
|
||||
}
|
||||
}
|
||||
if !fail_files_passed.is_empty() {
|
||||
println!(" ❌ Passed unexpectedly ({}):", fail_files_passed.len());
|
||||
for file in &fail_files_passed {
|
||||
println!(" - {} (should have failed but passed!)", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("\n==================================");
|
||||
|
||||
// Riepilogo
|
||||
let total_test_files = test_files_passed.len() + test_files_failed.len();
|
||||
let total_fail_files = fail_files_passed.len() + fail_files_failed.len();
|
||||
let total_files = total_test_files + total_fail_files;
|
||||
|
||||
println!("Summary:");
|
||||
if total_test_files > 0 {
|
||||
println!(
|
||||
" test_ files: {}/{} passed",
|
||||
test_files_passed.len(),
|
||||
total_test_files
|
||||
);
|
||||
}
|
||||
if total_fail_files > 0 {
|
||||
println!(
|
||||
" fail_ files: {}/{} failed (as expected)",
|
||||
fail_files_failed.len(),
|
||||
total_fail_files
|
||||
);
|
||||
}
|
||||
println!(" Total files tested: {}", total_files);
|
||||
|
||||
// Assicurati che almeno un file sia stato testato
|
||||
assert!(
|
||||
total_files > 0,
|
||||
"No test_ or fail_ .lox files found in examples directory"
|
||||
);
|
||||
|
||||
// Asserzioni per far fallire il test se le aspettative non sono rispettate
|
||||
if !test_files_failed.is_empty() {
|
||||
println!("\n❌ TEST FAILURE: The following test_ files failed but should have passed:");
|
||||
for (file, _) in &test_files_failed {
|
||||
println!(" - {}", file);
|
||||
}
|
||||
panic!(
|
||||
"{} test_ files failed unexpectedly",
|
||||
test_files_failed.len()
|
||||
);
|
||||
}
|
||||
|
||||
if !fail_files_passed.is_empty() {
|
||||
println!("\n❌ TEST FAILURE: The following fail_ files passed but should have failed:");
|
||||
for file in &fail_files_passed {
|
||||
println!(" - {}", file);
|
||||
}
|
||||
panic!(
|
||||
"{} fail_ files passed unexpectedly",
|
||||
fail_files_passed.len()
|
||||
);
|
||||
}
|
||||
|
||||
println!(
|
||||
"\n✅ All {} test/fail files behaved as expected!",
|
||||
total_files
|
||||
);
|
||||
}
|
||||
|
||||
fn run_lox_file(source: String, _filename: &str) -> Result<(), String> {
|
||||
// Crea un source registry e mantienilo per il pretty printing degli errori
|
||||
let mut source_registry = SourceRegistry::new();
|
||||
|
||||
// Aggiungi il source con il nome del file corretto
|
||||
let source_id = match source_registry.add_source_string(source.clone()) {
|
||||
Ok(id) => id,
|
||||
Err(e) => return Err(format!("Failed to add source: {}", e)),
|
||||
};
|
||||
|
||||
// Tokenizza
|
||||
let source_content = source_registry.get_by_id(source_id).content.clone();
|
||||
let mut lexer = Lexer::new(source_content, source_id);
|
||||
let tokens = match lexer.scans_tokens() {
|
||||
Ok(tokens) => tokens,
|
||||
Err(err) => {
|
||||
// Usa il pretty printing con source context
|
||||
return Err(err.display_with_source(&source_registry));
|
||||
}
|
||||
};
|
||||
|
||||
// Parsa
|
||||
let ast = match Parser::new(tokens).parse() {
|
||||
Ok(ast) => ast,
|
||||
Err(err) => {
|
||||
// Usa il pretty printing con source context
|
||||
return Err(err.display_with_source(&source_registry));
|
||||
}
|
||||
};
|
||||
|
||||
// Esegui
|
||||
let mut interpreter = Interpreter::new();
|
||||
for stmt in ast.iter() {
|
||||
match interpreter.evaluate(stmt.clone()) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
// Usa il pretty printing con source context
|
||||
return Err(err.display_with_source(&source_registry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user