use crate::brain::tools::toml_hot_reload::HotToml;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct Sample {
#[serde(default)]
value: u32,
#[serde(default)]
name: String,
}
fn tmpdir() -> std::path::PathBuf {
let mut p = std::env::temp_dir();
p.push(format!(
"opencrabs-hotreload-{}-{:?}",
std::process::id(),
std::thread::current().id()
));
std::fs::create_dir_all(&p).expect("tmpdir");
p
}
fn write(path: &std::path::Path, body: &str) {
std::fs::write(path, body).expect("write");
let t = std::time::SystemTime::now() + std::time::Duration::from_secs(1);
let f = std::fs::File::options()
.write(true)
.open(path)
.expect("reopen to set mtime");
f.set_modified(t).expect("set mtime");
}
#[test]
fn a_missing_file_yields_none() {
let path = tmpdir().join("absent.toml");
let _ = std::fs::remove_file(&path);
let hot: HotToml<Sample> = HotToml::new(path, "sample");
assert!(hot.get().is_none());
}
#[test]
fn a_present_file_parses() {
let path = tmpdir().join("present.toml");
write(&path, "value = 7\nname = \"alpha\"\n");
let hot: HotToml<Sample> = HotToml::new(path, "sample");
let got = hot.get().expect("parses");
assert_eq!(got.value, 7);
assert_eq!(got.name, "alpha");
}
#[test]
fn an_edit_is_picked_up_without_a_restart() {
let path = tmpdir().join("edited.toml");
write(&path, "value = 1\n");
let hot: HotToml<Sample> = HotToml::new(path.clone(), "sample");
assert_eq!(hot.get().expect("first").value, 1);
write(&path, "value = 2\n");
assert_eq!(
hot.get().expect("second").value,
2,
"the edit was not picked up — still serving the cached parse"
);
}
#[test]
fn an_unchanged_file_serves_the_cache() {
let path = tmpdir().join("stable.toml");
write(&path, "value = 5\n");
let hot: HotToml<Sample> = HotToml::new(path, "sample");
let a = hot.get().expect("first");
let b = hot.get().expect("second");
assert!(
std::sync::Arc::ptr_eq(&a, &b),
"an unchanged file was re-parsed instead of served from cache"
);
}
#[test]
fn a_file_appearing_later_is_picked_up() {
let path = tmpdir().join("appears.toml");
let _ = std::fs::remove_file(&path);
let hot: HotToml<Sample> = HotToml::new(path.clone(), "sample");
assert!(hot.get().is_none());
write(&path, "value = 9\n");
assert_eq!(
hot.get().expect("appeared").value,
9,
"the file appeared but the cached absence stuck"
);
}
#[test]
fn a_broken_file_yields_none_and_recovers_when_fixed() {
let path = tmpdir().join("broken.toml");
write(&path, "value = 3\n");
let hot: HotToml<Sample> = HotToml::new(path.clone(), "sample");
assert_eq!(hot.get().expect("valid").value, 3);
write(&path, "value = = = not toml\n");
assert!(hot.get().is_none(), "a parse error must yield None");
write(&path, "value = 4\n");
assert_eq!(
hot.get().expect("fixed").value,
4,
"fixing the file did not re-arm the load"
);
}