Repository: DioxusLabs/dioxus
File: packages/signals/tests/memo.rs (Rust)

Code before:

    dom.rebuild_in_place();
    dom.mark_dirty(ScopeId::APP);
    dom.render_immediate(&mut NoOpMutations);

    {
        let current_counter = counter.borrow();
        assert_eq!(current_counter.component, 1);
        assert_eq!(current_counter.memo, 2);
    }

    dom.mark_dirty(ScopeId::APP);
    dom.render_immediate(&mut NoOpMutations);
    dom.render_immediate(&mut NoOpMutations);

    {
        let current_counter = counter.borrow();
        assert_eq!(current_counter.component, 2);
        assert_eq!(current_counter.memo, 3);
    }
}

// Regression test for https://github.com/DioxusLabs/dioxus/issues/2990
#[test]
fn memos_sync_rerun_after_unrelated_write() {
    static PASSED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
    let mut dom = VirtualDom::new(|| {
        let mut signal = use_signal(|| 0);
        let memo = use_memo(move || dbg!(signal() < 2));
        if generation() == 0 {
            assert!(memo());
            signal += 1;
        } else {
            // It should be fine to hold the write and read the memo at the same time
            let mut write = signal.write();
            println!("Memo: {:?}", memo());
            assert!(memo());
            *write = 2;
            drop(write);
            assert!(!memo());
            PASSED.store(true, std::sync::atomic::Ordering::SeqCst);
        }

        rsx! {
            div {}
        }
    });

    dom.rebuild_in_place();
    dom.mark_dirty(ScopeId::APP);
    dom.render_immediate(&mut NoOpMutations);

Review comment (suggestion):
```suggestion
    static PASSED: AtomicBool = AtomicBool::new(false);
```

Code after:

    dom.rebuild_in_place();
    dom.mark_dirty(ScopeId::APP);
    dom.render_immediate(&mut NoOpMutations);

    {
        let current_counter = counter.borrow();
        assert_eq!(current_counter.component, 1);
        assert_eq!(current_counter.memo, 2);
    }

    dom.mark_dirty(ScopeId::APP);
    dom.render_immediate(&mut NoOpMutations);
    dom.render_immediate(&mut NoOpMutations);

    {
        let current_counter = counter.borrow();
        assert_eq!(current_counter.component, 2);
        assert_eq!(current_counter.memo, 3);
    }
}

// Regression test for https://github.com/DioxusLabs/dioxus/issues/2990
#[test]
fn memos_sync_rerun_after_unrelated_write() {
    static PASSED: AtomicBool = AtomicBool::new(false);
    let mut dom = VirtualDom::new(|| {
        let mut signal = use_signal(|| 0);
        let memo = use_memo(move || dbg!(signal() < 2));
        if generation() == 0 {
            assert!(memo());
            signal += 1;
        } else {
            // It should be fine to hold the write and read the memo at the same time
            let mut write = signal.write();
            println!("Memo: {:?}", memo());
            assert!(memo());
            *write = 2;
            drop(write);
            assert!(!memo());
            PASSED.store(true, std::sync::atomic::Ordering::SeqCst);
        }

        rsx! {
            div {}
        }
    });

    dom.rebuild_in_place();
    dom.mark_dirty(ScopeId::APP);
    dom.render_immediate(&mut NoOpMutations);