use crate::collection::{
Block, BlocksDeque, ExpansionTy::Additional, Vector, blocks_deque::BlockRef,
};
#[test]
fn expand_back() {
let mut bq = BlocksDeque::with_exact_capacity(2, 8).unwrap();
let _ = bq.expand_back(Additional(4), (), 1).unwrap();
assert_eq!(bq.as_slices(), (&[1, 1, 1, 1][..], &[][..]));
}
#[test]
fn get_empty_considers_zeroed_capacity() {
let mut bq = BlocksDeque::<i32, ()>::new();
bq.push_back_from_copyable_data([], ()).unwrap();
assert_eq!(bq.get(0), Some(Block { data: &[][..], misc: &(), range: 0..0 }));
}
#[test]
fn pop_back() {
let mut bq = BlocksDeque::with_exact_capacity(4, 8).unwrap();
check_state(&bq, 0, 0, &[], &[]);
bq.push_front_from_copyable_data([&[1][..]], ()).unwrap();
check_state(&bq, 1, 1, &[1], &[]);
bq.push_front_from_copyable_data([&[2, 3][..]], ()).unwrap();
check_state(&bq, 2, 3, &[2, 3, 1], &[]);
bq.push_front_from_copyable_data([&[4, 5], &[6][..]], ()).unwrap();
check_state(&bq, 3, 6, &[4, 5, 6, 2, 3, 1], &[]);
bq.push_front_from_copyable_data([&[7, 8][..]], ()).unwrap();
check_state(&bq, 4, 8, &[7, 8, 4, 5, 6, 2, 3, 1], &[]);
let _ = bq.pop_back();
check_state(&bq, 3, 7, &[7, 8, 4, 5, 6, 2, 3], &[]);
bq.push_front_from_copyable_data([&[9][..]], ()).unwrap();
check_state(&bq, 4, 8, &[9], &[7, 8, 4, 5, 6, 2, 3]);
let _ = bq.pop_back();
check_state(&bq, 3, 6, &[9], &[7, 8, 4, 5, 6]);
let _ = bq.pop_back();
check_state(&bq, 2, 3, &[9], &[7, 8]);
bq.push_front_from_copyable_data([&[10], &[11, 12][..]], ()).unwrap();
check_state(&bq, 3, 6, &[10, 11, 12, 9], &[7, 8]);
bq.push_front_from_copyable_data([&[13, 14][..]], ()).unwrap();
check_state(&bq, 4, 8, &[13, 14, 10, 11, 12, 9], &[7, 8]);
let _ = bq.pop_back();
check_state(&bq, 3, 6, &[13, 14, 10, 11, 12, 9], &[]);
let _ = bq.pop_back();
check_state(&bq, 2, 5, &[13, 14, 10, 11, 12], &[]);
let _ = bq.pop_back();
check_state(&bq, 1, 2, &[13, 14], &[]);
bq.push_front_from_copyable_data([&[15][..]], ()).unwrap();
check_state(&bq, 2, 3, &[15, 13, 14], &[]);
bq.push_front_from_copyable_data([&[16][..]], ()).unwrap();
check_state(&bq, 3, 4, &[16, 15, 13, 14], &[]);
let _ = bq.pop_back();
check_state(&bq, 2, 2, &[16, 15], &[]);
let _ = bq.pop_back();
check_state(&bq, 1, 1, &[16], &[]);
let _ = bq.pop_back();
check_state(&bq, 0, 0, &[], &[]);
}
#[test]
fn pop_front() {
let mut bq = BlocksDeque::with_exact_capacity(2, 8).unwrap();
check_state(&bq, 0, 0, &[], &[]);
bq.push_front_from_copyable_data([&[1, 2, 3][..]], ()).unwrap();
check_state(&bq, 1, 3, &[1, 2, 3], &[]);
bq.push_front_from_copyable_data([&[4, 5], &[6, 7, 8][..]], ()).unwrap();
check_state(&bq, 2, 8, &[4, 5, 6, 7, 8, 1, 2, 3], &[]);
let _ = bq.pop_front();
check_state(&bq, 1, 3, &[1, 2, 3], &[]);
let _ = bq.pop_front();
check_state(&bq, 0, 0, &[], &[]);
}
#[test]
fn pop_front_to_buffer_updates_logical_begin() {
let mut bq = BlocksDeque::with_exact_capacity(2, 4).unwrap();
bq.push_back_from_copyable_data([&[1, 2][..]], ()).unwrap();
bq.push_back_from_copyable_data([&[3, 4][..]], ()).unwrap();
assert_eq!(bq.get(0).unwrap().data, &[1, 2]);
assert_eq!(bq.get(1).unwrap().data, &[3, 4]);
let mut buffer = Vector::new();
drop(bq.pop_front_to_buffer(&mut buffer));
assert_eq!(bq.blocks_len(), 1);
assert_eq!(bq.get(0).unwrap().data, &[3, 4]);
}
#[test]
fn push_reserve_and_push() {
let mut bq = BlocksDeque::new();
bq.reserve_front(1, 4).unwrap();
bq.push_front_from_copyable_data([&[0, 1, 2, 3][..]], ()).unwrap();
check_state(&bq, 1, 4, &[0, 1, 2, 3], &[]);
assert_eq!(bq.get(0), Some(BlockRef { data: &[0, 1, 2, 3], misc: &(), range: 0..4 }));
assert_eq!(bq.get(1), None);
bq.reserve_front(1, 6).unwrap();
bq.push_front_from_copyable_data([&[4, 5, 6, 7, 8, 9][..]], ()).unwrap();
check_state(&bq, 2, 10, &[4, 5, 6, 7, 8, 9, 0, 1, 2, 3], &[]);
assert_eq!(bq.get(0), Some(BlockRef { data: &[4, 5, 6, 7, 8, 9], misc: &(), range: 0..6 }));
assert_eq!(bq.get(1), Some(BlockRef { data: &[0, 1, 2, 3], misc: &(), range: 6..10 }));
assert_eq!(bq.get(2), None);
}
#[test]
fn reserve_does_not_corrupt_wrapped_data() {
let mut bq = BlocksDeque::with_exact_capacity(2, 4).expect("failed to create deque");
bq.push_back_from_copyable_data([&[10, 20][..]], ()).unwrap();
bq.push_front_from_copyable_data([&[30][..]], ()).unwrap();
assert_eq!(bq.get(0).unwrap().data, &[30]);
assert_eq!(bq.get(1).unwrap().data, &[10, 20]);
bq.reserve_front(0, 10).unwrap();
let block_front = bq.get(0).unwrap();
let block_back = bq.get(1).unwrap();
assert_eq!(block_front.data, &[30]);
assert_eq!(block_back.data, &[10, 20]);
}
#[test]
fn wrap_pop_back() {
let mut bq = wrap_initial();
let _ = bq.pop_back();
let _ = bq.pop_back();
check_state(&bq, 1, 3, &[1, 2, 3], &[]);
assert_eq!(bq.get(0).unwrap().data, &[1, 2, 3]);
let _ = bq.pop_back();
check_state(&bq, 0, 0, &[], &[]);
}
#[test]
fn wrap_pop_front() {
let mut bq = wrap_initial();
let _ = bq.pop_front();
check_state(&bq, 2, 2, &[0, 0], &[]);
assert_eq!(bq.get(0).unwrap().data, &[0]);
assert_eq!(bq.get(1).unwrap().data, &[0]);
let _ = bq.pop_front();
let _ = bq.pop_front();
check_state(&bq, 0, 0, &[], &[]);
}
fn wrap_initial() -> BlocksDeque<i32, ()> {
let mut bq = BlocksDeque::with_exact_capacity(6, 8).unwrap();
check_state(&bq, 0, 0, &[], &[]);
for _ in 0..6 {
bq.push_front_from_copyable_data([&[0][..]], ()).unwrap();
}
check_state(&bq, 6, 6, &[0, 0, 0, 0, 0, 0], &[]);
for idx in 0..6 {
assert_eq!(bq.get(idx).unwrap().data, &[0]);
}
let _ = bq.pop_back();
let _ = bq.pop_back();
let _ = bq.pop_back();
let _ = bq.pop_back();
check_state(&bq, 2, 2, &[0, 0], &[]);
assert_eq!(bq.get(0).unwrap().data, &[0]);
assert_eq!(bq.get(1).unwrap().data, &[0]);
bq.push_front_from_copyable_data([&[1, 2, 3][..]], ()).unwrap();
check_state(&bq, 3, 5, &[1, 2, 3, 0, 0], &[]);
assert_eq!(bq.get(0).unwrap().data, &[1, 2, 3]);
assert_eq!(bq.get(1).unwrap().data, &[0]);
assert_eq!(bq.get(2).unwrap().data, &[0]);
bq
}
#[track_caller]
fn check_state(
bq: &BlocksDeque<i32, ()>,
blocks_len: usize,
elements_len: usize,
front: &[i32],
back: &[i32],
) {
let (local_front, local_back) = bq.as_slices();
assert_eq!(bq.blocks_len(), blocks_len);
assert_eq!(bq.elements_len(), elements_len);
assert_eq!(front, local_front);
assert_eq!(back, local_back);
}