use vecshard::{ShardExt, VecShard};
#[test]
fn deref() {
let vec = vec![1, 2, 3, 4, 5, 6];
let (left, mut right) = vec.split_inplace_at(3);
assert_eq!(&*left, &[1, 2, 3]);
assert_eq!(right[0], 4);
right[0] = 5;
right[1] = 8;
right[2] = 13;
let fib = VecShard::merge(left, right);
assert_eq!(*fib, [1, 2, 3, 5, 8, 13]);
}
#[test]
fn vec_roundtrip() {
let vec = vec!["ja", "da", "meint", "der", "ich", "hät'", "abgeschmatzt"];
let shard = VecShard::from(vec.clone());
let vec2: Vec<_> = shard.into();
assert_eq!(vec, vec2);
}
#[test]
fn into_vecs() {
let (left, right) = vec![1, 11, 21, 12_11, 11_12_21, 31_22_11].split_inplace_at(3);
let lvec: Vec<_> = left.into();
let rvec: Vec<_> = right.into();
assert_eq!(lvec, [1, 11, 21]);
assert_eq!(rvec, [12_11, 11_12_21, 31_22_11]);
}
#[test]
fn things_get_dropped() {
use std::rc::Rc;
let rc = Rc::new(());
let rcs = vec![rc.clone(); 20];
let (left, right) = rcs.split_inplace_at(10);
std::mem::drop(left);
for x in right {
assert_eq!(*x, ());
}
Rc::try_unwrap(rc).unwrap();
}
#[test]
fn clone_works() {
let vec = vec![1, 2, 6, 24, 120];
let (left, _) = vec.split_inplace_at(3);
assert_eq!(left, left.clone());
assert_eq!(*left, [1, 2, 6]);
}
#[test]
fn hash_works() {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
fn get_hash<T: Hash>(t: &T) -> u64 {
let mut s = DefaultHasher::new();
t.hash(&mut s);
s.finish()
}
let vec = vec![1, 8, 7];
let (left, right) = vec.split_inplace_at(1);
assert!(get_hash(&left) != get_hash(&right));
assert_eq!(get_hash(&right), get_hash(&VecShard::from(vec![8, 7])));
}
#[test]
fn debug_looks_ok() {
use std::fmt::Write;
let shard = VecShard::from(vec![1, 3, 1, 2]);
let mut buf = String::with_capacity(16);
write!(buf, "{:?}", shard).unwrap();
assert_eq!(buf, "[1, 3, 1, 2]");
}
#[test]
fn lucky_merges() {
let dish = vec!["mashed potatoes", "liquor", "pie", "jellied eels"];
let clone = dish.clone();
let old_ptr = clone.as_ptr();
let (rest, right) = clone.split_inplace_at(2);
let (left, middle) = rest.split_inplace_at(1);
let eww = VecShard::merge_inplace(middle, right).unwrap();
let new_dish: Vec<_> = VecShard::merge_inplace(left, eww).unwrap().into();
let new_ptr = new_dish.as_ptr();
assert_eq!(dish, new_dish);
assert_eq!(old_ptr, new_ptr);
}
#[test]
fn unlucky_merges() {
use vecshard::error::{CantMerge, WouldMove::*};
let vec = vec![1, 3, 6, 10, 15, 21, 28, 36];
let (left, rest) = vec.clone().split_inplace_at(4);
let (middle, right) = rest.split_inplace_at(2);
let CantMerge {
left: right,
right: middle,
reason,
} = VecShard::merge_inplace(right, middle).unwrap_err();
assert_eq!(reason, WrongOrder);
let CantMerge {
left,
right,
reason,
} = VecShard::merge_noalloc(left, right).unwrap_err();
assert_eq!(reason.to_string(), "the two shards are not directly adjacent in memory and can't be moved around because there are still other shards in the Vec");
let CantMerge {
right: left,
reason,
..
} = VecShard::merge_inplace(middle, left).unwrap_err();
assert_eq!(
reason.to_string(),
"the two shards are adjacent, but were passed in the reverse order."
);
let CantMerge { left, reason, .. } = VecShard::merge_inplace(left, right).unwrap_err();
assert_eq!(
reason.to_string(),
"the two shards are not directly adjacent in memory."
);
let different = VecShard::from(vec![4, 5, 2, 5, 7]);
let err = VecShard::merge_inplace(left, different).unwrap_err();
assert_eq!(
err.to_string(),
"Can't perform quick merge because the two shards are not from the same memory allocation."
);
let err = VecShard::merge_noalloc(err.left, err.right).unwrap_err();
assert_eq!(
err.to_string(),
"Can't perform quick merge because the two shards are not from the same memory allocation."
);
}
#[test]
fn weird_merges() {
let vec = vec![1, 4, 9, 16, 25, 36, 49, 64];
let (left, right) = vec.clone().split_inplace_at(4);
let big = VecShard::merge(right, left);
assert_eq!(*big, [25, 36, 49, 64, 1, 4, 9, 16]);
let (left, rest) = vec.clone().split_inplace_at(4);
let (middle, right) = rest.split_inplace_at(2);
let outer = VecShard::merge(left, right);
let big = VecShard::merge(outer, middle);
assert_eq!(*big, [1, 4, 9, 16, 49, 64, 25, 36]);
let (left, rest) = vec.clone().split_inplace_at(4);
let (middle, right) = rest.split_inplace_at(2);
std::mem::drop(middle);
let outer = VecShard::merge(left, right);
assert_eq!(*outer, [1, 4, 9, 16, 49, 64]);
let (left, rest) = vec.clone().split_inplace_at(4);
let (middle, right) = rest.split_inplace_at(2);
std::mem::drop(middle);
let outer = VecShard::merge(right, left);
assert_eq!(*outer, [49, 64, 1, 4, 9, 16]);
let (rest, right) = vec.clone().split_inplace_at(4);
let (left, middle) = rest.split_inplace_at(2);
std::mem::drop(middle);
let outer = VecShard::merge(right, left);
assert_eq!(*outer, [25, 36, 49, 64, 1, 4]);
}
#[test]
fn backwards_iteration() {
let mut shard = VecShard::from(vec![0, 1, 2, 3, 4]);
assert_eq!(shard.next(), Some(0));
assert_eq!(shard.next_back(), Some(4));
assert_eq!(shard.next_back(), Some(3));
assert_eq!(shard.next(), Some(1));
assert_eq!(shard.next_back(), Some(2));
assert_eq!(shard.next_back(), None);
}
#[test]
fn lens_match_up() {
let s1 = VecShard::from(vec![]);
let s2 = VecShard::from(vec![0]);
let (s3, s4) = vec![0; 100].split_inplace_at(10);
let mut s5 = s3.clone();
s5.next();
s5.next_back();
for shard in &[s1, s2, s3, s4, s5] {
assert_eq!(shard.len(), ExactSizeIterator::len(shard));
assert_eq!(shard.len(), shard.size_hint().0);
assert_eq!(shard.len(), shard.size_hint().1.unwrap());
}
}