use myc::ast::environment::Environment; #[test] fn test_if_branch_redefinition_works() { let env = Environment::new(); let source = "(if true (do (def x 10) x) (do (def x 20) x))"; let result = env.compile(source).into_result(); assert!(result.is_ok(), "Defining the same variable in different 'if' branches should work now: {:?}", result.err()); } #[test] fn test_forward_reference_in_if_is_local() { let env = Environment::new(); let source = r#" (do (def get-x (fn [] my-future-x)) (if true (def my-future-x 100) (def my-future-x 0)) (get-x)) "#; let result = env.compile(source).into_result(); assert!(result.is_err(), "my-future-x should be local to 'if' and not discoverable globally"); } #[test] fn test_macro_expansion_global_discovery() { let env = Environment::new(); // Goal: A macro generating a 'def' should allow forward references to that variable. let source = r#" (do (macro def-x [] `(def my-macro-x 42)) (def get-x (fn [] my-macro-x)) (def-x) (get-x)) "#; let result = env.run_script(source); // This currently fails with "Undefined variable 'my-macro-x'" assert!(result.is_ok(), "Forward reference to macro-generated global should work: {:?}", result.err()); } #[test] fn test_destructuring_global_discovery() { let env = Environment::new(); // Goal: Destructuring 'def' should also be hoisted by discover_globals. let source = r#" (do (def get-a (fn [] a)) (def [a b] [1 2]) (get-a)) "#; let result = env.run_script(source); // This currently fails with "Undefined variable 'a'" assert!(result.is_ok(), "Forward reference to destructured global should work: {:?}", result.err()); } #[test] fn test_macro_if_branch_scope_leak_fails() { let env = Environment::new(); // A macro defined inside an IF branch should NOT leak to the outer scope. let source = r#" (do (if true (macro my-if-macro [x] `(+ ~x 1)) ...) (my-if-macro 10)) "#; let result = env.compile(source).into_result(); // This currently PASSES (Ok), which is the BUG. We want it to FAIL (Err). assert!(result.is_err(), "Macros should not leak from 'if' branches, but currently they do: {:?}", result.ok()); }