#![cfg(not(target_arch = "wasm32"))]
use futures::executor::block_on;
use runmat_builtins::Value;
use runmat_core::RunMatSession;
use runmat_gc::gc_test_context;
#[test]
fn test_variable_persistence_basic() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
let result1 = block_on(engine.execute("a = 10")).unwrap();
assert!(result1.error.is_none());
if let Some(Value::Num(val)) = result1.value {
assert_eq!(val, 10.0);
} else {
panic!("Expected Num(10.0), got {:?}", result1.value);
}
let result2 = block_on(engine.execute("a + 5")).unwrap();
assert!(result2.error.is_none());
if let Some(Value::Num(val)) = result2.value {
assert_eq!(val, 15.0); } else {
panic!("Expected Num(15.0), got {:?}", result2.value);
}
let result3 = block_on(engine.execute("a")).unwrap();
assert!(result3.error.is_none());
if let Some(Value::Num(val)) = result3.value {
assert_eq!(val, 10.0);
} else {
panic!("Expected Num(10.0), got {:?}", result3.value);
}
});
}
#[test]
fn test_variable_persistence_multiple_variables() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
let result1 = block_on(engine.execute("x = 5")).unwrap();
assert!(result1.error.is_none());
let result2 = block_on(engine.execute("y = 3")).unwrap();
assert!(result2.error.is_none());
let result3 = block_on(engine.execute("z = 2")).unwrap();
assert!(result3.error.is_none());
let result4 = block_on(engine.execute("x + y + z")).unwrap();
assert!(result4.error.is_none());
if let Some(Value::Num(val)) = result4.value {
assert_eq!(val, 10.0); } else {
panic!("Expected Num(10.0), got {:?}", result4.value);
}
let result5 = block_on(engine.execute("x * y * z")).unwrap();
assert!(result5.error.is_none());
if let Some(Value::Num(val)) = result5.value {
assert_eq!(val, 30.0); } else {
panic!("Expected Num(30.0), got {:?}", result5.value);
}
});
}
#[test]
fn test_variable_persistence_reassignment() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
let result1 = block_on(engine.execute("value = 100")).unwrap();
assert!(result1.error.is_none());
let result2 = block_on(engine.execute("value / 10")).unwrap();
assert!(result2.error.is_none());
let result3 = block_on(engine.execute("value = 50")).unwrap();
assert!(result3.error.is_none());
let result4 = block_on(engine.execute("value * 2")).unwrap();
assert!(result4.error.is_none());
});
}
#[test]
fn test_expression_result_printing() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
let result1 = block_on(engine.execute("42")).unwrap();
assert!(result1.error.is_none());
if let Some(Value::Num(val)) = result1.value {
assert_eq!(val, 42.0);
} else {
panic!("Expected Num(42.0), got {:?}", result1.value);
}
let result2 = block_on(engine.execute("10 + 20")).unwrap();
assert!(result2.error.is_none());
if let Some(Value::Num(val)) = result2.value {
assert_eq!(val, 30.0);
} else {
panic!("Expected Num(30.0), got {:?}", result2.value);
}
let result3 = block_on(engine.execute("(5 + 3) * (10 - 2)")).unwrap();
assert!(result3.error.is_none());
if let Some(Value::Num(val)) = result3.value {
assert_eq!(val, 64.0); } else {
panic!("Expected Num(64.0), got {:?}", result3.value);
}
});
}
#[test]
fn test_mixed_assignments_and_expressions() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
let result1 = block_on(engine.execute("a = 7")).unwrap();
assert!(result1.error.is_none());
let result2 = block_on(engine.execute("b = 3")).unwrap();
assert!(result2.error.is_none());
let result3 = block_on(engine.execute("a * b")).unwrap();
assert!(result3.error.is_none());
if let Some(Value::Num(val)) = result3.value {
assert_eq!(val, 21.0); } else {
panic!("Expected Num(21.0), got {:?}", result3.value);
}
let result4 = block_on(engine.execute("c = a + b")).unwrap();
assert!(result4.error.is_none());
if let Some(Value::Num(val)) = result4.value {
assert_eq!(val, 10.0); } else {
panic!("Expected Num(10.0), got {:?}", result4.value);
}
let result5 = block_on(engine.execute("c * 2")).unwrap();
assert!(result5.error.is_none());
if let Some(Value::Num(val)) = result5.value {
assert_eq!(val, 20.0); } else {
panic!("Expected Num(20.0), got {:?}", result5.value);
}
let result6 = block_on(engine.execute("a + b + c")).unwrap();
assert!(result6.error.is_none());
if let Some(Value::Num(val)) = result6.value {
assert_eq!(val, 20.0); } else {
panic!("Expected Num(20.0), got {:?}", result6.value);
}
});
}
#[test]
fn test_variable_persistence_with_interpreter_only() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(false, false).unwrap();
let result1 = block_on(engine.execute("test_var = 123")).unwrap();
assert!(result1.error.is_none());
assert!(!result1.used_jit);
let result2 = block_on(engine.execute("test_var + 77")).unwrap();
assert!(result2.error.is_none());
assert!(!result2.used_jit); });
}
#[test]
fn test_variable_persistence_with_jit_hybrid() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
let result1 = block_on(engine.execute("jit_var = 456")).unwrap();
assert!(result1.error.is_none());
let result2 = block_on(engine.execute("jit_var - 56")).unwrap();
assert!(result2.error.is_none());
let result3 = block_on(engine.execute("jit_var2 = jit_var / 4")).unwrap();
assert!(result3.error.is_none());
let result4 = block_on(engine.execute("jit_var + jit_var2")).unwrap();
assert!(result4.error.is_none());
});
}
#[test]
fn test_large_number_of_variables() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
for i in 1..=10 {
let cmd = format!("var{} = {}", i, i * 10);
let result = block_on(engine.execute(&cmd)).unwrap();
assert!(result.error.is_none());
}
let result = block_on(engine.execute("var1 + var2 + var3 + var4 + var5")).unwrap();
assert!(result.error.is_none());
let result = block_on(engine.execute("var10 - var9 + var8")).unwrap();
assert!(result.error.is_none());
});
}
#[test]
fn test_zero_values_persistence() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
let result1 = block_on(engine.execute("zero_var = 0")).unwrap();
assert!(result1.error.is_none());
let result2 = block_on(engine.execute("zero_var + 5")).unwrap();
assert!(result2.error.is_none());
let result3 = block_on(engine.execute("10 - zero_var")).unwrap();
assert!(result3.error.is_none());
});
}
#[test]
fn test_negative_values_persistence() {
gc_test_context(|| {
let mut engine = RunMatSession::with_options(true, false).unwrap();
let result1 = block_on(engine.execute("neg = -15")).unwrap();
assert!(result1.error.is_none());
let result2 = block_on(engine.execute("pos = 25")).unwrap();
assert!(result2.error.is_none());
let result3 = block_on(engine.execute("neg + pos")).unwrap();
assert!(result3.error.is_none());
let result4 = block_on(engine.execute("neg * pos")).unwrap();
assert!(result4.error.is_none());
});
}