use super::*;
struct Buffer {
text: String,
}
struct View {
buffer: Handle<Buffer>,
seen_events: Vec<usize>,
}
struct Edited(usize);
#[test]
fn nested_updates_reach_other_entities() {
let mut entities = EntityMap::new();
let buffer = entities.insert(Buffer { text: String::new() });
let view = entities.insert(View { buffer, seen_events: Vec::new() });
entities.update(view, |view, cx| {
cx.update(view.buffer, |buffer, _| buffer.text.push_str("hola"));
});
assert_eq!(entities.read(buffer).map(|buffer| buffer.text.as_str()), Some("hola"));
}
#[test]
fn reentrant_update_of_the_same_entity_returns_none() {
let mut entities = EntityMap::new();
let buffer = entities.insert(Buffer { text: String::new() });
let nested = entities.update(buffer, |_, cx| cx.update(buffer, |_, _| ()));
assert_eq!(nested, Some(None));
}
#[test]
fn subscribers_receive_emitted_events_after_the_update() {
let mut entities = EntityMap::new();
let buffer = entities.insert(Buffer { text: String::new() });
let view = entities.insert(View { buffer, seen_events: Vec::new() });
entities.subscribe(buffer, view, |view: &mut View, event: &Edited, _| view.seen_events.push(event.0));
entities.update(buffer, |buffer, cx| {
buffer.text.push('x');
cx.emit(Edited(1));
cx.emit(Edited(2));
});
assert_eq!(entities.read(view).map(|view| view.seen_events.clone()), Some(vec![1, 2]));
}
#[test]
fn removed_subscribers_stop_listening() {
let mut entities = EntityMap::new();
let buffer = entities.insert(Buffer { text: String::new() });
let view = entities.insert(View { buffer, seen_events: Vec::new() });
let subscription =
entities.subscribe(buffer, view, |view: &mut View, event: &Edited, _| view.seen_events.push(event.0));
entities.unsubscribe(subscription);
entities.update(buffer, |_, cx| cx.emit(Edited(9)));
assert_eq!(entities.read(view).map(|view| view.seen_events.len()), Some(0));
}
#[test]
fn timers_run_only_once_due() {
let mut entities = EntityMap::new();
let buffer = entities.insert(Buffer { text: String::new() });
entities.schedule(std::time::Duration::from_secs(3600), move |entities| {
entities.update(buffer, |buffer, _| buffer.text.push('x'));
});
entities.schedule(std::time::Duration::ZERO, move |entities| {
entities.update(buffer, |buffer, _| buffer.text.push('a'));
});
assert!(entities.run_pending(std::time::Instant::now()));
assert_eq!(entities.read(buffer).map(|buffer| buffer.text.clone()), Some("a".to_owned()));
assert!(entities.timers.next_deadline().is_some());
}
#[test]
fn background_results_arrive_through_the_inbox() {
let mut entities = EntityMap::new();
let buffer = entities.insert(Buffer { text: String::new() });
let sender = entities.foreground();
let (done_sender, done) = std::sync::mpsc::channel();
entities.background.spawn(move || {
let computed = (1..=4).sum::<u32>().to_string();
sender.update(buffer, move |buffer, _| buffer.text = computed);
done_sender.send(()).ok();
});
done.recv_timeout(std::time::Duration::from_secs(5)).expect("el trabajo terminó");
entities.run_pending(std::time::Instant::now());
assert_eq!(entities.read(buffer).map(|buffer| buffer.text.clone()), Some("10".to_owned()));
}
#[test]
fn quiet_entities_do_not_wake_the_window_until_they_are_shown_again() {
let mut entities = EntityMap::new();
let handle = entities.insert(0u32);
entities.set_quiet(handle.id, true);
entities.update(handle, |_, cx| cx.notify());
assert!(!entities.is_dirty(), "un panel fuera de la vista no repinta la ventana");
entities.set_quiet(handle.id, false);
assert!(entities.is_dirty(), "al volver a verse se repinta");
entities.take_dirty();
entities.set_quiet(handle.id, true);
entities.remove(handle.id);
entities.set_quiet(handle.id, false);
}