cranpose-services 0.1.163

Multiplatform system services for Cranpose (HTTP, URI, and OS integrations)
Documentation
use std::sync::PoisonError;

use super::*;

fn recording_observer() -> (Observer, Arc<Mutex<Vec<String>>>) {
    let seen = Arc::new(Mutex::new(Vec::new()));
    let recorder = Arc::clone(&seen);
    let observer: Observer = Arc::new(move |payload: String| {
        recorder
            .lock()
            .unwrap_or_else(PoisonError::into_inner)
            .push(payload);
    });
    (observer, seen)
}

fn seen(log: &Arc<Mutex<Vec<String>>>) -> Vec<String> {
    log.lock().unwrap_or_else(PoisonError::into_inner).clone()
}

#[test]
fn a_new_observer_is_handed_the_newest_message_of_its_channel() {
    let mut mailbox = Mailbox::new();
    assert!(
        mailbox
            .publish(&HostMessage::new("theme", "light"))
            .is_empty()
    );
    assert!(
        mailbox
            .publish(&HostMessage::new("theme", "dark"))
            .is_empty()
    );

    let (observer, _log) = recording_observer();
    assert_eq!(
        mailbox.observe(1, "theme", observer),
        Some("dark".to_string()),
        "only the newest message is replayed"
    );
}

#[test]
fn a_message_reaches_only_the_observers_of_its_channel() {
    let mut mailbox = Mailbox::new();
    let (theme, _theme_log) = recording_observer();
    let (editor, _editor_log) = recording_observer();
    assert_eq!(mailbox.observe(1, "theme", theme), None);
    assert_eq!(mailbox.observe(2, "editor", editor), None);

    assert_eq!(
        mailbox
            .publish(&HostMessage::new("editor", "main.rs"))
            .len(),
        1
    );
}

#[test]
fn a_removed_observer_receives_nothing() {
    let mut mailbox = Mailbox::new();
    let (observer, _log) = recording_observer();
    mailbox.observe(7, "theme", observer);
    mailbox.remove_observer(7);

    assert!(
        mailbox
            .publish(&HostMessage::new("theme", "dark"))
            .is_empty()
    );
}

#[test]
fn clearing_forgets_the_newest_messages() {
    let mut mailbox = Mailbox::new();
    mailbox.publish(&HostMessage::new("theme", "dark"));
    mailbox.clear();

    let (observer, _log) = recording_observer();
    assert_eq!(mailbox.observe(1, "theme", observer), None);
}

#[test]
fn published_messages_reach_a_registered_observer_until_it_is_dropped() {
    let channel = "host-messages-test.observe";
    let log = Arc::new(Mutex::new(Vec::new()));
    let recorder = Arc::clone(&log);
    let registration = observe_host_messages(channel, move |payload| {
        recorder
            .lock()
            .unwrap_or_else(PoisonError::into_inner)
            .push(payload);
    });

    publish_host_message(HostMessage::new(channel, "first"));
    drop(registration);
    publish_host_message(HostMessage::new(channel, "second"));

    assert_eq!(seen(&log), vec!["first".to_string()]);
}

#[test]
fn sending_goes_to_the_installed_outbox_and_reports_a_missing_host() {
    let sent = Arc::new(Mutex::new(Vec::new()));
    let recorder = Arc::clone(&sent);
    install_host_outbox(move |message| {
        recorder
            .lock()
            .unwrap_or_else(PoisonError::into_inner)
            .push(message);
    });
    assert!(send_to_host("ide.notify", "saved"));

    clear_host_outbox();
    assert!(!send_to_host("ide.notify", "lost"));

    assert_eq!(
        *sent.lock().unwrap_or_else(PoisonError::into_inner),
        vec![HostMessage::new("ide.notify", "saved")]
    );
}