facett-search/tests/render.rs
//! **CPU render-proof + state_json coverage for facett-search.** The inline tests
//! cover the `parse` grammar only; the `SearchBar::ui()` render path (the TextEdit +
//! the live "describe" summary label) and `state_json` are never exercised. This drives
//! a real `egui_kittest` frame so the widget paints, and asserts the parsed-query
//! summary rides into the AccessKit tree + is reflected in `state_json`.
use egui_kittest::kittest::Queryable;
use egui_kittest::Harness;
use facett_search::SearchBar;
#[test]
fn search_bar_paints_and_shows_the_parsed_summary() {
let mut bar = SearchBar::new("Search");
// Pre-fill so the describe label paints (it only shows for a non-empty query).
bar.set_text("status:open,waiting sort:due login");
// The parse is observable as data before any render.
let st = bar.state_json();
assert_eq!(st["input"], "status:open,waiting sort:due login");
let describe = st["describe"].as_str().unwrap().to_string();
assert!(describe.contains("status: open OR waiting"), "the summary is data: {describe}");
let mut harness = Harness::new_ui(move |ui| {
bar.ui(ui);
});
harness.run();
// The live describe summary reached the AccessKit tree (a label with the text).
assert!(harness.query_by_label(&describe).is_some(), "the describe summary painted: {describe}");
}
#[test]
fn empty_search_bar_renders_without_a_summary() {
let mut bar = SearchBar::new("Search");
assert_eq!(bar.state_json()["describe"].as_str().unwrap(), "", "an empty query describes as nothing");
let mut harness = Harness::new_ui(move |ui| {
bar.ui(ui);
});
harness.run(); // must not panic with an empty query (no summary label)
}
#[test]
fn state_json_round_trips_the_query() {
let mut bar = SearchBar::new("Issues");
bar.set_text("assignee:me -priority:low #overdue");
let st = bar.state_json();
assert_eq!(st["title"], "Issues");
// The parsed clause structure is embedded as data.
let clauses = st["parsed"]["clauses"].as_array().unwrap();
assert!(clauses.len() >= 2, "clauses are serialised: {clauses:?}");
}