use crate::test::drop_tracker::DropTracker;
use crate::test::types::Three;
use enumoid::EnumOptionMap;
use enumoid::EnumSize;
use std::cell::Cell;
#[test]
fn test_empty_state() {
let map = EnumOptionMap::<Three, u16>::new();
assert!(map.is_empty(), "Expected new map to be empty");
assert!(!map.is_full(), "Expected new map to not be full");
assert_eq!(map.count(), 0, "Expected new map to have count of 0");
assert_eq!(
map.is_vec(),
EnumSize::from_usize(0),
"Expected empty map to be representable as 0-length vector"
);
assert_eq!(
map.get(Three::A),
None,
"Expected None for Three::A in empty map"
);
assert_eq!(
map.get(Three::B),
None,
"Expected None for Three::B in empty map"
);
assert_eq!(
map.get(Three::C),
None,
"Expected None for Three::C in empty map"
);
assert!(
!map.contains(Three::A),
"Expected empty map to not contain Three::A"
);
assert!(
!map.contains(Three::B),
"Expected empty map to not contain Three::B"
);
assert!(
!map.contains(Three::C),
"Expected empty map to not contain Three::C"
);
}
#[test]
fn test_set_and_get() {
let mut map = EnumOptionMap::<Three, u16>::new();
let old_value = map.set(Three::B, Some(200));
assert_eq!(
old_value, None,
"Expected set() to return None for previously empty key"
);
assert!(
!map.is_empty(),
"Expected map to not be empty after setting a value"
);
assert_eq!(
map.count(),
1,
"Expected map to have count of 1 after setting one value"
);
assert_eq!(
map.get(Three::B),
Some(&200),
"Expected get() to return the set value"
);
assert_eq!(
map.get(Three::A),
None,
"Expected get() to return None for unset key"
);
assert_eq!(
map.get(Three::C),
None,
"Expected get() to return None for unset key"
);
let old_value = map.set(Three::B, Some(300));
assert_eq!(
old_value,
Some(200),
"Expected set() to return previous value when overwriting"
);
assert_eq!(
map.get(Three::B),
Some(&300),
"Expected get() to return the new value"
);
assert_eq!(
map.count(),
1,
"Expected count to remain 1 after overwriting"
);
let old_value = map.set(Three::B, None);
assert_eq!(
old_value,
Some(300),
"Expected set(None) to return previous value"
);
assert_eq!(
map.get(Three::B),
None,
"Expected get() to return None after setting to None"
);
assert!(
map.is_empty(),
"Expected map to be empty after setting only value to None"
);
assert_eq!(
map.count(),
0,
"Expected count to be 0 after removing only value"
);
}
#[test]
fn test_insert_and_remove() {
let mut map = EnumOptionMap::<Three, i32>::new();
let old_value = map.insert(Three::A, 100);
assert_eq!(
old_value, None,
"Expected insert() to return None for new key"
);
assert_eq!(
map.get(Three::A),
Some(&100),
"Expected get() to return inserted value"
);
assert_eq!(map.count(), 1, "Expected count to be 1 after insert");
let old_value = map.insert(Three::A, 200);
assert_eq!(
old_value,
Some(100),
"Expected insert() to return previous value when overwriting"
);
assert_eq!(
map.get(Three::A),
Some(&200),
"Expected get() to return new inserted value"
);
assert_eq!(
map.count(),
1,
"Expected count to remain 1 after overwriting"
);
let removed_value = map.remove(Three::A);
assert_eq!(
removed_value,
Some(200),
"Expected remove() to return the removed value"
);
assert_eq!(
map.get(Three::A),
None,
"Expected get() to return None after removal"
);
assert_eq!(map.count(), 0, "Expected count to be 0 after removal");
assert!(
map.is_empty(),
"Expected map to be empty after removing only value"
);
let removed_value = map.remove(Three::B);
assert_eq!(
removed_value, None,
"Expected remove() to return None for non-existent key"
);
}
#[test]
fn test_insert_remove_by_index() {
let mut map = EnumOptionMap::<Three, i32>::new();
let old_value = map.insert_by_index(Three::A.into(), 42);
assert_eq!(
old_value, None,
"Expected insert_by_index() to return None for new index"
);
assert_eq!(
map.get_by_index(Three::A.into()),
Some(&42),
"Expected get_by_index() to return inserted value"
);
let removed_value = map.remove_by_index(Three::A.into());
assert_eq!(
removed_value,
Some(42),
"Expected remove_by_index() to return the removed value"
);
assert_eq!(
map.get_by_index(Three::A.into()),
None,
"Expected get_by_index() to return None after removal"
);
let removed_value = map.remove_by_index(Three::B.into());
assert_eq!(
removed_value, None,
"Expected remove_by_index() to return None for non-existent index"
);
}
#[test]
fn test_clear() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 10);
map.insert(Three::B, 20);
map.insert(Three::C, 30);
assert!(!map.is_empty(), "Expected map to not be empty before clear");
assert_eq!(map.count(), 3, "Expected count to be 3 before clear");
map.clear();
assert!(map.is_empty(), "Expected map to be empty after clear");
assert_eq!(map.count(), 0, "Expected count to be 0 after clear");
assert_eq!(
map.get(Three::A),
None,
"Expected get() to return None after clear"
);
assert_eq!(
map.get(Three::B),
None,
"Expected get() to return None after clear"
);
assert_eq!(
map.get(Three::C),
None,
"Expected get() to return None after clear"
);
}
#[test]
fn test_contains() {
let mut map = EnumOptionMap::<Three, i32>::new();
assert!(
!map.contains(Three::A),
"Expected empty map to not contain Three::A"
);
assert!(
!map.contains(Three::B),
"Expected empty map to not contain Three::B"
);
assert!(
!map.contains(Three::C),
"Expected empty map to not contain Three::C"
);
map.insert(Three::B, 100);
assert!(
!map.contains(Three::A),
"Expected map to not contain Three::A"
);
assert!(map.contains(Three::B), "Expected map to contain Three::B");
assert!(
!map.contains(Three::C),
"Expected map to not contain Three::C"
);
assert!(
!map.contains_index(Three::A.into()),
"Expected map to not contain index A"
);
assert!(
map.contains_index(Three::B.into()),
"Expected map to contain index B"
);
assert!(
!map.contains_index(Three::C.into()),
"Expected map to not contain index C"
);
}
#[test]
fn test_keys() {
let mut map = EnumOptionMap::<Three, i32>::new();
let keys = map.keys();
assert!(
!keys.contains(Three::A),
"Expected empty map keys to not contain Three::A"
);
assert!(
!keys.contains(Three::B),
"Expected empty map keys to not contain Three::B"
);
assert!(
!keys.contains(Three::C),
"Expected empty map keys to not contain Three::C"
);
map.insert(Three::A, 10);
map.insert(Three::C, 30);
let keys = map.keys();
assert!(keys.contains(Three::A), "Expected keys to contain Three::A");
assert!(
!keys.contains(Three::B),
"Expected keys to not contain Three::B"
);
assert!(keys.contains(Three::C), "Expected keys to contain Three::C");
}
#[test]
fn test_full_state() {
let mut map = EnumOptionMap::<Three, i32>::new();
assert!(!map.is_full(), "Expected map to not be full initially");
map.insert(Three::A, 10);
assert!(
!map.is_full(),
"Expected map to not be full with 1/3 values"
);
map.insert(Three::B, 20);
assert!(
!map.is_full(),
"Expected map to not be full with 2/3 values"
);
map.insert(Three::C, 30);
assert!(map.is_full(), "Expected map to be full with 3/3 values");
map.remove(Three::B);
assert!(
!map.is_full(),
"Expected map to not be full after removing a value"
);
}
#[test]
fn test_is_vec() {
let mut map = EnumOptionMap::<Three, i32>::new();
assert_eq!(
map.is_vec(),
EnumSize::from_usize(0),
"Expected empty map to be representable as 0-length vector"
);
map.insert(Three::A, 10);
assert_eq!(
map.is_vec(),
EnumSize::from_usize(1),
"Expected [A] to be representable as 1-length vector"
);
map.insert(Three::B, 20);
assert_eq!(
map.is_vec(),
EnumSize::from_usize(2),
"Expected [A,B] to be representable as 2-length vector"
);
map.insert(Three::C, 30);
assert_eq!(
map.is_vec(),
EnumSize::from_usize(3),
"Expected [A,B,C] to be representable as 3-length vector"
);
map.remove(Three::B);
assert_eq!(
map.is_vec(),
None,
"Expected [A,_,C] to not be representable as vector"
);
map.remove(Three::A);
assert_eq!(
map.is_vec(),
None,
"Expected [_,_,C] to not be representable as vector"
);
}
#[test]
fn test_eq() {
let mut a = EnumOptionMap::<Three, i32>::new();
a.insert(Three::A, 10);
a.insert(Three::C, 30);
let mut b = EnumOptionMap::<Three, i32>::new();
b.insert(Three::A, 10);
b.insert(Three::C, 30);
assert_eq!(a, b, "Expected maps with identical entries to be equal");
let mut differing_value = EnumOptionMap::<Three, i32>::new();
differing_value.insert(Three::A, 10);
differing_value.insert(Three::C, 99);
assert_ne!(
a, differing_value,
"Expected maps with a differing value to be unequal"
);
let mut differing_presence = EnumOptionMap::<Three, i32>::new();
differing_presence.insert(Three::A, 10);
assert_ne!(
a, differing_presence,
"Expected maps with differing presence to be unequal"
);
}
#[test]
fn test_mutable_get() {
let mut map = EnumOptionMap::<Three, i32>::new();
assert_eq!(
map.get_mut(Three::A),
None,
"Expected get_mut() to return None for empty map"
);
map.insert(Three::A, 100);
let value_mut = map
.get_mut(Three::A)
.expect("Expected get_mut to return Some for existing key");
*value_mut += 50;
assert_eq!(
map.get(Three::A),
Some(&150),
"Expected value to be modified through get_mut()"
);
let value_mut = map
.get_by_index_mut(Three::A.into())
.expect("Expected get_by_index_mut to return Some for existing key");
*value_mut *= 2;
assert_eq!(
map.get(Three::A),
Some(&300),
"Expected value to be modified through get_by_index_mut()"
);
}
#[test]
fn test_iteration_present_elements() {
let mut map = EnumOptionMap::<Three, i32>::new();
let collected: Vec<_> = map.iter().collect();
assert_eq!(collected, vec![], "Expected empty iteration for empty map");
map.insert(Three::A, 10);
map.insert(Three::C, 30);
let collected: Vec<_> = map.iter().collect();
assert_eq!(
collected,
vec![(Three::A, &10), (Three::C, &30)],
"Expected iteration to yield inserted values in order"
);
for (_, value) in map.iter_mut() {
*value *= 10;
}
let collected: Vec<_> = map.iter().collect();
assert_eq!(
collected,
vec![(Three::A, &100), (Three::C, &300)],
"Expected values to be modified through iter_mut()"
);
}
#[test]
fn test_iterator_exact_size_and_double_ended() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 10);
map.insert(Three::C, 30);
let mut iter = map.iter();
assert_eq!(
iter.size_hint().0,
2,
"Expected correct size hint lower bound"
);
assert_eq!(
iter.nth(1),
Some((Three::C, &30)),
"Expected nth(1) to return second element"
);
assert_eq!(map.iter().count(), 2, "Expected iterator count to be 2");
let empty_map = EnumOptionMap::<Three, i32>::new();
let empty_iter = empty_map.iter();
assert_eq!(
empty_iter.size_hint().0,
0,
"Expected empty iterator lower bound to be 0"
);
}
#[test]
fn test_iterator_partial_consumption() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 10);
map.insert(Three::B, 20);
map.insert(Three::C, 30);
let mut iter = map.iter();
assert_eq!(iter.next(), Some((Three::A, &10)), "Expected first element");
let remaining: Vec<_> = iter.collect();
assert_eq!(
remaining,
vec![(Three::B, &20), (Three::C, &30)],
"Expected remaining elements after partial consumption"
);
}
#[test]
fn test_iterator_single_element() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::B, 42);
let collected: Vec<_> = map.iter().collect();
assert_eq!(
collected,
vec![(Three::B, &42)],
"Expected single element iteration"
);
let mut iter = map.iter();
assert_eq!(
iter.next(),
Some((Three::B, &42)),
"Expected single element"
);
assert_eq!(iter.next(), None, "Expected iterator to be exhausted");
}
#[test]
fn test_swap_present_with_present() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 10);
map.insert(Three::C, 30);
map.swap(Three::A, Three::C);
assert_eq!(
map.get(Three::A),
Some(&30),
"Expected swapped value for Three::A"
);
assert_eq!(
map.get(Three::C),
Some(&10),
"Expected swapped value for Three::C"
);
assert_eq!(map.count(), 2, "Expected count to remain 2 after swap");
}
#[test]
fn test_swap_by_index_present_with_present() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 15);
map.insert(Three::B, 25);
map.swap_by_index(Three::A.into(), Three::B.into());
assert_eq!(
map.get(Three::A),
Some(&25),
"Expected swapped value for Three::A after swap_by_index"
);
assert_eq!(
map.get(Three::B),
Some(&15),
"Expected swapped value for Three::B after swap_by_index"
);
assert_eq!(
map.count(),
2,
"Expected count to remain 2 after swap_by_index"
);
}
#[test]
fn test_swap_present_with_absent() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 100);
map.swap(Three::A, Three::B);
assert_eq!(
map.get(Three::A),
None,
"Expected Three::A to become absent after swapping into an empty slot"
);
assert_eq!(
map.get(Three::B),
Some(&100),
"Expected Three::B to receive the value after swap"
);
assert_eq!(map.count(), 1, "Expected count to remain 1 after swap");
}
#[test]
fn test_swap_by_index_present_with_absent() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::C, 200);
map.swap_by_index(Three::C.into(), Three::A.into());
assert_eq!(
map.get(Three::C),
None,
"Expected Three::C to become absent after swapping into an empty slot"
);
assert_eq!(
map.get(Three::A),
Some(&200),
"Expected Three::A to receive the value after swap_by_index"
);
assert_eq!(
map.count(),
1,
"Expected count to remain 1 after swap_by_index"
);
}
#[test]
fn test_from_iterator() {
let map: EnumOptionMap<Three, i32> =
[(Three::A, 10), (Three::C, 30)].into_iter().collect();
assert_eq!(map.get(Three::A), Some(&10), "Expected value for A");
assert_eq!(map.get(Three::B), None, "Expected absent key B");
assert_eq!(map.get(Three::C), Some(&30), "Expected value for C");
assert_eq!(map.count(), 2, "Expected count to be 2 after collecting");
}
#[test]
fn test_extend() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 10);
map.extend([(Three::A, 99), (Three::C, 30)]);
assert_eq!(
map.get(Three::A),
Some(&99),
"Expected overridden value for A"
);
assert_eq!(map.get(Three::B), None, "Expected absent key B");
assert_eq!(
map.get(Three::C),
Some(&30),
"Expected extended value for C"
);
assert_eq!(map.count(), 2, "Expected count to be 2 after extending");
}
#[test]
fn test_from_iterator_duplicate_keys_take_last() {
let map: EnumOptionMap<Three, i32> =
[(Three::A, 10), (Three::A, 99)].into_iter().collect();
assert_eq!(
map.get(Three::A),
Some(&99),
"Expected the last value for a duplicated key"
);
assert_eq!(
map.count(),
1,
"Expected count to be 1 despite duplicate keys"
);
}
#[test]
fn test_from_iterator_empty() {
let map: EnumOptionMap<Three, i32> = std::iter::empty().collect();
assert!(map.is_empty(), "Expected empty map from empty iterator");
assert_eq!(map.count(), 0, "Expected count of 0 from empty iterator");
}
#[test]
fn test_into_iterator_owned() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 10);
map.insert(Three::C, 30);
let collected: Vec<(Three, i32)> = map.into_iter().collect();
assert_eq!(
collected,
vec![(Three::A, 10), (Three::C, 30)],
"Expected consuming iteration to yield only populated pairs in order"
);
}
#[test]
fn test_into_iterator_owned_roundtrips() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 10);
map.insert(Three::C, 30);
let roundtripped: EnumOptionMap<Three, i32> = map.into_iter().collect();
let mut expected = EnumOptionMap::<Three, i32>::new();
expected.insert(Three::A, 10);
expected.insert(Three::C, 30);
assert_eq!(
roundtripped, expected,
"Expected into_iter().collect() to round-trip"
);
}
#[test]
fn test_into_iterator_owned_empty() {
let map = EnumOptionMap::<Three, i32>::new();
let collected: Vec<(Three, i32)> = map.into_iter().collect();
assert_eq!(
collected,
vec![],
"Expected empty consuming iteration for empty map"
);
}
#[test]
fn test_into_iterator_by_ref() {
let mut map = EnumOptionMap::<Three, i32>::new();
map.insert(Three::A, 10);
map.insert(Three::C, 30);
let collected: Vec<(Three, &i32)> = (&map).into_iter().collect();
assert_eq!(
collected,
vec![(Three::A, &10), (Three::C, &30)],
"Expected &EnumOptionMap iteration to yield populated pairs"
);
for (_, value) in &mut map {
*value += 1;
}
assert_eq!(
map.get(Three::A),
Some(&11),
"Expected value mutated via &mut"
);
assert_eq!(
map.get(Three::C),
Some(&31),
"Expected value mutated via &mut"
);
}
#[test]
fn test_into_iterator_owned_drops_only_populated_when_consumed() {
let drops = Cell::new(0);
let mut map = EnumOptionMap::<Three, DropTracker>::new();
map.insert(Three::A, DropTracker::new(1, &drops));
map.insert(Three::C, DropTracker::new(3, &drops));
let ids: Vec<i32> = map.into_iter().map(|(_, v)| v.id()).collect();
assert_eq!(ids, vec![1, 3], "Expected ids of populated keys in order");
assert_eq!(
drops.get(),
2,
"Expected only the two populated values to be dropped"
);
}
#[test]
fn test_into_iterator_owned_drops_remainder_when_abandoned() {
let drops = Cell::new(0);
let mut map = EnumOptionMap::<Three, DropTracker>::new();
map.insert(Three::A, DropTracker::new(1, &drops));
map.insert(Three::C, DropTracker::new(3, &drops));
let mut iter = map.into_iter();
{
let (key, value) = iter.next().expect("Expected a first pair");
assert_eq!(key, Three::A, "Expected first populated key");
assert_eq!(value.id(), 1, "Expected first value id");
assert_eq!(drops.get(), 0, "Expected no drops while value is held");
}
assert_eq!(drops.get(), 1, "Expected the moved-out value to drop");
drop(iter);
assert_eq!(
drops.get(),
2,
"Expected the remaining populated value to drop when abandoned"
);
}