Files
RustAst/tests/destructuring.rs
Brummel 49ad76e7c3 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`.
2026-03-21 15:56:07 +01:00

140 lines
4.1 KiB
Rust

use myc::ast::environment::Environment;
use myc::ast::types::Value;
#[test]
fn test_dynamic_call_destructuring_underflow() {
let env = Environment::new();
let source = "(do
(def call-dynamic (fn [f data] (f data)))
(def data [10 [20 30]])
(def x (fn [[a [b c]]] (+ a (+ b c))))
(call-dynamic x data))";
let result = env.run_script(source);
if let Err(e) = &result {
panic!("Failed: {}", e);
}
assert_eq!(format!("{}", result.unwrap()), "60");
}
#[test]
fn test_nested_destructuring_optimization() {
let env = Environment::new();
let source_tuple = "((fn [[x y]] (+ x y)) [10 20])";
assert_eq!(format!("{}", env.run_script(source_tuple).unwrap()), "30");
let dump_tuple = env.dump_ast(source_tuple).unwrap();
assert!(
dump_tuple.contains("Constant: 30"),
"Nested tuple should be folded to 30. Dump:\n{}",
dump_tuple
);
}
#[test]
fn test_def_destructuring() {
let env = Environment::new();
// 1. Global destructuring
let source_global = "(do (def [a b] [1 2]) (+ a b))";
assert_eq!(format!("{}", env.run_script(source_global).unwrap()), "3");
// 2. Local nested destructuring inside a function
let source_local =
"((fn [x] (do (def [a [[b c] d]] x) (+ a (+ b (+ c d))))) [1 [[2 3] 4]])";
assert_eq!(format!("{}", env.run_script(source_local).unwrap()), "10");
// 3. Verify destructuring result manually
let source_check = "(do (def [x y] [7 8]) [x y])";
let res = env.run_script(source_check).unwrap();
if let Value::Tuple(vals) = res {
assert_eq!(vals.len(), 2);
assert_eq!(format!("{}", vals[0]), "7");
assert_eq!(format!("{}", vals[1]), "8");
} else {
panic!("Expected tuple from [x y], got {:?}", res);
}
}
#[test]
fn test_assign_destructuring() {
// 1. Simple assignment destructuring
{
let env = Environment::new();
let source_simple = "(do (def a 0) (def b 0) (assign [a b] [10 20]) (+ a b))";
assert_eq!(format!("{}", env.run_script(source_simple).unwrap()), "30");
}
// 2. Nested assignment destructuring
{
let env = Environment::new();
let source_nested =
"(do (def a 0) (def b 0) (def c 0) (assign [a [b c]] [1 [2 3]]) (+ a (+ b c)))";
assert_eq!(format!("{}", env.run_script(source_nested).unwrap()), "6");
}
// 3. Assignment value check
{
let env = Environment::new();
let source_return = "(do (def a 0) (def b 0) (assign [a b] [5 6]) [a b])";
let res = env.run_script(source_return).unwrap();
if let Value::Tuple(vals) = res {
assert_eq!(vals.len(), 2);
assert_eq!(format!("{}", vals[0]), "5");
assert_eq!(format!("{}", vals[1]), "6");
} else {
panic!("Expected tuple from [a b], got {:?}", res);
}
}
}
#[test]
fn test_multi_level_destructuring() {
let env = Environment::new();
let source = "(do
(def process_data (fn [conf]
(do
(def [str s] conf)
(def [f ss] s)
[\"Symbol:\" str \"field:\" f \"id:\" ss]
)
)
)
(process_data [\"btc\" [:close \"cls\"]]))";
let res = env.run_script(source).unwrap();
assert_eq!(
format!("{}", res),
"[\"Symbol:\" \"btc\" \"field:\" :close \"id:\" \"cls\"]"
);
}
#[test]
fn test_captured_slot_destructuring() {
let env = Environment::new();
// A closure capturing both slots from a destructuring def must work correctly.
let source = r#"
(do
(def [x y] [10 20])
(def get-sum (fn [] (+ x y)))
(get-sum))
"#;
assert_eq!(format!("{}", env.run_script(source).unwrap()), "30");
}
#[test]
fn test_destructuring_capture_mutation() {
let env = Environment::new();
// A closure mutating a slot bound via destructuring must see the updated value.
let source = r#"
(do
(def [a b] [1 2])
(def inc! (fn [] (assign a (+ a b))))
(inc!)
(inc!)
a)
"#;
// 1+2=3, 3+2=5
assert_eq!(format!("{}", env.run_script(source).unwrap()), "5");
}