use crate::*;
use flo_rope::*;
use futures::executor;
use futures::prelude::*;
use std::sync::*;
#[test]
fn mutable_rope_sends_changes_to_stream() {
let mutable_rope = RopeBindingMut::<usize, ()>::new();
let mut rope_stream = mutable_rope.follow_changes();
mutable_rope.replace(0..0, vec![1, 2, 3, 4]);
executor::block_on(async move {
let next = rope_stream.next().await;
assert!(next == Some(RopeAction::Replace(0..0, vec![1,2,3,4])));
});
}
#[test]
fn watch_mutable_rope() {
let mutable_rope = RopeBindingMut::<usize, ()>::new();
let change_count = bind(0);
let change_counter = change_count.clone();
let watcher = mutable_rope.watch(notify(move || change_counter.set(change_counter.get() + 1)));
let mut rope_stream = mutable_rope.follow_changes();
mutable_rope.replace(0..0, vec![1, 2, 3, 4]);
executor::block_on(async { rope_stream.next().await });
assert!(change_count.get() == 0);
watcher.get();
mutable_rope.replace(0..4, vec![1, 2, 3, 4, 5]);
executor::block_on(async { rope_stream.next().await });
assert!(change_count.get() == 1);
mutable_rope.replace(0..5, vec![1, 2, 3, 4]);
executor::block_on(async { rope_stream.next().await });
assert!(change_count.get() == 1);
}
#[test]
fn pull_from_mutable_binding() {
let mutable_rope = RopeBindingMut::<usize, ()>::new();
let rope_copy = RopeBinding::from_stream(mutable_rope.follow_changes());
let mut rope_stream = rope_copy.follow_changes();
mutable_rope.replace(0..0, vec![1, 2, 3, 4]);
executor::block_on(async move {
let next = rope_stream.next().await;
assert!(next == Some(RopeAction::Replace(0..0, vec![1,2,3,4])))
});
assert!(rope_copy.len() == 4);
assert!(rope_copy.read_cells(0..4).collect::<Vec<_>>() == vec![1, 2, 3, 4]);
}
#[test]
fn concatenate_ropes() {
let lhs = RopeBindingMut::<usize, ()>::new();
let rhs = RopeBindingMut::<usize, ()>::new();
let chain = lhs.chain(&rhs);
let mut follow_chain = chain.follow_changes();
lhs.replace(0..0, vec![1, 2, 3]);
executor::block_on(async { follow_chain.next().await });
println!("{:?}", chain.read_cells(0..3).collect::<Vec<_>>());
assert!(chain.read_cells(0..3).collect::<Vec<_>>() == vec![1, 2, 3]);
rhs.replace(0..0, vec![10, 11, 12]);
executor::block_on(async { follow_chain.next().await });
println!("{:?}", chain.read_cells(0..6).collect::<Vec<_>>());
assert!(chain.read_cells(0..6).collect::<Vec<_>>() == vec![1, 2, 3, 10, 11, 12]);
lhs.replace(1..2, vec![4, 5, 6]);
executor::block_on(async { follow_chain.next().await });
println!("{:?}", chain.read_cells(0..8).collect::<Vec<_>>());
assert!(chain.read_cells(0..8).collect::<Vec<_>>() == vec![1, 4, 5, 6, 3, 10, 11, 12]);
rhs.replace(1..2, vec![20, 21, 22]);
executor::block_on(async { follow_chain.next().await });
println!("{:?}", chain.read_cells(0..10).collect::<Vec<_>>());
assert!(chain.read_cells(0..10).collect::<Vec<_>>() == vec![1, 4, 5, 6, 3, 10, 20, 21, 22, 12]);
}
#[test]
fn map_ropes() {
let rope = RopeBindingMut::<usize, ()>::new();
rope.replace(0..0, vec![1, 2, 3]);
let add_one = rope.map(|val| val+1);
let mut follow_add = add_one.follow_changes();
executor::block_on(async { follow_add.next().await });
assert!(add_one.read_cells(0..3).collect::<Vec<_>>() == vec![2, 3, 4]);
rope.replace(1..1, vec![8, 9, 10]);
executor::block_on(async { follow_add.next().await });
assert!(add_one.read_cells(0..6).collect::<Vec<_>>() == vec![2, 9, 10, 11, 3, 4]);
}
#[test]
fn watch_computed_rope() {
let length = bind(0);
let length_copy = length.clone();
let rope = RopeBinding::<_, ()>::computed(move || (0..length_copy.get()).into_iter().map(|idx| idx));
let change_count = bind(0);
let change_counter = change_count.clone();
let watcher = rope.watch(notify(move || change_counter.set(change_counter.get() + 1)));
let mut follow_rope = rope.follow_changes();
length.set(1);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 1);
assert!(change_count.get() == 0);
watcher.get();
length.set(3);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 3);
assert!(change_count.get() == 1);
length.set(2);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 2);
assert!(change_count.get() == 1);
watcher.get();
length.set(10);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 10);
assert!(change_count.get() == 2);
}
#[test]
fn computed_rope() {
let length = bind(0);
let length_copy = length.clone();
let rope = RopeBinding::<_, ()>::computed(move || (0..length_copy.get()).into_iter().map(|idx| idx));
let mut follow_rope = rope.follow_changes();
length.set(1);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 1);
assert!(rope.read_cells(0..1).collect::<Vec<_>>() == vec![0]);
length.set(3);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 3);
assert!(rope.read_cells(0..3).collect::<Vec<_>>() == vec![0, 1, 2]);
length.set(2);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 2);
assert!(rope.read_cells(0..2).collect::<Vec<_>>() == vec![0, 1]);
length.set(10);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 10);
assert!(rope.read_cells(0..10).collect::<Vec<_>>() == vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
#[test]
fn computed_rope_using_diffs_1() {
let length = bind(0);
let length_copy = length.clone();
let rope = RopeBinding::<_, ()>::computed_difference(move || (0..length_copy.get()).into_iter().map(|idx| idx));
let mut follow_rope = rope.follow_changes();
length.set(1);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 1);
assert!(rope.read_cells(0..1).collect::<Vec<_>>() == vec![0]);
length.set(3);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 3);
assert!(rope.read_cells(0..3).collect::<Vec<_>>() == vec![0, 1, 2]);
length.set(2);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 2);
assert!(rope.read_cells(0..2).collect::<Vec<_>>() == vec![0, 1]);
length.set(10);
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 10);
assert!(rope.read_cells(0..10).collect::<Vec<_>>() == vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
#[test]
fn computed_rope_using_diffs_2() {
let length = bind(0);
let length_copy = length.clone();
let rope = RopeBinding::<_, ()>::computed_difference(move || (0..length_copy.get()).into_iter().map(|idx| idx));
let mut follow_rope = rope.follow_changes();
length.set(1);
let diff = executor::block_on(async { follow_rope.next().await });
assert!(diff == Some(RopeAction::Replace(0..0, vec![0])));
length.set(3);
let diff = executor::block_on(async { follow_rope.next().await });
assert!(diff == Some(RopeAction::Replace(1..1, vec![1, 2])));
length.set(2);
let diff = executor::block_on(async { follow_rope.next().await });
assert!(diff == Some(RopeAction::Replace(2..3, vec![])));
length.set(10);
let diff = executor::block_on(async { follow_rope.next().await });
assert!(diff == Some(RopeAction::Replace(2..2, vec![2, 3, 4, 5, 6, 7, 8, 9])));
}
#[test]
fn computed_rope_using_diffs_3() {
let items = bind(vec![]);
let items_copy = items.clone();
let rope = RopeBinding::<_, ()>::computed_difference(move || items_copy.get());
let mut follow_rope = rope.follow_changes();
let val = vec![1, 1, 1, 1];
items.set(val.clone());
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == val.len());
assert!(rope.read_cells(0..val.len()).collect::<Vec<_>>() == val);
let val = vec![1, 1, 2, 2, 1, 1, 3, 3];
items.set(val.clone());
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == val.len());
assert!(rope.read_cells(0..val.len()).collect::<Vec<_>>() == val);
let val = vec![1, 1, 1, 1];
items.set(val.clone());
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == val.len());
assert!(rope.read_cells(0..val.len()).collect::<Vec<_>>() == val);
let val = vec![1, 2, 1, 3, 3, 1, 4, 4, 4, 1, 5, 5, 5, 5];
items.set(val.clone());
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == val.len());
assert!(rope.read_cells(0..val.len()).collect::<Vec<_>>() == val);
let val = vec![1, 1, 1, 1];
items.set(val.clone());
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == val.len());
assert!(rope.read_cells(0..val.len()).collect::<Vec<_>>() == val);
}
#[test]
fn bind_rope_length_to_computed() {
let items = bind(vec![]);
let items_copy = items.clone();
let rope = RopeBinding::<_, ()>::computed_difference(move || items_copy.get());
let rope_copy = rope.clone();
let rope_length = computed(move || rope_copy.len());
let mut follow_rope = rope.follow_changes();
assert!(rope_length.get() == 0);
let is_changed = Arc::new(Mutex::new(false));
let is_changed_copy = is_changed.clone();
rope_length.when_changed(notify(move || *is_changed_copy.lock().unwrap() = true)).keep_alive();
let val = vec![1, 1, 1, 1];
items.set(val.clone());
executor::block_on(async { follow_rope.next().await });
assert!(rope.len() == 4);
assert!(rope_length.get() == 4);
assert!(*is_changed.lock().unwrap() == true);
}
#[test]
fn bind_rope_mut_length_to_computed() {
let rope = RopeBindingMut::<_, ()>::new();
let rope_copy = rope.clone();
let rope_length = computed(move || rope_copy.len());
let mut follow_rope = rope.follow_changes();
assert!(rope_length.get() == 0);
let is_changed = Arc::new(Mutex::new(false));
let is_changed_copy = is_changed.clone();
rope_length.when_changed(notify(move || *is_changed_copy.lock().unwrap() = true)).keep_alive();
let val = vec![1, 1, 1, 1];
rope.replace(0..0, val);
executor::block_on(async { follow_rope.next().await });
rope.len();
assert!(rope_length.get() == 4);
assert!(*is_changed.lock().unwrap() == true);
}
#[test]
fn bind_rope_read_cells_to_computed() {
let items = bind(vec![]);
let items_copy = items.clone();
let rope = RopeBinding::<_, ()>::computed_difference(move || items_copy.get());
let rope_copy = rope.clone();
let rope_cells = computed(move || rope_copy.read_cells(0..2).collect::<Vec<_>>());
let mut follow_rope = rope.follow_changes();
assert!(rope_cells.get() == vec![]);
let is_changed = Arc::new(Mutex::new(false));
let is_changed_copy = is_changed.clone();
rope_cells.when_changed(notify(move || *is_changed_copy.lock().unwrap() = true)).keep_alive();
let val = vec![1, 1, 1, 1];
items.set(val.clone());
executor::block_on(async { follow_rope.next().await });
rope.len();
assert!(rope_cells.get() == vec![1,1]);
assert!(*is_changed.lock().unwrap() == true);
}
#[test]
fn bind_rope_mut_read_cells_to_computed() {
let rope = RopeBindingMut::<_, ()>::new();
let rope_copy = rope.clone();
let rope_cells = computed(move || rope_copy.read_cells(0..2).collect::<Vec<_>>());
let mut follow_rope = rope.follow_changes();
assert!(rope_cells.get() == vec![]);
let is_changed = Arc::new(Mutex::new(false));
let is_changed_copy = is_changed.clone();
rope_cells.when_changed(notify(move || *is_changed_copy.lock().unwrap() = true)).keep_alive();
let val = vec![1, 1, 1, 1];
rope.replace(0..0, val);
executor::block_on(async { follow_rope.next().await });
rope.len();
assert!(rope_cells.get() == vec![1,1]);
assert!(*is_changed.lock().unwrap() == true);
}
#[test]
fn following_rope_generates_when_changed() {
let rope = RopeBindingMut::<_, ()>::new();
let following_rope = RopeBinding::from_stream(rope.follow_changes());
let rope_copy = following_rope.clone();
let rope_cells = computed(move || rope_copy.read_cells(0..2).collect::<Vec<_>>());
let mut follow_rope = following_rope.follow_changes();
assert!(rope_cells.get() == vec![]);
let is_changed = Arc::new(Mutex::new(false));
let is_changed_copy = is_changed.clone();
rope_cells.when_changed(notify(move || *is_changed_copy.lock().unwrap() = true)).keep_alive();
let val = vec![1, 1, 1, 1];
rope.replace(0..0, val);
executor::block_on(async { follow_rope.next().await });
rope.len();
following_rope.len();
assert!(*is_changed.lock().unwrap() == true);
assert!(rope_cells.get() == vec![1,1]);
}
#[test]
fn retain_cells_1() {
let rope = RopeBindingMut::<_, ()>::new();
rope.replace(0..0, 0..10);
rope.retain_cells(|x| (x%2) == 0);
assert!(rope.len() == 5);
assert!(rope.read_cells(0..5).collect::<Vec<_>>() == vec![0, 2, 4, 6, 8]);
}
#[test]
fn retain_cells_2() {
let rope = RopeBindingMut::<_, ()>::new();
rope.replace(0..0, 0..10);
rope.retain_cells(|x| (x%2) == 1);
assert!(rope.len() == 5);
assert!(rope.read_cells(0..5).collect::<Vec<_>>() == vec![1, 3, 5, 7, 9]);
}
#[test]
fn retain_cells_3() {
let rope = RopeBindingMut::<_, ()>::new();
rope.replace(0..0, 0..10);
rope.retain_cells(|x| *x < 1 || *x > 8);
assert!(rope.len() == 2);
assert!(rope.read_cells(0..5).collect::<Vec<_>>() == vec![0, 9]);
}
#[test]
fn retain_cells_4() {
let rope = RopeBindingMut::<_, ()>::new();
rope.replace(0..0, 0..10);
rope.retain_cells(|x| *x < 5);
assert!(rope.len() == 5);
assert!(rope.read_cells(0..5).collect::<Vec<_>>() == vec![0, 1, 2, 3, 4]);
}
#[test]
fn retain_cells_5() {
let rope = RopeBindingMut::<_, ()>::new();
rope.replace(0..0, 0..10);
rope.retain_cells(|x| *x >= 5);
assert!(rope.len() == 5);
assert!(rope.read_cells(0..5).collect::<Vec<_>>() == vec![5, 6, 7, 8, 9]);
}