haematite-cli 0.21.3

The haematite command: serve a store, its door and Studio, answer MCP, query with jq, and host the store's assistant seat
Documentation
use super::mapped;
use crate::serve::query::parser::pipeline;
use crate::serve::query::source::Scope;

type TestResult = Result<(), String>;

#[test]
fn match_grammar_has_a_named_execution_refusal() -> TestResult {
    for (query, hop) in [
        ("match (c:patients)", false),
        ("match (c:patients)-[:admitted_to]->(w:wards)", true),
        ("match (c:patients)<-[:admitted_to]-(w:wards)", true),
        ("patients | match (c:patients)", false),
        (
            "match (c:patients)-[:admitted_to]->(w:wards)<-[:staffed_by]-(n:nurses)",
            true,
        ),
    ] {
        let plan = pipeline(query).map_err(|error| error.to_string())?;
        let executed = mapped(&plan, None, None).map_err(|error| error.message)?;
        assert!(
            matches!(&executed.scope, Scope::Collection(name) if name == "patients"),
            "{query}"
        );
        let pattern = executed.matching.as_ref().ok_or("match pattern missing")?;
        assert_eq!(pattern.collection, "patients", "{query}");
        assert_eq!(pattern.is_hop(), hop, "{query}");
        assert_eq!(executed.names, vec!["match"], "{query}");
        assert!(
            matches!(executed.stages.as_slice(), [haematite_query::stage::Stage::Match { hop: actual }] if *actual == hop),
            "{query}"
        );
    }
    Ok(())
}