pub mod session_start;
#[cfg(test)]
mod tests {
use crate::checkpoint::Checkpoint;
fn temp_path(name: &str) -> std::path::PathBuf {
use std::sync::atomic::{AtomicU64, Ordering};
static COUNTER: AtomicU64 = AtomicU64::new(0);
let pid = std::process::id();
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or(0);
let seq = COUNTER.fetch_add(1, Ordering::Relaxed);
std::env::temp_dir().join(format!("vibestats_hooks_{name}_{pid}_{nanos}_{seq}.toml"))
}
#[test]
fn throttle_branch_checkpoint_with_recent_timestamp() {
let mut cp = Checkpoint::default();
cp.update_throttle_timestamp();
assert!(
cp.should_throttle(),
"should_throttle must be true immediately after update"
);
}
#[test]
fn no_throttle_branch_checkpoint_with_old_timestamp() {
let cp = Checkpoint {
throttle_timestamp: Some("2020-01-01T00:00:00Z".to_string()),
..Default::default()
};
assert!(
!cp.should_throttle(),
"should_throttle must be false for old timestamp"
);
}
#[test]
fn no_throttle_branch_checkpoint_absent() {
let cp = Checkpoint::default();
assert!(
!cp.should_throttle(),
"should_throttle must be false when no throttle_timestamp is set"
);
}
#[test]
fn throttle_save_does_not_clobber_sync_persisted_fields() {
let path = temp_path("no_clobber");
let mut sync_cp = Checkpoint::default();
sync_cp.update_hash("2026-04-10", "deadbeef");
sync_cp.set_auth_error();
sync_cp.save(&path).unwrap();
let mut throttle_cp = Checkpoint::load(&path);
throttle_cp.update_throttle_timestamp();
throttle_cp.save(&path).unwrap();
let final_cp = Checkpoint::load(&path);
assert!(
final_cp.hash_matches("2026-04-10", "deadbeef"),
"date_hashes written by sync::run must survive throttle save"
);
assert!(
final_cp.auth_error,
"auth_error written by sync::run must survive throttle save"
);
assert!(
final_cp.throttle_timestamp.is_some(),
"stop_hook must have stamped throttle_timestamp"
);
let _ = std::fs::remove_file(&path); }
}