use std::fs;
use lantern::ingest::ingest_path;
use lantern::query_success::{apply_query_success, get_query_success_count, record_query_success};
use lantern::search::{SearchOptions, search};
use lantern::store::Store;
use tempfile::tempdir;
fn setup_store_with(files: &[(&str, &str)]) -> (tempfile::TempDir, Store) {
let root = tempdir().unwrap();
let mut store = Store::initialize(&root.path().join("store")).unwrap();
let data = root.path().join("data");
fs::create_dir_all(&data).unwrap();
for (name, body) in files {
fs::write(data.join(name), body).unwrap();
}
ingest_path(&mut store, &data).unwrap();
(root, store)
}
#[test]
fn new_chunks_default_to_neutral_query_success_count() {
let (_root, store) = setup_store_with(&[("a.md", "Lanterns glow in the dark forest.")]);
let hits = search(&store, "lantern", SearchOptions::default()).unwrap();
assert_eq!(hits.len(), 1);
assert_eq!(hits[0].query_success_count, 0);
}
#[test]
fn record_query_success_increments_and_is_visible_on_next_search() {
let (_root, store) = setup_store_with(&[("a.md", "Lanterns glow in the dark forest.")]);
let chunk_id = {
let hits = search(&store, "lantern", SearchOptions::default()).unwrap();
hits[0].chunk_id.clone()
};
assert_eq!(record_query_success(&store, &chunk_id).unwrap(), 1);
assert_eq!(record_query_success(&store, &chunk_id).unwrap(), 2);
assert_eq!(get_query_success_count(&store, &chunk_id).unwrap(), Some(2));
let hits = search(&store, "lantern", SearchOptions::default()).unwrap();
let hit = hits.iter().find(|h| h.chunk_id == chunk_id).unwrap();
assert_eq!(hit.query_success_count, 2);
}
#[test]
fn apply_query_success_returns_updated_confidence_snapshot() {
let (_root, store) = setup_store_with(&[("a.md", "Lanterns glow in the dark forest.")]);
let chunk_id = {
let hits = search(&store, "lantern", SearchOptions::default()).unwrap();
hits[0].chunk_id.clone()
};
let report = apply_query_success(&store, &chunk_id).unwrap();
assert_eq!(report.chunk_id, chunk_id);
assert_eq!(report.count, 1);
assert!(
(0.0..=1.0).contains(&report.confidence),
"confidence should stay in range: {:?}",
report.confidence_breakdown
);
assert!(
report.confidence_breakdown.query_success_factor > 0.0,
"expected positive query-success factor in report: {:?}",
report.confidence_breakdown
);
}
#[test]
fn query_success_raises_confidence_relative_to_neutral_peer() {
let (_root, store) = setup_store_with(&[
("a.md", "Lanterns glow in the dark forest."),
("b.md", "Lanterns are useful in old mines as well."),
]);
store
.conn()
.execute(
"UPDATE chunks
SET timestamp_unix = 1,
last_accessed_at = NULL,
access_count = 0,
access_decay_at = NULL",
[],
)
.unwrap();
let chunk_ids: Vec<String> = store
.conn()
.prepare("SELECT id FROM chunks ORDER BY id")
.unwrap()
.query_map([], |row| row.get(0))
.unwrap()
.collect::<Result<Vec<_>, _>>()
.unwrap();
assert_eq!(chunk_ids.len(), 2, "expected exactly two chunks");
let success_id = chunk_ids[0].clone();
let other_id = chunk_ids[1].clone();
apply_query_success(&store, &success_id).unwrap();
assert_eq!(
get_query_success_count(&store, &success_id).unwrap(),
Some(1)
);
assert_eq!(get_query_success_count(&store, &other_id).unwrap(), Some(0));
let hits = search(&store, "lantern", SearchOptions::default()).unwrap();
let success = hits.iter().find(|h| h.chunk_id == success_id).unwrap();
let other = hits.iter().find(|h| h.chunk_id == other_id).unwrap();
assert_eq!(success.query_success_count, 1);
assert_eq!(other.query_success_count, 0);
assert!(
success.confidence > other.confidence,
"query-success should strictly raise confidence above a neutral peer \
(success={}, other={})",
success.confidence,
other.confidence,
);
assert!(
success.confidence_breakdown.query_success_factor > 0.0,
"query_success_factor should be > 0 after a recorded success: {:?}",
success.confidence_breakdown,
);
assert_eq!(
other.confidence_breakdown.query_success_factor, 0.0,
"neutral peer must keep the query_success_factor=0 default: {:?}",
other.confidence_breakdown,
);
}
#[test]
fn record_query_success_errors_for_missing_chunk() {
let (_root, store) = setup_store_with(&[("a.md", "just a seed chunk")]);
let err = record_query_success(&store, "does-not-exist").unwrap_err();
assert!(
err.to_string().contains("no chunk"),
"unexpected error: {err}"
);
assert_eq!(
get_query_success_count(&store, "does-not-exist").unwrap(),
None,
);
}