use super::*;
#[test]
fn ranking_is_name_then_summary_then_text_then_offset_then_address() {
let ws = PathBuf::from("/w/void");
let snap = world(
&ws,
vec![],
vec![
ball("bl-body", "unrelated", "a long line then void here"),
ball("bl-title", "the void", "nothing"),
ball("void-id", "unrelated", "nothing"),
],
vec![],
);
let found = run(&snap, "void", &always());
let ids: Vec<String> = found
.hits
.iter()
.filter_map(|h| match &h.at {
Address::Ball { id, .. } => Some(id.clone()),
_ => None,
})
.collect();
assert_eq!(ids, ["void-id", "bl-title", "bl-body"]);
let fields: Vec<Field> = found.hits.iter().map(|h| h.field).collect();
assert_eq!(
fields,
[Field::Name, Field::Name, Field::Summary, Field::Text],
"the workspace name matches too, and sorts by offset within its tier"
);
}
#[test]
fn matching_is_ascii_case_insensitive_and_the_offset_indexes_the_real_bytes() {
let ws = PathBuf::from("/w/x");
let snap = world(
&ws,
vec![],
vec![ball("b", "t", "Nyarlathotep waits")],
vec![],
);
let found = run(&snap, " NYARLATHOTEP ", &always());
assert_eq!(found.hits.len(), 1);
assert_eq!(found.hits[0].offset, 0);
assert_eq!(found.hits[0].excerpt, "Nyarlathotep waits");
}
#[test]
fn an_empty_query_matches_nothing_and_clears_rather_than_refusing() {
let ws = PathBuf::from("/w/x");
let snap = world(&ws, vec![], vec![ball("b", "t", "body")], vec![]);
assert_eq!(run(&snap, " ", &always()), Found::default());
}
#[test]
fn the_bound_is_deterministic_and_caps_the_answer() {
let ws = PathBuf::from("/w/x");
let balls: Vec<Ball> = (0..MAX + 10)
.map(|n| ball(&format!("bl-{n:03}"), "t", "body"))
.collect();
let snap = world(&ws, vec![], balls, vec![]);
let found = run(&snap, "bl-", &always());
assert_eq!(found.hits.len(), MAX);
assert_eq!(
found,
run(&snap, "bl-", &always()),
"same world, same answer"
);
}
#[test]
fn an_answer_is_empty_only_when_both_halves_are() {
assert!(Found::default().is_empty());
let ws = PathBuf::from("/w/x");
let snap = world(&ws, vec![], vec![ball("b", "gate", "body")], vec![]);
assert!(
!run(&snap, "gate", &always()).is_empty(),
"a hit is content"
);
assert!(
run(&snap, "nothing-matches-this", &always()).is_empty(),
"no hit and no unreadable source is nothing to show"
);
let unreadable = Found {
needle: "gate".to_owned(),
hits: vec![],
unreadable: vec!["/w/x — permission denied".to_owned()],
};
assert!(
!unreadable.is_empty(),
"a gap in the corpus is content of its own"
);
}
#[test]
fn a_search_that_matched_nothing_still_knows_what_it_answered() {
let ws = PathBuf::from("/w/x");
let snap = world(&ws, vec![], vec![ball("b", "gate", "body")], vec![]);
let nothing = run(&snap, " ZzzzNotAThing ", &always());
assert!(nothing.is_empty(), "nothing to paint");
assert!(nothing.asked(), "but a search was asked");
assert_eq!(
nothing.needle, "ZzzzNotAThing",
"trimmed, and in the operator's own case — the match is folded, the \
word they typed is not"
);
assert_eq!(
crate::search::no_matches(¬hing.needle),
"no matches for `ZzzzNotAThing`"
);
assert!(!Found::default().asked());
assert!(!run(&snap, " ", &always()).asked());
assert!(run(&snap, "gate", &always()).asked());
}