use super::*;
use crate::error::OpError;
#[test]
fn test_memory_store_load() {
let mut memory = Memory::new();
memory.load(0).unwrap_err();
memory.store(0, 0).unwrap_err();
memory.alloc(1).unwrap();
assert_eq!(memory.load(0).unwrap(), 0);
memory.store(0, 1).unwrap();
assert_eq!(memory.load(0).unwrap(), 1);
memory.load(1).unwrap_err();
memory.store(1, 0).unwrap_err();
assert_eq!(memory.len().unwrap(), 1);
}
#[test]
fn test_free_empty_memory() {
let mut memory = Memory::new();
assert!(memory.is_empty());
assert!(matches!(
memory.free(0),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_free_valid_address() {
let mut memory = Memory::new();
memory.alloc(10).unwrap();
assert_eq!(memory.len().unwrap(), 10);
for i in 0..10 {
memory.store(i, i as Word).unwrap();
}
memory.free(5).unwrap();
assert_eq!(memory.len().unwrap(), 5);
for i in 0..5 {
assert_eq!(memory.load(i).unwrap(), i as Word);
}
assert!(matches!(
memory.load(5),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_free_at_last_index() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
memory.free(4).unwrap();
assert_eq!(memory.len().unwrap(), 4);
for i in 0..4 {
assert_eq!(memory.load(i).unwrap(), 0);
}
}
#[test]
fn test_free_at_start() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
memory.free(0).unwrap();
assert!(memory.is_empty());
assert_eq!(memory.len().unwrap(), 0);
}
#[test]
fn test_free_invalid_address() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
assert!(matches!(
memory.free(5),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert!(matches!(
memory.free(Word::MAX),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert_eq!(memory.len().unwrap(), 5);
}
#[test]
fn test_free_negative_address() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
assert!(matches!(
memory.free(-1),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert_eq!(memory.len().unwrap(), 5);
}
#[test]
fn test_free_multiple_times() {
let mut memory = Memory::new();
memory.alloc(10).unwrap();
memory.free(8).unwrap();
assert_eq!(memory.len().unwrap(), 8);
memory.free(5).unwrap();
assert_eq!(memory.len().unwrap(), 5);
memory.free(0).unwrap();
assert!(memory.is_empty());
}
#[test]
fn test_free_then_allocate() {
let mut memory = Memory::new();
memory.alloc(10).unwrap();
memory.free(5).unwrap();
assert_eq!(memory.len().unwrap(), 5);
memory.alloc(3).unwrap();
assert_eq!(memory.len().unwrap(), 8);
for i in 0..5 {
assert_eq!(memory.load(i).unwrap(), 0);
}
}
#[test]
fn test_free_capacity_reduction() {
let mut memory = Memory::new();
memory.alloc(1000).unwrap();
let index_to_keep = 100;
memory.free(index_to_keep).unwrap();
assert_eq!(memory.0.capacity(), index_to_keep as usize);
}
#[test]
fn test_store_range_empty_memory() {
let mut memory = Memory::new();
let values = vec![1, 2, 3];
assert!(matches!(
memory.store_range(0, &values),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_store_range_sanity() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let values = vec![10, 20, 30];
memory.store_range(0, &values).unwrap();
assert_eq!(memory.load(0).unwrap(), 10);
assert_eq!(memory.load(1).unwrap(), 20);
assert_eq!(memory.load(2).unwrap(), 30);
assert_eq!(memory.load(3).unwrap(), 0);
assert_eq!(memory.load(4).unwrap(), 0);
}
#[test]
fn test_store_range_at_offset() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let values = vec![10, 20];
memory.store_range(2, &values).unwrap();
assert_eq!(memory.load(0).unwrap(), 0);
assert_eq!(memory.load(1).unwrap(), 0);
assert_eq!(memory.load(2).unwrap(), 10);
assert_eq!(memory.load(3).unwrap(), 20);
assert_eq!(memory.load(4).unwrap(), 0);
}
#[test]
fn test_store_range_exact_fit() {
let mut memory = Memory::new();
memory.alloc(3).unwrap();
let values = vec![1, 2, 3];
memory.store_range(0, &values).unwrap();
for i in 0..3 {
assert_eq!(memory.load(i as Word).unwrap(), (i + 1) as Word);
}
}
#[test]
fn test_store_range_overflow() {
let mut memory = Memory::new();
memory.alloc(3).unwrap();
let values = vec![1, 2, 3, 4];
assert!(matches!(
memory.store_range(0, &values),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert_eq!(memory.load(0).unwrap(), 0);
}
#[test]
fn test_store_range_invalid_start_address() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let values = vec![1, 2];
assert!(matches!(
memory.store_range(4, &values), Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert!(matches!(
memory.store_range(5, &values),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert!(matches!(
memory.store_range(Word::MAX, &values),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_store_range_negative_address() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let values = vec![1, 2];
assert!(matches!(
memory.store_range(-1, &values),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert_eq!(memory.load(0).unwrap(), 0);
}
#[test]
fn test_store_range_empty_slice() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let values: Vec<Word> = vec![];
memory.store_range(0, &values).unwrap();
assert_eq!(memory.load(0).unwrap(), 0);
}
#[test]
fn test_store_range_multiple_times() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let values1 = vec![1, 2];
memory.store_range(0, &values1).unwrap();
let values2 = vec![3, 4];
memory.store_range(1, &values2).unwrap();
assert_eq!(memory.load(0).unwrap(), 1);
assert_eq!(memory.load(1).unwrap(), 3);
assert_eq!(memory.load(2).unwrap(), 4);
assert_eq!(memory.load(3).unwrap(), 0);
assert_eq!(memory.load(4).unwrap(), 0);
}
#[test]
fn test_store_range_max_values() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let values = vec![Word::MAX, Word::MIN, Word::MAX];
memory.store_range(1, &values).unwrap();
assert_eq!(memory.load(1).unwrap(), Word::MAX);
assert_eq!(memory.load(2).unwrap(), Word::MIN);
assert_eq!(memory.load(3).unwrap(), Word::MAX);
}
#[test]
fn test_store_range_after_free() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
memory.free(3).unwrap();
let values = vec![1, 2];
assert!(matches!(
memory.store_range(2, &values),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
memory.store_range(0, &values).unwrap();
assert_eq!(memory.load(0).unwrap(), 1);
assert_eq!(memory.load(1).unwrap(), 2);
}
#[test]
fn test_load_range_empty_memory() {
let mut memory = Memory::new();
assert!(matches!(
memory.load_range(0, 1),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_load_range_sanity() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let test_values = vec![10, 20, 30];
memory.store_range(0, &test_values).unwrap();
let loaded = memory.load_range(0, 3).unwrap();
assert_eq!(loaded, test_values);
}
#[test]
fn test_load_range_at_offset() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
memory.store_range(0, &[1, 2, 3, 4, 5]).unwrap();
let loaded = memory.load_range(2, 2).unwrap();
assert_eq!(loaded, vec![3, 4]);
}
#[test]
fn test_load_range_exact_size() {
let mut memory = Memory::new();
memory.alloc(3).unwrap();
memory.store_range(0, &[1, 2, 3]).unwrap();
let loaded = memory.load_range(0, 3).unwrap();
assert_eq!(loaded, vec![1, 2, 3]);
}
#[test]
fn test_load_range_overflow() {
let mut memory = Memory::new();
memory.alloc(3).unwrap();
assert!(matches!(
memory.load_range(0, 4),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert!(matches!(
memory.load_range(2, 2),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_load_range_invalid_start_address() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
assert!(matches!(
memory.load_range(5, 1),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
assert!(matches!(
memory.load_range(Word::MAX, 1),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_load_range_negative_address() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
assert!(matches!(
memory.load_range(-1, 1),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_load_range_zero_size() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
let loaded = memory.load_range(0, 0).unwrap();
assert!(loaded.is_empty());
}
#[test]
fn test_load_range_negative_size() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
assert!(matches!(
memory.load_range(0, -1),
Err(OpError::Temporary(TemporaryError::Overflow))
));
}
#[test]
fn test_load_range_maximum_size() {
let mut memory = Memory::new();
let size = 100; memory.alloc(size).unwrap();
for i in 0..size {
memory.store(i as Word, i as Word).unwrap();
}
let loaded = memory.load_range(0, size as Word).unwrap();
for (i, &value) in loaded.iter().enumerate() {
assert_eq!(value, i as Word);
}
}
#[test]
fn test_load_range_after_modification() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
memory.store_range(0, &[1, 2, 3, 4, 5]).unwrap();
memory.store(2, 30).unwrap();
memory.store(3, 40).unwrap();
let loaded = memory.load_range(1, 3).unwrap();
assert_eq!(loaded, vec![2, 30, 40]);
}
#[test]
fn test_load_range_after_free() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
memory.store_range(0, &[1, 2, 3, 4, 5]).unwrap();
memory.free(3).unwrap();
assert!(matches!(
memory.load_range(2, 2),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
let loaded = memory.load_range(0, 2).unwrap();
assert_eq!(loaded, vec![1, 2]);
}
#[test]
fn test_load_range_large_size_overflow() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
assert!(matches!(
memory.load_range(Word::MAX - 1, 2),
Err(OpError::Temporary(TemporaryError::IndexOutOfBounds))
));
}
#[test]
fn test_load_range_consecutive_loads() {
let mut memory = Memory::new();
memory.alloc(5).unwrap();
memory.store_range(0, &[1, 2, 3, 4, 5]).unwrap();
let first = memory.load_range(0, 2).unwrap();
let second = memory.load_range(2, 2).unwrap();
let third = memory.load_range(4, 1).unwrap();
assert_eq!(first, vec![1, 2]);
assert_eq!(second, vec![3, 4]);
assert_eq!(third, vec![5]);
}