diff --git a/src/sync_logic.rs b/src/sync_logic.rs index f2a0e2b..57011b2 100644 --- a/src/sync_logic.rs +++ b/src/sync_logic.rs @@ -135,3 +135,72 @@ impl LtcState { &self.last_match_status } } + +#[cfg(test)] +mod tests { + use super::*; + use chrono::{Local, Utc}; + + fn get_test_frame(status: &str, h: u32, m: u32, s: u32) -> LtcFrame { + LtcFrame { + status: status.to_string(), + hours: h, + minutes: m, + seconds: s, + frames: 0, + frame_rate: 25.0, + timestamp: Utc::now(), + } + } + + #[test] + fn test_ltc_frame_matches_system_time() { + let now = Local::now(); + let frame = get_test_frame("LOCK", now.hour(), now.minute(), now.second()); + assert!(frame.matches_system_time()); + } + + #[test] + fn test_ltc_frame_does_not_match_system_time() { + let now = Local::now(); + // Create a time that is one hour ahead, wrapping around 23:00 + let different_hour = (now.hour() + 1) % 24; + let frame = get_test_frame("LOCK", different_hour, now.minute(), now.second()); + assert!(!frame.matches_system_time()); + } + + #[test] + fn test_ltc_state_update_lock() { + let mut state = LtcState::new(); + let frame = get_test_frame("LOCK", 10, 20, 30); + state.update(frame); + assert_eq!(state.lock_count, 1); + assert_eq!(state.free_count, 0); + assert!(state.latest.is_some()); + } + + #[test] + fn test_ltc_state_update_free() { + let mut state = LtcState::new(); + state.record_offset(100); + assert!(!state.offset_history.is_empty()); + + let frame = get_test_frame("FREE", 10, 20, 30); + state.update(frame); + assert_eq!(state.lock_count, 0); + assert_eq!(state.free_count, 1); + assert!(state.offset_history.is_empty()); // Offsets should be cleared + assert_eq!(state.last_match_status, "UNKNOWN"); + } + + #[test] + fn test_offset_history_management() { + let mut state = LtcState::new(); + for i in 0..25 { + state.record_offset(i); + } + assert_eq!(state.offset_history.len(), 20); + assert_eq!(*state.offset_history.front().unwrap(), 5); // 0-4 are pushed out + assert_eq!(*state.offset_history.back().unwrap(), 24); + } +}