use std::cell::Cell;
use std::rc::Rc;
use std::time::{Duration, Instant};
use telar::{drain_tasks, watch_path};
fn scratch(name: &str) -> std::path::PathBuf {
let dir = std::env::temp_dir().join(format!("telar-watch-{name}-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).expect("create scratch dir");
dir
}
fn settle_until(hits: &Rc<Cell<usize>>, want: usize, timeout: Duration) -> usize {
let deadline = Instant::now() + timeout;
while hits.get() < want && Instant::now() < deadline {
drain_tasks();
std::thread::sleep(Duration::from_millis(10));
}
drain_tasks();
hits.get()
}
#[test]
fn a_write_under_the_watched_directory_reaches_the_ui_thread() {
let dir = scratch("write");
let hits = Rc::new(Cell::new(0usize));
let counted = Rc::clone(&hits);
let watch = watch_path(&dir, move || counted.set(counted.get() + 1));
std::thread::sleep(Duration::from_millis(200));
std::fs::write(dir.join("config.toml"), "a = 1\n").unwrap();
assert!(
settle_until(&hits, 1, Duration::from_secs(10)) >= 1,
"the write never reached the callback"
);
watch.cancel();
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn a_cancelled_watch_stops_reporting() {
let dir = scratch("cancel");
let hits = Rc::new(Cell::new(0usize));
let counted = Rc::clone(&hits);
let watch = watch_path(&dir, move || counted.set(counted.get() + 1));
std::thread::sleep(Duration::from_millis(200));
std::fs::write(dir.join("first.toml"), "a = 1\n").unwrap();
let before = settle_until(&hits, 1, Duration::from_secs(10));
assert!(before >= 1, "the watch never reported at all");
watch.cancel();
std::fs::write(dir.join("second.toml"), "b = 2\n").unwrap();
std::thread::sleep(Duration::from_millis(300));
drain_tasks();
assert_eq!(hits.get(), before, "a cancelled watch kept reporting");
let _ = std::fs::remove_dir_all(&dir);
}