use super::*;
use crate::value::Value;
#[test]
fn test_create_env() {
let env = create_env(3);
assert!(!env.is_null());
unsafe {
let _ = Box::from_raw(env);
}
}
#[test]
fn test_env_set_and_get() {
let env = create_env(3);
unsafe {
env_set(env, 0, Value::Int(42));
env_set(env, 1, Value::Bool(true));
env_set(env, 2, Value::Int(99));
}
unsafe {
let env_slice = &*env;
let env_data = env_slice.as_ptr();
let env_len = env_slice.len();
assert_eq!(env_get(env_data, env_len, 0), Value::Int(42));
assert_eq!(env_get(env_data, env_len, 1), Value::Bool(true));
assert_eq!(env_get(env_data, env_len, 2), Value::Int(99));
}
unsafe {
let _ = Box::from_raw(env);
}
}
#[test]
fn test_make_closure() {
let env = create_env(2);
unsafe {
env_set(env, 0, Value::Int(5));
env_set(env, 1, Value::Int(10));
let closure = make_closure(0x1234, env);
match closure {
Value::Closure { fn_ptr, env } => {
assert_eq!(fn_ptr, 0x1234);
assert_eq!(env.len(), 2);
assert_eq!(env[0], Value::Int(5));
assert_eq!(env[1], Value::Int(10));
}
_ => panic!("Expected Closure value"),
}
}
}
#[test]
fn test_push_closure() {
use crate::stack::{pop, push};
use crate::value::Value;
let mut stack = crate::stack::alloc_test_stack();
stack = unsafe { push(stack, Value::Int(10)) };
stack = unsafe { push(stack, Value::Int(5)) };
let fn_ptr = 0x1234;
stack = unsafe { push_closure(stack, fn_ptr, 2) };
let (_stack, closure_value) = unsafe { pop(stack) };
match closure_value {
Value::Closure { fn_ptr: fp, env } => {
assert_eq!(fp, fn_ptr as usize);
assert_eq!(env.len(), 2);
assert_eq!(env[0], Value::Int(10)); assert_eq!(env[1], Value::Int(5)); }
_ => panic!("Expected Closure value, got {:?}", closure_value),
}
}
#[test]
fn test_push_closure_zero_captures() {
use crate::stack::pop;
use crate::value::Value;
let stack = crate::stack::alloc_test_stack();
let fn_ptr = 0x5678;
let stack = unsafe { push_closure(stack, fn_ptr, 0) };
let (_stack, closure_value) = unsafe { pop(stack) };
match closure_value {
Value::Closure { fn_ptr: fp, env } => {
assert_eq!(fp, fn_ptr as usize);
assert_eq!(env.len(), 0);
}
_ => panic!("Expected Closure value, got {:?}", closure_value),
}
}
#[test]
fn test_env_get_bool() {
let env = create_env(2);
unsafe {
env_set(env, 0, Value::Bool(true));
env_set(env, 1, Value::Bool(false));
let env_slice = &*env;
let env_data = env_slice.as_ptr();
let env_len = env_slice.len();
assert_eq!(env_get_bool(env_data, env_len, 0), 1);
assert_eq!(env_get_bool(env_data, env_len, 1), 0);
let _ = Box::from_raw(env);
}
}
#[test]
fn test_env_get_float() {
let env = create_env(2);
unsafe {
env_set(env, 0, Value::Float(1.234));
env_set(env, 1, Value::Float(-5.678));
let env_slice = &*env;
let env_data = env_slice.as_ptr();
let env_len = env_slice.len();
assert!((env_get_float(env_data, env_len, 0) - 1.234).abs() < 0.0001);
assert!((env_get_float(env_data, env_len, 1) - (-5.678)).abs() < 0.0001);
let _ = Box::from_raw(env);
}
}
#[test]
fn test_env_get_quotation() {
let env = create_env(1);
let wrapper: usize = 0xDEADBEEF;
let impl_: usize = 0xCAFEBABE;
unsafe {
env_set(env, 0, Value::Quotation { wrapper, impl_ });
let env_slice = &*env;
let env_data = env_slice.as_ptr();
let env_len = env_slice.len();
assert_eq!(env_get_quotation(env_data, env_len, 0), impl_ as i64);
let _ = Box::from_raw(env);
}
}