cranpose-core 0.1.164

Core runtime for a Jetpack Compose inspired UI framework in Rust
Documentation
use std::rc::Rc;

use super::*;
use crate::state::{ObjectId, PREEXISTING_SNAPSHOT_ID, StateObject, StateRecord};

fn mock_state_record() -> Rc<StateRecord> {
    StateRecord::new(PREEXISTING_SNAPSHOT_ID, (), None)
}

struct MockState(usize);

impl StateObject for MockState {
    fn object_id(&self) -> ObjectId {
        ObjectId(self.0)
    }

    fn first_record(&self) -> Rc<StateRecord> {
        mock_state_record()
    }

    fn try_readable_record(
        &self,
        snapshot_id: SnapshotId,
        invalid: &SnapshotIdSet,
    ) -> Option<Rc<StateRecord>> {
        Some(self.readable_record(snapshot_id, invalid))
    }

    fn readable_record(
        &self,
        _snapshot_id: SnapshotId,
        _invalid: &SnapshotIdSet,
    ) -> Rc<StateRecord> {
        mock_state_record()
    }

    fn prepend_state_record(&self, _record: Rc<StateRecord>) {}

    fn promote_record(&self, _child_id: SnapshotId) -> Result<(), &'static str> {
        Ok(())
    }

    fn as_any(&self) -> &dyn std::any::Any {
        self
    }
}

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

    assert_eq!(snapshot.snapshot_id(), 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(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(1, SnapshotIdSet::new(), None, None);

    assert_eq!(snapshot.snapshot_id(), 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(1, SnapshotIdSet::new(), None, None);

    let mock_state = Arc::new(MockState(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(
        1,
        SnapshotIdSet::new(),
        Some(Arc::new({
            let initial_reads = Rc::clone(&initial_reads);
            move |_| initial_reads.set(initial_reads.get() + 1)
        })),
        None,
        None,
    );

    snapshot.set_read_observer(Some(Arc::new({
        let replacement_reads = Rc::clone(&replacement_reads);
        move |_| replacement_reads.set(replacement_reads.get() + 1)
    })));
    snapshot.record_read(&MockState(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(
        1,
        SnapshotIdSet::new(),
        None,
        Some(Arc::new({
            let initial_writes = Rc::clone(&initial_writes);
            move |_| initial_writes.set(initial_writes.get() + 1)
        })),
        None,
    );

    snapshot.set_write_observer(Some(Arc::new({
        let replacement_writes = Rc::clone(&replacement_writes);
        move |_| replacement_writes.set(replacement_writes.get() + 1)
    })));
    snapshot.record_write(Arc::new(MockState(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(1, SnapshotIdSet::new(), None, None, None);
    snapshot.set_read_observer(Some(Arc::new({
        let parent_reads = Rc::clone(&parent_reads);
        move |_| parent_reads.set(parent_reads.get() + 1)
    })));
    snapshot.set_write_observer(Some(Arc::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(3));
    nested.record_write(Arc::new(MockState(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(
        1,
        SnapshotIdSet::new(),
        Some(Arc::new({
            let initial_reads = Rc::clone(&initial_reads);
            move |_| initial_reads.set(initial_reads.get() + 1)
        })),
        None,
    );

    snapshot.set_read_observer(Some(Arc::new({
        let replacement_reads = Rc::clone(&replacement_reads);
        move |_| replacement_reads.set(replacement_reads.get() + 1)
    })));
    snapshot.record_read(&MockState(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(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(1, SnapshotIdSet::new(), None, None);

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