use luci::index::Index;
use luci::mapping::{FieldType, Mapping};
use luci::search::expression::parse_search;
use serde_json::json;
fn test_dir(name: &str) -> std::path::PathBuf {
let dir = std::env::temp_dir().join(format!("luci_deltest_{}_{name}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
dir
}
fn schema() -> Mapping {
Mapping::builder()
.field("title", FieldType::Text)
.field("tag", FieldType::Keyword)
.build()
}
#[test]
fn metadata_only_delete_commit_persists_across_reopen() {
let path = test_dir("metadata_only_delete");
let deleted_id;
{
let index = Index::create_with_mapping(&path, schema()).unwrap();
index.add(json!({"title": "doc one", "tag": "a"})).unwrap();
index.add(json!({"title": "doc two", "tag": "b"})).unwrap();
assert_eq!(
index.count(json!({"match_all": {}})).unwrap(),
2,
"both docs present before deletion"
);
let expr = parse_search(json!({"term": {"tag": "a"}}), 1).unwrap();
let results = index.search(&expr).unwrap();
deleted_id = results
.hit(0)
.and_then(|h| h.id())
.expect("tag=a doc must have an _id");
assert!(index.delete(&deleted_id).unwrap(), "doc found and marked");
index.txn_commit().unwrap();
assert_eq!(
index.count(json!({"match_all": {}})).unwrap(),
1,
"deletion visible in-process immediately after txn_commit"
);
}
{
let index = Index::open(&path).unwrap();
assert_eq!(
index.count(json!({"match_all": {}})).unwrap(),
1,
"deletion must persist across reopen (metadata-only commit must flip the root)"
);
assert!(
index.get(&deleted_id).unwrap().is_none(),
"deleted doc must not reappear on reopen"
);
}
let _ = std::fs::remove_dir_all(&path);
}
#[test]
fn bare_delete_auto_commits_and_persists_across_reopen() {
let path = test_dir("bare_delete");
let deleted_id;
{
let index = Index::create_with_mapping(&path, schema()).unwrap();
index
.add(json!({"title": "keep me", "tag": "keep"}))
.unwrap();
index
.add(json!({"title": "remove me", "tag": "drop"}))
.unwrap();
let expr = parse_search(json!({"term": {"tag": "drop"}}), 1).unwrap();
deleted_id = index
.search(&expr)
.unwrap()
.hit(0)
.and_then(|h| h.id())
.expect("tag=drop doc must have an _id");
assert!(index.delete(&deleted_id).unwrap());
}
{
let index = Index::open(&path).unwrap();
assert_eq!(
index.count(json!({"match_all": {}})).unwrap(),
1,
"bare delete() must persist across reopen"
);
assert!(index.get(&deleted_id).unwrap().is_none());
}
let _ = std::fs::remove_dir_all(&path);
}