use std::fs;
use lantern::diff::diff;
use lantern::ingest::{ingest_path, ingest_stdin};
use lantern::store::Store;
use tempfile::tempdir;
#[test]
fn empty_store_reports_all_buckets_empty() {
let root = tempdir().unwrap();
let store = Store::initialize(&root.path().join("store")).unwrap();
let report = diff(&store, None).unwrap();
assert!(report.scanned_path.is_none());
assert!(report.unchanged.is_empty());
assert!(report.changed.is_empty());
assert!(report.missing.is_empty());
assert!(report.unindexed.is_empty());
}
#[test]
fn unchanged_file_is_reported_as_unchanged() {
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();
let file = data.join("a.md");
fs::write(&file, "stable content").unwrap();
ingest_path(&mut store, &file).unwrap();
let report = diff(&store, Some(&data)).unwrap();
assert_eq!(report.unchanged.len(), 1);
assert!(report.unchanged[0].path.ends_with("/a.md"));
assert_eq!(
report.unchanged[0].current_sha256, report.unchanged[0].indexed_sha256,
"hashes should match for unchanged file"
);
assert!(report.changed.is_empty());
assert!(report.missing.is_empty());
assert!(report.unindexed.is_empty());
}
#[test]
fn edited_file_is_reported_as_changed() {
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();
let file = data.join("a.md");
fs::write(&file, "first version").unwrap();
ingest_path(&mut store, &file).unwrap();
fs::write(&file, "second version has more text").unwrap();
let report = diff(&store, Some(&data)).unwrap();
assert!(report.unchanged.is_empty());
assert_eq!(report.changed.len(), 1);
assert!(report.changed[0].path.ends_with("/a.md"));
assert_ne!(
report.changed[0].current_sha256, report.changed[0].indexed_sha256,
"hashes must differ for a changed file"
);
}
#[test]
fn deleted_file_is_reported_as_missing() {
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();
let file = data.join("a.md");
fs::write(&file, "temporary").unwrap();
ingest_path(&mut store, &file).unwrap();
fs::remove_file(&file).unwrap();
let report = diff(&store, Some(&data)).unwrap();
assert!(report.unchanged.is_empty());
assert!(report.changed.is_empty());
assert_eq!(report.missing.len(), 1);
assert_eq!(report.missing[0].reason, "not found");
}
#[test]
fn new_files_on_disk_are_reported_as_unindexed() {
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();
let indexed = data.join("known.md");
fs::write(&indexed, "already indexed").unwrap();
ingest_path(&mut store, &indexed).unwrap();
fs::write(data.join("fresh.md"), "freshly dropped markdown").unwrap();
fs::write(data.join("ignore.log"), "unsupported extension").unwrap();
let report = diff(&store, Some(&data)).unwrap();
assert_eq!(report.unchanged.len(), 1);
assert_eq!(report.unindexed.len(), 1);
assert!(report.unindexed[0].path.ends_with("/fresh.md"));
}
#[test]
fn scoping_excludes_sources_outside_the_scanned_path() {
let root = tempdir().unwrap();
let mut store = Store::initialize(&root.path().join("store")).unwrap();
let inside = root.path().join("inside");
let outside = root.path().join("outside");
fs::create_dir_all(&inside).unwrap();
fs::create_dir_all(&outside).unwrap();
fs::write(inside.join("a.md"), "in").unwrap();
fs::write(outside.join("b.md"), "out").unwrap();
ingest_path(&mut store, &inside).unwrap();
ingest_path(&mut store, &outside).unwrap();
let report = diff(&store, Some(&inside)).unwrap();
assert_eq!(report.unchanged.len(), 1);
assert!(report.unchanged[0].path.ends_with("/a.md"));
}
#[test]
fn stdin_sources_are_never_reported() {
let root = tempdir().unwrap();
let mut store = Store::initialize(&root.path().join("store")).unwrap();
ingest_stdin(&mut store, "stdin://note-1", None, b"just stdin").unwrap();
let report = diff(&store, None).unwrap();
assert!(report.unchanged.is_empty());
assert!(report.changed.is_empty());
assert!(report.missing.is_empty());
assert!(report.unindexed.is_empty());
}
#[test]
fn store_wide_mode_skips_unindexed_scan() {
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();
fs::write(data.join("a.md"), "indexed").unwrap();
fs::write(data.join("b.md"), "not indexed").unwrap();
ingest_path(&mut store, &data.join("a.md")).unwrap();
let report = diff(&store, None).unwrap();
assert_eq!(report.unchanged.len(), 1);
assert!(report.unindexed.is_empty(), "no scan when path is omitted");
assert!(report.scanned_path.is_none());
}