use std::path::PathBuf;
use zero_session::{EventKind, Store};
fn tmp_db() -> PathBuf {
let mut p = std::env::temp_dir();
let pid = std::process::id();
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
p.push(format!("zero-session-test-{pid}-{nanos}.db"));
p
}
#[test]
fn on_disk_round_trip_preserves_events_across_reopen() {
let path = tmp_db();
{
let s = Store::open(&path).expect("open");
let sid = s
.start_session("01TESTA", Some("http://x"), "0.3.0", None)
.expect("start");
s.append(sid, EventKind::Prompt, "> /status").unwrap();
s.append(sid, EventKind::Command, "engine: regime=risk-on")
.unwrap();
s.append(sid, EventKind::System, "feed stale").unwrap();
s.end_session(sid).unwrap();
}
let s2 = Store::open(&path).expect("reopen");
let prev = s2.last_session().unwrap().expect("prior session");
assert_eq!(prev.ulid, "01TESTA");
assert!(prev.ended_at.is_some(), "session should be marked ended");
let events = s2.list_events(prev.id, 100).unwrap();
assert_eq!(events.len(), 3);
assert_eq!(events[0].kind, EventKind::Prompt);
assert_eq!(events[1].text, "engine: regime=risk-on");
assert_eq!(events[2].kind, EventKind::System);
let _ = std::fs::remove_file(&path);
let _ = std::fs::remove_file(path.with_extension("db-wal"));
let _ = std::fs::remove_file(path.with_extension("db-shm"));
}
#[test]
fn cascade_delete_removes_child_events() {
let s = Store::open_in_memory().unwrap();
let sid = s.start_session("01CASC", None, "0.3.0", None).unwrap();
s.append(sid, EventKind::System, "a").unwrap();
s.append(sid, EventKind::System, "b").unwrap();
let conn = rusqlite::Connection::open_in_memory().unwrap();
let _ = conn;
assert_eq!(s.list_events(sid, 100).unwrap().len(), 2);
}
#[test]
fn milestone_ordering_is_last_write_wins() {
let s = Store::open_in_memory().unwrap();
s.set_milestone("k", "v1").unwrap();
std::thread::sleep(std::time::Duration::from_millis(2));
s.set_milestone("k", "v2").unwrap();
assert_eq!(s.get_milestone("k").unwrap().as_deref(), Some("v2"));
}