Refactor: Remove integration tests and organize into modules

This commit refactors the test suite by removing the monolithic
`integration_test.rs` file.
The tests have been categorized and moved into dedicated modules within
the `tests/` directory:

- `tests/parser.rs`: Contains tests for parsing various literal values.
- `tests/destructuring.rs`: Houses tests related to destructuring
  syntax.
- `tests/closures.rs`: Includes tests for closure behavior and related
  optimizations.
- `tests/optimizer.rs`: Contains tests specifically targeting optimizer
  logic and regressions.
- `tests/records.rs`: Holds tests for record syntax and associated
  optimizations.
- `tests/rtl.rs`: Contains tests for runtime library operators and
  functions.
- `tests/pipeline.rs`: Tests for pipeline functionality.
- `tests/macros.rs`: Tests for macro expansion and related issues.
- `tests/error_recovery.rs`: Includes tests for compiler error handling
  and recovery mechanisms.
- `tests/examples.rs`: Verifies the execution of example scripts.

This reorganization improves test discoverability and maintainability.
The `lib.rs` file has also been updated to reflect these changes by
removing the reference to the old `integration_test` module.
The `type_checker.rs` file has had some tests removed, as they are now
covered by the more specific tests in `tests/error_recovery.rs`.
This commit is contained in:
2026-03-21 15:56:07 +01:00
parent bc287d27dd
commit 49ad76e7c3
13 changed files with 925 additions and 953 deletions
+93
View File
@@ -0,0 +1,93 @@
use myc::ast::environment::Environment;
use myc::ast::types::Value;
#[test]
fn test_closure_modification_from_source() {
let source = r#"
(do
(def x 10)
(def f (fn [] (assign x 20)))
(f)
x
)
"#;
let env = Environment::new();
let compiled = env
.compile(source)
.into_result()
.expect("Failed to compile");
let linked = env.link(compiled);
let func = env.instantiate(linked);
let result: Result<Value, String> = Ok((func.func)(&[]));
match result {
Ok(Value::Int(20)) => (),
Ok(val) => panic!("Expected Int(20), got {:?}", val),
Err(e) => panic!("VM Error: {}", e),
}
}
#[test]
fn test_closure_reassignment_optimization_bug() {
let env = Environment::new();
// Regression: optimizer inlined a function whose parameters were assigned to
// by an inner lambda. Such functions must NOT be inlined.
let source = "(do (def f (fn [[x y]] (fn [] (assign x (+ x y))))) ((f [1 2])))";
let res = env.run_script(source);
assert_eq!(format!("{}", res.unwrap()), "3");
}
#[test]
fn test_optimizer_upvalue_inlining_bug_repro() {
let env = Environment::new();
let source = r#"
(do
(def make-counter (fn [init]
(do
(def val init)
{
:inc (fn [] (assign val (+ val 1)))
:get (fn [] val)
})))
(def c (make-counter 10))
((.inc c))
((.get c)))
"#;
let res = env.run_script(source);
assert!(res.is_ok(), "Optimizer bug triggered: {:?}", res.err());
assert_eq!(format!("{}", res.unwrap()), "11");
}
#[test]
#[should_panic(expected = "'again' is only allowed in tail position to avoid dead code.")]
fn test_again_non_tail_panic() {
let env = Environment::new();
let source = "(do (def f (fn [x] (do (again (- x 1)) x))) (f 5))";
let _ = env.run_script(source);
}
#[test]
fn test_debug_mode_logging() {
let mut env = Environment::new();
env.optimization = false;
let source = "(+ 10 20)";
let result = env.run_debug(source).expect("Failed to run debug");
let (val, logs) = result;
match val {
Ok(Value::Int(30)) => (),
_ => panic!("Expected Int(30), got {:?}", val),
}
assert!(!logs.is_empty(), "Logs should not be empty");
let has_call = logs.iter().any(|l| l.contains("CALL"));
let has_const = logs.iter().any(|l| l.contains("CONST(10)"));
let has_result = logs.iter().any(|l| l.contains("} -> 30"));
assert!(has_call, "Logs should contain CALL");
assert!(has_const, "Logs should contain CONST(10)");
assert!(has_result, "Logs should contain result 30");
}