use super::*;
#[test]
fn test_make_map() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let (_stack, result) = pop(stack);
match result {
Value::Map(m) => assert!(m.is_empty()),
_ => panic!("Expected Map"),
}
}
}
#[test]
fn test_map_set_and_get() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::String("name".into()));
let stack = push(stack, Value::String("Alice".into()));
let stack = map_set(stack);
let stack = push(stack, Value::String("name".into()));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
assert_eq!(flag, Value::Bool(true));
let (_stack, result) = pop(stack);
match result {
Value::String(s) => assert_eq!(s.as_str(), "Alice"),
_ => panic!("Expected String"),
}
}
}
#[test]
fn test_map_set_with_int_key() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::Int(42));
let stack = push(stack, Value::String("answer".into()));
let stack = map_set(stack);
let stack = push(stack, Value::Int(42));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
assert_eq!(flag, Value::Bool(true));
let (_stack, result) = pop(stack);
match result {
Value::String(s) => assert_eq!(s.as_str(), "answer"),
_ => panic!("Expected String"),
}
}
}
#[test]
fn test_map_has() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::String("key".into()));
let stack = push(stack, Value::Int(100));
let stack = map_set(stack);
let stack = crate::stack::dup(stack);
let stack = push(stack, Value::String("key".into()));
let stack = map_has(stack);
let (stack, result) = pop(stack);
assert_eq!(result, Value::Bool(true));
let stack = push(stack, Value::String("missing".into()));
let stack = map_has(stack);
let (_stack, result) = pop(stack);
assert_eq!(result, Value::Bool(false));
}
}
#[test]
fn test_map_remove() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::String("a".into()));
let stack = push(stack, Value::Int(1));
let stack = map_set(stack);
let stack = push(stack, Value::String("b".into()));
let stack = push(stack, Value::Int(2));
let stack = map_set(stack);
let stack = push(stack, Value::String("a".into()));
let stack = map_remove(stack);
let stack = crate::stack::dup(stack);
let stack = push(stack, Value::String("a".into()));
let stack = map_has(stack);
let (stack, result) = pop(stack);
assert_eq!(result, Value::Bool(false));
let stack = push(stack, Value::String("b".into()));
let stack = map_has(stack);
let (_stack, result) = pop(stack);
assert_eq!(result, Value::Bool(true));
}
}
#[test]
fn test_map_size() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = map_size(stack);
let (stack, result) = pop(stack);
assert_eq!(result, Value::Int(0));
let stack = make_map(stack);
let stack = push(stack, Value::String("a".into()));
let stack = push(stack, Value::Int(1));
let stack = map_set(stack);
let stack = push(stack, Value::String("b".into()));
let stack = push(stack, Value::Int(2));
let stack = map_set(stack);
let stack = map_size(stack);
let (_stack, result) = pop(stack);
assert_eq!(result, Value::Int(2));
}
}
#[test]
fn test_map_empty() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = map_empty(stack);
let (stack, result) = pop(stack);
assert_eq!(result, Value::Bool(true));
let stack = make_map(stack);
let stack = push(stack, Value::String("key".into()));
let stack = push(stack, Value::Int(1));
let stack = map_set(stack);
let stack = map_empty(stack);
let (_stack, result) = pop(stack);
assert_eq!(result, Value::Bool(false));
}
}
#[test]
fn test_map_keys_and_values() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::String("x".into()));
let stack = push(stack, Value::Int(10));
let stack = map_set(stack);
let stack = push(stack, Value::String("y".into()));
let stack = push(stack, Value::Int(20));
let stack = map_set(stack);
let stack = crate::stack::dup(stack); let stack = map_keys(stack);
let (stack, keys_result) = pop(stack);
match keys_result {
Value::Variant(v) => {
assert_eq!(v.fields.len(), 2);
}
_ => panic!("Expected Variant"),
}
let stack = map_values(stack);
let (_stack, values_result) = pop(stack);
match values_result {
Value::Variant(v) => {
assert_eq!(v.fields.len(), 2);
}
_ => panic!("Expected Variant"),
}
}
}
#[test]
fn test_map_get_found() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::String("key".into()));
let stack = push(stack, Value::Int(42));
let stack = map_set(stack);
let stack = push(stack, Value::String("key".into()));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
let (_stack, value) = pop(stack);
assert_eq!(flag, Value::Bool(true));
assert_eq!(value, Value::Int(42));
}
}
#[test]
fn test_map_get_not_found() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::String("missing".into()));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
let (_stack, _value) = pop(stack); assert_eq!(flag, Value::Bool(false));
}
}
#[test]
fn test_map_with_bool_key() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::Bool(true));
let stack = push(stack, Value::String("yes".into()));
let stack = map_set(stack);
let stack = push(stack, Value::Bool(false));
let stack = push(stack, Value::String("no".into()));
let stack = map_set(stack);
let stack = push(stack, Value::Bool(true));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
assert_eq!(flag, Value::Bool(true));
let (_stack, result) = pop(stack);
match result {
Value::String(s) => assert_eq!(s.as_str(), "yes"),
_ => panic!("Expected String"),
}
}
}
#[test]
fn test_map_key_overwrite() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::String("key".into()));
let stack = push(stack, Value::Int(100));
let stack = map_set(stack);
let stack = push(stack, Value::String("key".into()));
let stack = push(stack, Value::Int(200));
let stack = map_set(stack);
let stack = crate::stack::dup(stack);
let stack = map_size(stack);
let (stack, size) = pop(stack);
assert_eq!(size, Value::Int(1));
let stack = push(stack, Value::String("key".into()));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
assert_eq!(flag, Value::Bool(true));
let (_stack, result) = pop(stack);
assert_eq!(result, Value::Int(200));
}
}
#[test]
fn test_map_mixed_key_types() {
unsafe {
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::String("name".into()));
let stack = push(stack, Value::String("Alice".into()));
let stack = map_set(stack);
let stack = push(stack, Value::Int(42));
let stack = push(stack, Value::String("answer".into()));
let stack = map_set(stack);
let stack = push(stack, Value::Bool(true));
let stack = push(stack, Value::String("yes".into()));
let stack = map_set(stack);
let stack = crate::stack::dup(stack);
let stack = map_size(stack);
let (stack, size) = pop(stack);
assert_eq!(size, Value::Int(3));
let stack = crate::stack::dup(stack);
let stack = push(stack, Value::String("name".into()));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
assert_eq!(flag, Value::Bool(true));
let (stack, result) = pop(stack);
match result {
Value::String(s) => assert_eq!(s.as_str(), "Alice"),
_ => panic!("Expected String for name key"),
}
let stack = crate::stack::dup(stack);
let stack = push(stack, Value::Int(42));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
assert_eq!(flag, Value::Bool(true));
let (stack, result) = pop(stack);
match result {
Value::String(s) => assert_eq!(s.as_str(), "answer"),
_ => panic!("Expected String for int key"),
}
let stack = push(stack, Value::Bool(true));
let stack = map_get(stack);
let (stack, flag) = pop(stack);
assert_eq!(flag, Value::Bool(true));
let (_stack, result) = pop(stack);
match result {
Value::String(s) => assert_eq!(s.as_str(), "yes"),
_ => panic!("Expected String for bool key"),
}
}
}
#[test]
fn test_map_fold_empty() {
unsafe {
use crate::quotations::push_quotation;
let stack = crate::stack::alloc_test_stack();
let stack = make_map(stack);
let stack = push(stack, Value::Int(99));
unsafe extern "C" fn noop(stack: Stack) -> Stack {
stack
}
let fn_ptr = noop as *const () as usize;
let stack = push_quotation(stack, fn_ptr, fn_ptr);
let stack = patch_seq_map_fold(stack);
let (_stack, result) = pop(stack);
assert_eq!(result, Value::Int(99));
}
}