haematite-cli 0.21.0

The haematite command: serve a store, its door and Studio, answer MCP, query with jq, and host the store's assistant seat
use super::Monitor;
use std::io::{self, Write};
use std::os::unix::net::UnixStream;
use std::sync::mpsc;
use std::time::Duration;

type TestResult = Result<(), Box<dyn std::error::Error>>;

#[test]
fn readable_data_keeps_the_follow_until_hangup_even_with_unread_bytes() -> TestResult {
    let (mut client, server) = UnixStream::pair()?;
    let (observed, observations) = mpsc::channel();
    let (closed, closure) = mpsc::channel();
    let monitor = Monitor::start_observed(
        server,
        move || {
            if let Err(error) = closed.send(()) {
                eprintln!("fixture close signal failed: {error}");
            }
        },
        move |decision| observed.send(decision).map_err(io::Error::other),
    )?;
    client.write_all(b"queued request bytes")?;
    let readable = observations.recv_timeout(Duration::from_secs(5));
    drop(client);
    let hung_up = closure.recv_timeout(Duration::from_secs(5));
    drop(monitor);
    assert!(!readable?, "readability was mistaken for a client hangup");
    hung_up?;
    Ok(())
}