facett-search/tests/matrix.rs
//! **The functional matrix cell for facett-search** — the pane emitted NO
//! testmatrix row of either aspect before this file (see
//! `.nornir/docs/test-matrix-inventory-history.md`, "~10 panes emit no cell").
//!
//! ONE call through the shared generic-`Facet` probe (L5) — no bespoke harness.
use facett_search::SearchBar;
#[test]
fn search_probe_emits_render_and_input_cells() {
let mut view = SearchBar::local();
let script = [
r#"{"set_text":"status:open,waiting sort:due"}"#, // retype (re-parses)
r#""submit""#, // the Enter key
r#"{"set_text":""}"#, // clear the bar
];
let probe = facett_core::testmatrix::probe_and_emit("facett-search", &mut view, &script);
assert!(probe.drew(), "the search bar must tessellate to vertices");
assert!(probe.cardinality() > 0, "state_json reports the parsed query");
assert!(probe.responded(), "update_json must drive state — a dead seam is a regression");
// EXACT parse contract on the fixture: a field filter, a negation, free text
// and a sort all survive the round trip through `state_json`.
let d0 = probe.initial_state["describe"].as_str().unwrap();
assert!(d0.contains("status: open"), "{d0}");
assert!(d0.contains("assignee: me"), "{d0}");
assert!(d0.contains("≠tag: spam"), "negation is parsed: {d0}");
assert!(d0.contains("text:\"bygglov\""), "{d0}");
assert!(d0.contains("sort:due"), "{d0}");
let d1 = probe.steps[0].state["describe"].as_str().unwrap();
assert!(d1.contains("status: open OR waiting"), "a comma list is an OR: {d1}");
assert_eq!(probe.steps[2].state["input"], "", "the bar cleared");
// The headless Enter fed `take_submit` the SAME query the parser produced.
let submitted = view.take_submit().expect("submit queued a query");
assert!(submitted.describe().contains("status: open OR waiting"));
assert!(view.take_submit().is_none(), "take_submit drains");
}
/// RED-when-broken: retyping must RE-PARSE, not merely store the string. A bar
/// that keeps a stale `parsed` would still change `state_json["input"]` and so
/// would sail past a loose "responded" oracle.
#[test]
fn retyping_reparses_the_query_not_just_the_string() {
let mut s = SearchBar::new("Q");
s.set_text("status:open");
assert_eq!(s.query().clauses.len(), 1);
s.set_text("status:open assignee:me has:attachment");
assert_eq!(s.query().clauses.len(), 3, "every clause is re-derived from the new text");
s.set_text("");
assert!(s.query().clauses.is_empty() && s.query().text.is_empty(), "clearing clears the parse");
}