use rand::Rng;
#[allow(dead_code)]
mod common;
use btree_vec::BTreeVec;
use eips::Eips;
#[test]
fn get() {
const NUM_INSERT: usize = 1000;
const NUM_REMOVE: usize = 300;
const NUM_MOVE: usize = 250;
let mut rng = common::make_rng();
let mut items = BTreeVec::<u128, 16>::create();
let mut eips = Eips::<u128>::new();
for i in 0..NUM_INSERT {
let id = rng.random();
let index = rng.random_range(0..i + 1);
let change = eips.insert(index, id).unwrap();
assert_eq!(change.id, id);
eips.apply_change(change).unwrap();
items.insert(index, id);
}
let mut removed = Vec::new();
for i in 0..NUM_REMOVE {
let index = rng.random_range(0..NUM_INSERT - i);
let change = eips.remove(index).unwrap();
eips.apply_change(change).unwrap();
let id = items.remove(index);
assert_eq!(change.id, id);
removed.push(id);
}
const LEN: usize = NUM_INSERT - NUM_REMOVE;
for _ in 0..NUM_MOVE {
let old = rng.random_range(0..LEN);
let new = rng.random_range(0..LEN);
let id = rng.random();
let change = eips.mv(old, new, id).unwrap();
assert_eq!(change.id, id);
eips.apply_change(change).unwrap();
let old_id = items.remove(old);
items.insert(new, old_id);
}
for _ in 0..NUM_REMOVE {
let index = rng.random_range(0..LEN);
let change = eips.remove(index).unwrap();
assert_eq!(change.id, items[index]);
}
assert_eq!(eips.len(), LEN);
assert_eq!(items.len(), LEN);
for (i, id) in items.iter().copied().enumerate() {
assert_eq!(eips.get(i).unwrap(), id);
assert_eq!(eips.remote_get(&id).unwrap(), Some(i));
let (change, index) = eips.get_change(&id).unwrap();
assert_eq!(change.id, id);
assert_eq!(index, Some(i));
}
assert!(eips.get(LEN).is_err());
assert!(eips.remote_get(&rng.random()).is_err());
assert!(eips.get_change(&rng.random()).is_err());
for id in removed {
assert_eq!(eips.remote_get(&id).unwrap(), None);
let (change, index) = eips.get_change(&id).unwrap();
assert_eq!(change.id, id);
assert_eq!(index, None);
}
}
#[test]
fn malicious_move() {
use std::num::NonZeroU64;
let mut eips = Eips::<(u64, u64)>::new();
for i in 0..100 {
let change = eips.insert(i, (0, i as _)).unwrap();
eips.apply_change(change).unwrap();
}
for i in 0..10 {
let change = eips.mv(i * 10, 100 - i * 10 - 5, (1, i as _)).unwrap();
eips.apply_change(change).unwrap();
}
for i in 0..100 {
let change = eips.mv(i, (i * 2) % 100, (1, (i + 10) as _)).unwrap();
let mut bad = change;
bad.move_info.as_mut().unwrap().timestamp = NonZeroU64::new(match i {
20 => u64::MAX,
30 => u64::MAX - 1,
40 => u64::MAX / 2,
_ => (111 + i) as _,
})
.unwrap();
assert!(eips.apply_change(bad).is_err());
eips.apply_change(change).unwrap();
}
}
#[test]
fn duplicate_id() {
let mut eips = Eips::<(u64, u64)>::new();
let c1 = eips.insert(0, (0, 0)).unwrap();
let c2 = eips.insert(0, (1, 0)).unwrap();
eips.apply_change(c1).unwrap();
eips.apply_change(c2).unwrap();
let c3 = eips.insert(1, (2, 0)).unwrap();
let c4 = eips.insert(2, (2, 0)).unwrap();
eips.apply_change(c3).unwrap();
assert!(eips.apply_change(c4).is_err());
}