strop-core 0.32.3

strop editor core: rope buffer, byte-offset positions, edit ops
Documentation
use super::*;
use crate::worker::CancelReason;
use std::sync::mpsc::channel;

#[test]
fn cancellation_waits_for_the_actual_committed_effect_receipt() {
    let root = tempfile::tempdir().unwrap();
    let file = root.path().join("effect");
    let target = file.clone();
    let (ready, entered) = channel();
    let (release, wait) = channel();
    let (tx, rx) = channel();
    let handle = spawn_effect(
        "observed-effect",
        move |outcome| {
            tx.send(outcome).unwrap();
        },
        move |_| {
            std::fs::write(&target, "committed").unwrap();
            ready.send(()).unwrap();
            wait.recv().unwrap();
            Outcome::Success(std::fs::metadata(target).unwrap().len())
        },
    );
    entered.recv().unwrap();
    handle.cancel(CancelReason::Dismissed);
    assert!(
        rx.try_recv().is_err(),
        "cancellation must not fabricate an early terminal result"
    );
    release.send(()).unwrap();
    assert!(matches!(rx.recv().unwrap(), Outcome::Success(9)));
    assert_eq!(std::fs::read(file).unwrap(), b"committed");
}

#[test]
fn cancellation_cleanup_failure_preserves_the_observed_value() {
    let root = tempfile::tempdir().unwrap();
    let file = root.path().join("effect");
    let target = file.clone();
    let (ready, entered) = channel();
    let (cleanup_started, cleanup_entered) = channel();
    let (cleanup_release, cleanup_wait) = channel();
    let (work_release, work_wait) = channel();
    let (tx, rx) = channel();
    let handle = spawn_effect(
        "effect-cleanup",
        move |outcome| {
            tx.send(outcome).unwrap();
        },
        move |token| {
            token
                .register_cancel_resource(move || {
                    cleanup_started.send(()).unwrap();
                    cleanup_wait.recv().unwrap();
                    Err(Failure::new(FailureKind::Io, "injected cleanup failure"))
                })
                .unwrap();
            std::fs::write(&target, "committed").unwrap();
            ready.send(()).unwrap();
            work_wait.recv().unwrap();
            Outcome::Success(std::fs::metadata(target).unwrap().len())
        },
    );
    entered.recv().unwrap();
    let cancelling = std::thread::spawn(move || handle.cancel(CancelReason::Dismissed));
    cleanup_entered.recv().unwrap();
    work_release.send(()).unwrap();
    assert!(rx.try_recv().is_err());
    cleanup_release.send(()).unwrap();
    cancelling.join().unwrap();
    assert!(
        matches!(rx.recv().unwrap(), Outcome::Failed { failure, partial: Some(9) } if failure.kind == FailureKind::Io)
    );
    assert_eq!(std::fs::read(file).unwrap(), b"committed");
}