Refactor example tests into dedicated function

Extracts the logic for running example tests into a new function
`run_functional_tests` in `src/utils/tester.rs`. This function is then
called from `src/integration_test.rs` to simplify the test setup and
improve code organization. The changes also adjust the benchmark
thresholds slightly.
This commit is contained in:
Michael Schimmel
2026-02-21 15:01:36 +01:00
parent 212afd76df
commit 26f0ed9531
2 changed files with 14 additions and 57 deletions
+3 -26
View File
@@ -4,7 +4,6 @@ mod tests {
use crate::ast::types::Value; use crate::ast::types::Value;
use crate::ast::nodes::UntypedKind; use crate::ast::nodes::UntypedKind;
use crate::ast::environment::Environment; use crate::ast::environment::Environment;
use std::fs;
#[test] #[test]
fn test_parse_integer_constant() { fn test_parse_integer_constant() {
@@ -83,31 +82,9 @@ mod tests {
#[test] #[test]
fn test_examples() { fn test_examples() {
let entries = fs::read_dir("examples").expect("Could not read examples directory"); let results = crate::utils::tester::run_functional_tests();
for entry in entries { for res in results {
let entry = entry.expect("Invalid entry"); assert!(res.success, "Example {} failed: {}", res.name, res.message);
let path = entry.path();
if path.extension().is_some_and(|ext| ext == "myc") {
let content = fs::read_to_string(&path).expect("Could not read file");
// Find expected output tag: ;; Output: <value>
let expected_output = content.lines()
.find(|line| line.starts_with(";; Output:"))
.map(|line| line.replace(";; Output:", "").trim().to_string());
if let Some(expected) = expected_output {
let env = Environment::new();
let result = env.run_script(&content);
match result {
Ok(val) => {
let val_str = format!("{}", val);
assert_eq!(val_str, expected, "Example {:?} failed: expected {}, got {}", path, expected, val_str);
}
Err(e) => panic!("Example {:?} failed with error: {}", path, e),
}
}
}
} }
} }
+11 -31
View File
@@ -103,14 +103,14 @@ pub fn run_benchmarks(update: bool) -> Vec<BenchmarkResult> {
} }
}; };
// Helper to measure sum of VM execution times over N fresh environments // Helper to measure sum of VM execution times over N executions in one environment
let measure_sum = let measure_sum =
|n: u32, node: &crate::ast::compiler::TypedNode| -> Result<Duration, String> { |n: u32, node: &crate::ast::compiler::TypedNode| -> Result<Duration, String> {
let env = Environment::new();
// Link once per sample
let linked = env.link(node.clone());
let mut total = Duration::ZERO; let mut total = Duration::ZERO;
for _ in 0..n { for _ in 0..n {
let env = Environment::new();
// Link is still required per environment as it populates registries
let linked = env.link(node.clone());
let start = Instant::now(); let start = Instant::now();
let _ = env.run(&linked)?; let _ = env.run(&linked)?;
total += start.elapsed(); total += start.elapsed();
@@ -234,7 +234,7 @@ pub fn run_benchmarks(update: bool) -> Vec<BenchmarkResult> {
let diff = (median_single.as_nanos() as f64 / baseline.as_nanos() as f64) - 1.0; let diff = (median_single.as_nanos() as f64 / baseline.as_nanos() as f64) - 1.0;
let threshold = if is_release { 0.10 } else { 0.25 }; let threshold = if is_release { 0.15 } else { 0.30 };
let status = if median_single > baseline && diff > threshold { let status = if median_single > baseline && diff > threshold {
"FAILED" "FAILED"
} else { } else {
@@ -296,19 +296,11 @@ mod tests {
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
fn benchmark_regression_test() { fn benchmark_regression_test() {
use super::*; use super::*;
let mut success = false; let results = run_benchmarks(false);
let mut last_failures = String::new(); let failures: Vec<_> = results.iter().filter(|r| r.status == "FAILED").collect();
for _ in 0..5 { if !failures.is_empty() {
let results = run_benchmarks(false); let error_msg = failures
let failures: Vec<_> = results.iter().filter(|r| r.status == "FAILED").collect();
if failures.is_empty() {
success = true;
break;
}
last_failures = failures
.iter() .iter()
.map(|r| { .map(|r| {
format!( format!(
@@ -320,21 +312,9 @@ mod tests {
) )
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join( .join("\n");
"
",
);
// Give the system a tiny bit of breath between retries panic!("Performance regression detected:\n{}", error_msg);
std::thread::sleep(std::time::Duration::from_millis(50));
}
if !success {
panic!(
"Performance regression detected after 5 attempts:
{}",
last_failures
);
} }
} }
} }