cranpose-core 0.1.164

Core runtime for a Jetpack Compose inspired UI framework in Rust
Documentation
use super::*;
use crate::state::NeverEqual;

fn counting(hits: &Rc<Cell<u32>>) -> impl Fn(&&'static str) + 'static {
    let hits = Rc::clone(hits);
    move |_| hits.set(hits.get() + 1)
}

#[test]
fn an_observer_nested_in_another_observers_pass_keeps_its_reads() {
    let _guard = reset_snapshot_runtime();
    let outer_state = SnapshotMutableState::new_in_arc(0, Arc::new(NeverEqual));
    let inner_state = SnapshotMutableState::new_in_arc(0, Arc::new(NeverEqual));
    let outer = SnapshotStateObserver::new(|job| job());
    let inner = SnapshotStateObserver::new(|job| job());
    outer.start();
    inner.start();
    let outer_hits = Rc::new(Cell::new(0));
    let inner_hits = Rc::new(Cell::new(0));

    outer.observe_reads("outer", counting(&outer_hits), || {
        let _ = outer_state.get();
        inner.observe_reads("inner", counting(&inner_hits), || {
            let _ = inner_state.get();
        });
    });

    inner_state.set(1);
    assert_eq!(inner_hits.get(), 1, "the nested observer lost its read");
    assert_eq!(
        outer_hits.get(),
        1,
        "the enclosing observer sees nested reads too"
    );
    outer_state.set(1);
    assert_eq!(outer_hits.get(), 2);
    assert_eq!(inner_hits.get(), 1);
}

#[test]
fn nesting_the_same_observer_keeps_reads_on_the_innermost_scope() {
    let _guard = reset_snapshot_runtime();
    let outer_state = SnapshotMutableState::new_in_arc(0, Arc::new(NeverEqual));
    let inner_state = SnapshotMutableState::new_in_arc(0, Arc::new(NeverEqual));
    let observer = SnapshotStateObserver::new(|job| job());
    observer.start();
    let outer_hits = Rc::new(Cell::new(0));
    let inner_hits = Rc::new(Cell::new(0));

    observer.observe_reads("outer", counting(&outer_hits), || {
        let _ = outer_state.get();
        observer.observe_reads("inner", counting(&inner_hits), || {
            let _ = inner_state.get();
        });
    });

    inner_state.set(1);
    assert_eq!((outer_hits.get(), inner_hits.get()), (0, 1));
    outer_state.set(1);
    assert_eq!((outer_hits.get(), inner_hits.get()), (1, 1));
}