cranpose-core 0.22.2

Composition runtime and reactive state for Cranpose
Documentation
use std::rc::Rc;

use super::*;
use crate::tests::state_mock::MockState;

#[test]
fn test_transparent_observer_mutable_snapshot() {
    let _guard = reset_runtime_for_tests();
    let snapshot = TransparentObserverMutableSnapshot::new(
        SnapshotId(1),
        SnapshotIdSet::new(),
        None,
        None,
        None,
    );

    assert_eq!(snapshot.snapshot_id(), SnapshotId(1));
    assert!(!snapshot.read_only());
    assert!(snapshot.can_reuse());
}

#[test]
fn test_transparent_observer_mutable_apply() {
    let _guard = reset_runtime_for_tests();
    let snapshot = TransparentObserverMutableSnapshot::new(
        SnapshotId(1),
        SnapshotIdSet::new(),
        None,
        None,
        None,
    );

    let result = snapshot.apply();
    assert!(result.is_success());
}

#[test]
fn test_transparent_observer_snapshot() {
    let _guard = reset_runtime_for_tests();
    let snapshot =
        TransparentObserverSnapshot::new(SnapshotId(1), SnapshotIdSet::new(), None, None);

    assert_eq!(snapshot.snapshot_id(), SnapshotId(1));
    assert!(snapshot.read_only());
    assert!(snapshot.can_reuse());
}

#[test]
#[should_panic(expected = "Cannot write to a read-only snapshot")]
fn test_transparent_observer_snapshot_write_panics() {
    let _guard = reset_runtime_for_tests();

    let snapshot =
        TransparentObserverSnapshot::new(SnapshotId(1), SnapshotIdSet::new(), None, None);

    let mock_state = Rc::new(MockState::with_id(0));
    snapshot.record_write(mock_state);
}

#[test]
fn transparent_mutable_set_read_observer_replaces_observer() {
    let _guard = reset_runtime_for_tests();
    let initial_reads = Rc::new(Cell::new(0));
    let replacement_reads = Rc::new(Cell::new(0));
    let snapshot = TransparentObserverMutableSnapshot::new(
        SnapshotId(1),
        SnapshotIdSet::new(),
        Some(Rc::new({
            let initial_reads = Rc::clone(&initial_reads);
            move |_| initial_reads.set(initial_reads.get() + 1)
        })),
        None,
        None,
    );

    snapshot.set_read_observer(Some(Rc::new({
        let replacement_reads = Rc::clone(&replacement_reads);
        move |_| replacement_reads.set(replacement_reads.get() + 1)
    })));
    snapshot.record_read(&MockState::with_id(1));

    assert_eq!(initial_reads.get(), 0);
    assert_eq!(replacement_reads.get(), 1);
}

#[test]
fn transparent_mutable_set_write_observer_replaces_observer() {
    let _guard = reset_runtime_for_tests();
    let initial_writes = Rc::new(Cell::new(0));
    let replacement_writes = Rc::new(Cell::new(0));
    let snapshot = TransparentObserverMutableSnapshot::new(
        SnapshotId(1),
        SnapshotIdSet::new(),
        None,
        Some(Rc::new({
            let initial_writes = Rc::clone(&initial_writes);
            move |_| initial_writes.set(initial_writes.get() + 1)
        })),
        None,
    );

    snapshot.set_write_observer(Some(Rc::new({
        let replacement_writes = Rc::clone(&replacement_writes);
        move |_| replacement_writes.set(replacement_writes.get() + 1)
    })));
    snapshot.record_write(Rc::new(MockState::with_id(2)));

    assert_eq!(initial_writes.get(), 0);
    assert_eq!(replacement_writes.get(), 1);
}

#[test]
fn transparent_mutable_nested_snapshot_inherits_replaced_observers() {
    let _guard = reset_runtime_for_tests();
    let parent_reads = Rc::new(Cell::new(0));
    let parent_writes = Rc::new(Cell::new(0));
    let snapshot = TransparentObserverMutableSnapshot::new(
        SnapshotId(1),
        SnapshotIdSet::new(),
        None,
        None,
        None,
    );
    snapshot.set_read_observer(Some(Rc::new({
        let parent_reads = Rc::clone(&parent_reads);
        move |_| parent_reads.set(parent_reads.get() + 1)
    })));
    snapshot.set_write_observer(Some(Rc::new({
        let parent_writes = Rc::clone(&parent_writes);
        move |_| parent_writes.set(parent_writes.get() + 1)
    })));

    let nested = snapshot.take_nested_mutable_snapshot(None, None);
    nested.record_read(&MockState::with_id(3));
    nested.record_write(Rc::new(MockState::with_id(4)));

    assert_eq!(parent_reads.get(), 1);
    assert_eq!(parent_writes.get(), 1);
}

#[test]
fn transparent_readonly_set_read_observer_replaces_observer() {
    let _guard = reset_runtime_for_tests();
    let initial_reads = Rc::new(Cell::new(0));
    let replacement_reads = Rc::new(Cell::new(0));
    let snapshot = TransparentObserverSnapshot::new(
        SnapshotId(1),
        SnapshotIdSet::new(),
        Some(Rc::new({
            let initial_reads = Rc::clone(&initial_reads);
            move |_| initial_reads.set(initial_reads.get() + 1)
        })),
        None,
    );

    snapshot.set_read_observer(Some(Rc::new({
        let replacement_reads = Rc::clone(&replacement_reads);
        move |_| replacement_reads.set(replacement_reads.get() + 1)
    })));
    snapshot.record_read(&MockState::with_id(5));

    assert_eq!(initial_reads.get(), 0);
    assert_eq!(replacement_reads.get(), 1);
}

#[test]
fn test_transparent_observer_mutable_nested() {
    let _guard = reset_runtime_for_tests();
    let parent = TransparentObserverMutableSnapshot::new(
        SnapshotId(1),
        SnapshotIdSet::new(),
        None,
        None,
        None,
    );

    let nested = parent.take_nested_mutable_snapshot(None, None);
    assert!(nested.snapshot_id() > parent.snapshot_id());
}

#[test]
fn test_transparent_observer_snapshot_nested() {
    let _guard = reset_runtime_for_tests();
    let parent = TransparentObserverSnapshot::new(SnapshotId(1), SnapshotIdSet::new(), None, None);

    let nested = parent.take_nested_snapshot(None);
    assert_eq!(nested.snapshot_id(), parent.snapshot_id());
    assert!(nested.read_only());
}