aura-gui 0.2.2

UI nativa acelerada por GPU para escritorio, Android e iOS, en un solo crate: estilo tipo Tailwind, componentes, sombras, animaciones y agentes de IA. Reposo a cero. Licencia AGPL-3.0 o comercial.
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);
}