use crate::{DeferredMap, Key};
#[test]
fn test_basic_removal() {
let mut map = DeferredMap::new();
let h = map.allocate_handle();
let k = h.key();
map.insert(h, 42);
assert_eq!(map.remove(k), Some(42));
assert_eq!(map.len(), 0);
assert_eq!(map.get(k), None);
}
#[test]
fn test_removal_returns_correct_value() {
let mut map = DeferredMap::new();
let h = map.allocate_handle();
let k = h.key();
map.insert(h, "Hello".to_string());
let removed = map.remove(k);
assert_eq!(removed, Some("Hello".to_string()));
}
#[test]
fn test_removal_of_nonexistent_key() {
let mut map = DeferredMap::<i32>::new();
let h = map.allocate_handle();
let k = h.key();
let result = map.remove(k);
assert_eq!(result, None);
}
#[test]
fn test_removal_with_outdated_key() {
let mut map = DeferredMap::new();
let h = map.allocate_handle();
let k1 = h.key();
map.insert(h, 42);
map.remove(k1);
let result = map.remove(k1);
assert_eq!(result, None);
}
#[test]
fn test_removal_decrements_len() {
let mut map = DeferredMap::new();
let mut keys = Vec::new();
for i in 0..10 {
let h = map.allocate_handle();
let k = h.key();
map.insert(h, i);
keys.push(k);
}
assert_eq!(map.len(), 10);
for key in keys {
map.remove(key);
}
assert_eq!(map.len(), 0);
}
#[test]
fn test_removal_allows_slot_reuse() {
let mut map = DeferredMap::new();
let h1 = map.allocate_handle();
let k1 = h1.key();
map.insert(h1, 42);
let index1 = k1.index();
map.remove(k1);
let h2 = map.allocate_handle();
let index2 = h2.index();
assert_eq!(index1, index2);
}
#[test]
fn test_removal_increments_generation() {
let mut map = DeferredMap::new();
let h1 = map.allocate_handle();
let gen1 = h1.generation();
let k1 = h1.key();
map.insert(h1, 42);
map.remove(k1);
let h2 = map.allocate_handle();
let gen2 = h2.generation();
assert_eq!(gen2.get(), gen1.get() + 1);
}
#[test]
fn test_removal_of_multiple_elements() {
let mut map = DeferredMap::new();
let mut keys = Vec::new();
for i in 0..100 {
let h = map.allocate_handle();
let k = h.key();
map.insert(h, i);
keys.push(k);
}
for i in (0..100).step_by(2) {
let removed = map.remove(keys[i]);
assert_eq!(removed, Some(i));
}
assert_eq!(map.len(), 50);
for i in (1..100).step_by(2) {
assert_eq!(map.get(keys[i]), Some(&i));
}
}
#[test]
fn test_removal_and_reinsertion_cycle() {
let mut map = DeferredMap::new();
for cycle in 0..10 {
let h = map.allocate_handle();
let k = h.key();
map.insert(h, cycle);
assert_eq!(map.get(k), Some(&cycle));
assert_eq!(map.remove(k), Some(cycle));
assert_eq!(map.get(k), None);
}
}
#[test]
fn test_removal_with_custom_drop() {
use std::sync::{
Arc,
atomic::{AtomicUsize, Ordering},
};
let drop_count = Arc::new(AtomicUsize::new(0));
struct DropCounter {
count: Arc<AtomicUsize>,
}
impl Drop for DropCounter {
fn drop(&mut self) {
self.count.fetch_add(1, Ordering::SeqCst);
}
}
let mut map = DeferredMap::new();
let h = map.allocate_handle();
let k = h.key();
map.insert(
h,
DropCounter {
count: drop_count.clone(),
},
);
assert_eq!(drop_count.load(Ordering::SeqCst), 0);
map.remove(k);
assert_eq!(drop_count.load(Ordering::SeqCst), 1);
}
#[test]
fn test_removal_frees_memory() {
let mut map = DeferredMap::new();
let mut keys = Vec::new();
for _ in 0..100 {
let large_string = format!("{}", "a".repeat(1000));
let h = map.allocate_handle();
let k = h.key();
map.insert(h, large_string);
keys.push(k);
}
for key in keys {
map.remove(key);
}
assert_eq!(map.len(), 0);
}
#[test]
fn test_removal_maintains_other_elements() {
let mut map = DeferredMap::new();
let mut keys = Vec::new();
for i in 0..10 {
let h = map.allocate_handle();
let k = h.key();
map.insert(h, i * 10);
keys.push(k);
}
map.remove(keys[5]);
for (i, &key) in keys.iter().enumerate() {
if i == 5 {
assert_eq!(map.get(key), None);
} else {
assert_eq!(map.get(key), Some(&(i * 10)));
}
}
}
#[test]
fn test_removal_pattern_lifo() {
let mut map = DeferredMap::new();
let mut keys = Vec::new();
for i in 0..10 {
let h = map.allocate_handle();
let k = h.key();
map.insert(h, i);
keys.push(k);
}
for i in (0..10).rev() {
let removed = map.remove(keys[i]);
assert_eq!(removed, Some(i));
}
assert!(map.is_empty());
}
#[test]
fn test_removal_pattern_fifo() {
let mut map = DeferredMap::new();
let mut keys = Vec::new();
for i in 0..10 {
let h = map.allocate_handle();
let k = h.key();
map.insert(h, i);
keys.push(k);
}
for i in 0..10 {
let removed = map.remove(keys[i]);
assert_eq!(removed, Some(i));
}
assert!(map.is_empty());
}
#[test]
fn test_removal_pattern_random() {
let mut map = DeferredMap::new();
let mut keys = Vec::new();
for i in 0..20 {
let h = map.allocate_handle();
let k = h.key();
map.insert(h, i);
keys.push(k);
}
let remove_order = vec![
5, 15, 2, 18, 0, 10, 7, 12, 3, 17, 1, 14, 8, 19, 4, 11, 6, 13, 9, 16,
];
for idx in remove_order {
map.remove(keys[idx]);
}
assert!(map.is_empty());
}
#[test]
fn test_removal_after_clear() {
let mut map = DeferredMap::new();
let h = map.allocate_handle();
let k = h.key();
map.insert(h, 42);
map.clear();
let result = map.remove(k);
assert_eq!(result, None);
}
#[test]
fn test_removal_slot_added_to_free_list() {
let mut map = DeferredMap::new();
let h1 = map.allocate_handle();
let k1 = h1.key();
map.insert(h1, 1);
map.remove(k1);
let h2 = map.allocate_handle();
let k2 = h2.key();
map.insert(h2, 2);
map.remove(k2);
let h3 = map.allocate_handle();
let k3 = h3.key();
map.insert(h3, 3);
map.remove(k3);
let h4 = map.allocate_handle();
let index4 = h4.index();
let index3 = k3.index();
assert_eq!(index4, index3);
}
#[test]
fn test_removal_with_box_type() {
let mut map = DeferredMap::new();
let h = map.allocate_handle();
let k = h.key();
map.insert(h, Box::new(42));
let removed = map.remove(k);
assert_eq!(removed, Some(Box::new(42)));
}
#[test]
fn test_removal_doesnt_affect_capacity() {
let mut map = DeferredMap::new();
for i in 0..10 {
let h = map.allocate_handle();
map.insert(h, i);
}
let capacity_before = map.capacity();
let h = map.allocate_handle();
let k = h.key();
map.insert(h, 0);
map.remove(k);
let capacity_after = map.capacity();
assert!(capacity_after >= capacity_before);
}
#[test]
fn test_double_removal_fails() {
let mut map = DeferredMap::new();
let h = map.allocate_handle();
let k = h.key();
map.insert(h, 42);
assert_eq!(map.remove(k), Some(42));
assert_eq!(map.remove(k), None);
}