#[path = "common/harness.rs"]
mod harness;
use harness::TestHarness;
use macrame::prelude::*;
const TS: &str = "2026-01-01T00:00:00.000000Z";
fn model() -> ModelName {
ModelName::new("hybrid_v1").unwrap()
}
fn v(rank: usize) -> Vec<f32> {
let theta = (rank as f32) * std::f32::consts::PI / 16.0;
vec![theta.cos(), theta.sin()]
}
fn query_vec() -> Vec<f32> {
v(0)
}
async fn fixture(harness: &TestHarness) -> Database {
let db = Database::open(&harness.db_path).await.unwrap();
let docs: [(&str, &str, &str, usize); 6] = [
("semantic", "Nearest", "a paraphrase with no rare words", 0),
("middle", "Middle", "ordinary filler text", 4),
(
"lexical",
"Distant",
"contains zygomorphic exactly once",
12,
),
("filler1", "Filler One", "ordinary filler text", 6),
("filler2", "Filler Two", "ordinary filler text", 8),
("both", "Both", "zygomorphic paraphrase", 2),
];
let concepts: Vec<ConceptUpsert> = docs
.iter()
.map(|(id, title, content, _)| {
ConceptUpsert::new(*id, *title)
.content(*content)
.valid_from(TS)
})
.collect();
db.write_concepts(concepts).await.unwrap();
db.register_model(&model(), 2).await.unwrap();
let rows: Vec<(String, Vec<f32>)> = docs
.iter()
.map(|(id, _, _, rank)| (id.to_string(), v(*rank)))
.collect();
db.upsert_embeddings(&model(), rows).await.unwrap();
db
}
fn ids(hits: &[HybridHit]) -> Vec<String> {
hits.iter().map(|h| h.concept_id.clone()).collect()
}
#[tokio::test]
async fn the_fusion_returns_what_neither_arm_finds_alone() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
let vector_only = search_vector(db.read_conn(), &query_vec(), &model(), 3)
.await
.unwrap();
let vector_ids: Vec<&str> = vector_only.iter().map(|r| r.concept_id.as_str()).collect();
assert!(
!vector_ids.contains(&"lexical"),
"fixture is wrong: the vector arm was supposed to miss the rare-term \
document in its top 3, got {vector_ids:?}"
);
let keyword_only = keyword_search(db.read_conn(), &escape_fts5_query("zygomorphic"), 10)
.await
.unwrap();
let keyword_ids: Vec<&str> = keyword_only.iter().map(|(id, _)| id.as_str()).collect();
assert!(
!keyword_ids.contains(&"semantic"),
"fixture is wrong: the keyword arm was supposed to miss the paraphrase, \
got {keyword_ids:?}"
);
let fused = HybridSearch::new(model(), "zygomorphic", query_vec())
.top_k(4)
.execute(db.read_conn())
.await
.unwrap();
let fused_ids = ids(&fused);
assert!(
fused_ids.contains(&"lexical".to_string()),
"the keyword arm's exclusive find is missing: {fused_ids:?}"
);
assert!(
fused_ids.contains(&"semantic".to_string()),
"the vector arm's exclusive find is missing: {fused_ids:?}"
);
assert_eq!(
fused_ids.first().map(String::as_str),
Some("both"),
"the document ranked well by both arms did not come first: {fused:?}"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn each_hit_carries_the_evidence_for_its_rank() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
let fused = HybridSearch::new(model(), "zygomorphic", query_vec())
.top_k(6)
.execute(db.read_conn())
.await
.unwrap();
let hit = |id: &str| fused.iter().find(|h| h.concept_id == id).cloned().unwrap();
let both = hit("both");
assert!(both.vector_rank.is_some() && both.keyword_rank.is_some());
let semantic = hit("semantic");
assert!(
semantic.vector_rank.is_some() && semantic.keyword_rank.is_none(),
"the paraphrase has no rare term, so it cannot have a keyword rank: {semantic:?}"
);
let lexical = hit("lexical");
assert!(
lexical.keyword_rank.is_some(),
"the rare-term document must carry a keyword rank: {lexical:?}"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn rewriting_a_concept_retracts_its_old_terms() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
let before = keyword_search(db.read_conn(), &escape_fts5_query("zygomorphic"), 10)
.await
.unwrap();
assert!(before.iter().any(|(id, _)| id == "lexical"));
db.upsert_concept(
ConceptUpsert::new("lexical", "Distant")
.content("now says brachiopod instead")
.valid_from(TS),
)
.await
.unwrap();
let after = keyword_search(db.read_conn(), &escape_fts5_query("zygomorphic"), 10)
.await
.unwrap();
assert!(
!after.iter().any(|(id, _)| id == "lexical"),
"the index still matches a word the concept no longer contains: {after:?}"
);
let new_term = keyword_search(db.read_conn(), &escape_fts5_query("brachiopod"), 10)
.await
.unwrap();
assert!(
new_term.iter().any(|(id, _)| id == "lexical"),
"the replacement text was never indexed: {new_term:?}"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn the_index_can_be_rebuilt_from_the_ledger() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
let expected = keyword_search(db.read_conn(), &escape_fts5_query("zygomorphic"), 10)
.await
.unwrap();
assert!(!expected.is_empty(), "fixture must match something to lose");
{
let outside = libsql::Builder::new_local(&harness.db_path)
.build()
.await
.unwrap();
let conn = outside.connect().unwrap();
conn.execute("DELETE FROM concepts_fts", ()).await.unwrap();
}
let damaged = keyword_search(db.read_conn(), &escape_fts5_query("zygomorphic"), 10)
.await
.unwrap();
assert!(damaged.is_empty(), "the damage did not take: {damaged:?}");
db.rebuild_fts().await.unwrap();
let restored = keyword_search(db.read_conn(), &escape_fts5_query("zygomorphic"), 10)
.await
.unwrap();
assert_eq!(
restored
.iter()
.map(|(id, _)| id.clone())
.collect::<Vec<_>>(),
expected
.iter()
.map(|(id, _)| id.clone())
.collect::<Vec<_>>(),
"rebuilding did not restore the index"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn a_retired_concept_leaves_the_results() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
db.upsert_concept(
ConceptUpsert::new("lexical", "Distant")
.content("contains zygomorphic exactly once")
.valid_from(TS)
.retired(true),
)
.await
.unwrap();
let hits = keyword_search(db.read_conn(), &escape_fts5_query("zygomorphic"), 10)
.await
.unwrap();
assert!(
!hits.iter().any(|(id, _)| id == "lexical"),
"a retired concept came back from search: {hits:?}"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn maintaining_the_index_never_touches_the_ledger() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
async fn log_len(db: &Database) -> i64 {
db.read_conn()
.query("SELECT COUNT(*) FROM transaction_log", ())
.await
.unwrap()
.next()
.await
.unwrap()
.unwrap()
.get(0)
.unwrap()
}
let before = log_len(&db).await;
db.rebuild_fts().await.unwrap();
assert_eq!(
log_len(&db).await,
before,
"rebuilding the search index wrote to transaction_log"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn a_search_box_cannot_become_a_query_expression() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
for hostile in [
r#"unbalanced " quote"#,
"trailing AND",
"title:Distant",
"zygomorphic NOT paraphrase",
"*",
"!!!",
] {
let out = HybridSearch::new(model(), hostile, query_vec())
.top_k(3)
.execute(db.read_conn())
.await;
assert!(
out.is_ok(),
"hostile query {hostile:?} reached FTS5 as syntax: {:?}",
out.err()
);
}
let raw_ok = HybridSearch::new(model(), "zygomorphic OR brachiopod", query_vec())
.raw_match(true)
.top_k(3)
.execute(db.read_conn())
.await;
assert!(
raw_ok.is_ok(),
"a valid raw expression was refused: {:?}",
raw_ok.err()
);
let raw_bad = HybridSearch::new(model(), r#"unbalanced " quote"#, query_vec())
.raw_match(true)
.top_k(3)
.execute(db.read_conn())
.await;
assert!(
raw_bad.is_err(),
"raw_match must not silently escape; if this passes, the flag does nothing"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn the_same_query_answers_the_same_way_twice() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
let once = HybridSearch::new(model(), "ordinary filler text", query_vec())
.top_k(6)
.execute(db.read_conn())
.await
.unwrap();
for _ in 0..8 {
let again = HybridSearch::new(model(), "ordinary filler text", query_vec())
.top_k(6)
.execute(db.read_conn())
.await
.unwrap();
assert_eq!(
ids(&once),
ids(&again),
"fused order is not stable across runs"
);
}
db.close().await.unwrap();
}
#[tokio::test]
async fn reading_each_arm_deeper_than_top_k_is_what_lets_agreement_win() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
let shallow = HybridSearch::new(model(), "ordinary filler text", query_vec())
.top_k(2)
.depth(2)
.execute(db.read_conn())
.await
.unwrap();
let deep = HybridSearch::new(model(), "ordinary filler text", query_vec())
.top_k(2)
.depth(10)
.execute(db.read_conn())
.await
.unwrap();
assert_eq!(shallow.len(), 2);
assert_eq!(deep.len(), 2);
let deep_has_both_arms = deep
.iter()
.any(|h| h.vector_rank.is_some() && h.keyword_rank.is_some());
assert!(
deep_has_both_arms,
"at depth 10 a document agreed on by both arms should surface: {deep:?}"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn asking_for_nothing_returns_nothing() {
let harness = TestHarness::new();
let db = fixture(&harness).await;
let hits = HybridSearch::new(model(), "zygomorphic", query_vec())
.top_k(0)
.execute(db.read_conn())
.await
.unwrap();
assert!(hits.is_empty());
db.close().await.unwrap();
}