use chrono::Duration;
use qubit_clock::meter::TimeMeter;
use qubit_clock::{Clock, MockClock, MonotonicClock};
use std::thread;
use std::time::Duration as StdDuration;
#[test]
fn test_new() {
let meter = TimeMeter::new();
assert!(!meter.is_running());
assert!(!meter.is_stopped());
assert_eq!(meter.millis(), 0);
}
#[test]
fn test_with_clock() {
let clock = MonotonicClock::new();
let meter = TimeMeter::with_clock(clock);
assert!(!meter.is_running());
assert!(!meter.is_stopped());
assert_eq!(meter.millis(), 0);
}
#[test]
fn test_with_clock_started() {
let clock = MonotonicClock::new();
let meter = TimeMeter::with_clock_started(clock);
assert!(meter.is_running());
assert!(!meter.is_stopped());
}
#[test]
fn test_start_now() {
let meter = TimeMeter::start_now();
assert!(meter.is_running());
assert!(!meter.is_stopped());
}
#[test]
fn test_start_and_stop() {
let mut meter = TimeMeter::new();
assert!(!meter.is_running());
assert!(!meter.is_stopped());
meter.start();
assert!(meter.is_running());
assert!(!meter.is_stopped());
meter.stop();
assert!(!meter.is_running());
assert!(meter.is_stopped());
}
#[test]
fn test_restart() {
let mut meter = TimeMeter::new();
meter.start();
thread::sleep(StdDuration::from_millis(10));
meter.stop();
let first_duration = meter.millis();
meter.restart();
assert!(meter.is_running());
assert!(!meter.is_stopped());
thread::sleep(StdDuration::from_millis(10));
meter.stop();
let second_duration = meter.millis();
assert!(second_duration < first_duration + second_duration);
}
#[test]
fn test_reset() {
let mut meter = TimeMeter::start_now();
thread::sleep(StdDuration::from_millis(10));
meter.stop();
meter.reset();
assert!(!meter.is_running());
assert!(!meter.is_stopped());
assert_eq!(meter.millis(), 0);
}
#[test]
fn test_millis_with_mock_clock() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(1000, false);
meter.stop();
assert_eq!(meter.millis(), 1000);
}
#[test]
fn test_millis_not_started() {
let meter = TimeMeter::new();
assert_eq!(meter.millis(), 0);
}
#[test]
fn test_millis_running() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(500, false);
assert_eq!(meter.millis(), 500);
clock.add_millis(500, false);
assert_eq!(meter.millis(), 1000);
}
#[test]
fn test_millis_stopped() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(1000, false);
meter.stop();
assert_eq!(meter.millis(), 1000);
clock.add_millis(1000, false);
assert_eq!(meter.millis(), 1000); }
#[test]
fn test_seconds() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(5500, false);
meter.stop();
assert_eq!(meter.seconds(), 5);
}
#[test]
fn test_minutes() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(125000, false); meter.stop();
assert_eq!(meter.minutes(), 2);
}
#[test]
fn test_duration() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(1500, false);
meter.stop();
let duration = meter.duration();
assert_eq!(duration, Duration::milliseconds(1500));
}
#[test]
fn test_readable_duration() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(1500, false);
meter.stop();
let readable = meter.readable_duration();
assert_eq!(readable, "1.5s");
}
#[test]
fn test_speed_per_second_zero_time() {
let meter = TimeMeter::new();
assert_eq!(meter.speed_per_second(1000), None);
}
#[test]
fn test_speed_per_second() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(2000, false); meter.stop();
let speed = meter.speed_per_second(1000);
assert_eq!(speed, Some(500.0)); }
#[test]
fn test_speed_per_minute_zero_time() {
let meter = TimeMeter::new();
assert_eq!(meter.speed_per_minute(1000), None);
}
#[test]
fn test_speed_per_minute() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(2000, false); meter.stop();
let speed = meter.speed_per_minute(1000);
assert_eq!(speed, Some(30000.0)); }
#[test]
fn test_formatted_speed_per_second_zero_time() {
let meter = TimeMeter::new();
assert_eq!(meter.formatted_speed_per_second(1000), "N/A");
}
#[test]
fn test_formatted_speed_per_second() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(2000, false);
meter.stop();
let formatted = meter.formatted_speed_per_second(1000);
assert_eq!(formatted, "500.00/s");
}
#[test]
fn test_formatted_speed_per_minute_zero_time() {
let meter = TimeMeter::new();
assert_eq!(meter.formatted_speed_per_minute(1000), "N/A");
}
#[test]
fn test_formatted_speed_per_minute() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(2000, false);
meter.stop();
let formatted = meter.formatted_speed_per_minute(1000);
assert_eq!(formatted, "30000.00/m");
}
#[test]
fn test_is_running_states() {
let mut meter = TimeMeter::new();
assert!(!meter.is_running());
meter.start();
assert!(meter.is_running());
meter.stop();
assert!(!meter.is_running());
meter.start();
assert!(meter.is_running());
}
#[test]
fn test_is_stopped_states() {
let mut meter = TimeMeter::new();
assert!(!meter.is_stopped());
meter.start();
assert!(!meter.is_stopped());
meter.stop();
assert!(meter.is_stopped());
meter.start();
assert!(!meter.is_stopped());
}
#[test]
fn test_clock_accessors() {
let clock = MonotonicClock::new();
let initial_time = clock.millis();
let mut meter = TimeMeter::with_clock(clock);
let clock_ref = meter.clock();
let time1 = clock_ref.millis();
assert!(time1 >= initial_time);
let _clock_mut = meter.clock_mut();
}
#[test]
fn test_multiple_start_calls() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(1000, false);
meter.start();
clock.add_millis(500, false);
meter.stop();
assert_eq!(meter.millis(), 500);
}
#[test]
fn test_real_time_measurement() {
let mut meter = TimeMeter::new();
meter.start();
thread::sleep(StdDuration::from_millis(100));
meter.stop();
let elapsed = meter.millis();
assert!(elapsed >= 95);
}
#[test]
fn test_real_time_without_stop() {
let meter = TimeMeter::start_now();
thread::sleep(StdDuration::from_millis(50));
let elapsed1 = meter.millis();
thread::sleep(StdDuration::from_millis(50));
let elapsed2 = meter.millis();
assert!(elapsed2 > elapsed1);
assert!(elapsed1 >= 45);
assert!(elapsed2 >= 95);
}
#[test]
fn test_default_trait() {
let meter: TimeMeter<MonotonicClock> = Default::default();
assert!(!meter.is_running());
assert_eq!(meter.millis(), 0);
}
#[test]
fn test_speed_calculation_with_fractional_seconds() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(500, false); meter.stop();
assert_eq!(meter.seconds(), 0);
assert_eq!(meter.speed_per_second(1000), Some(2000.0));
assert_eq!(meter.speed_per_minute(1000), Some(120_000.0));
meter.restart();
clock.add_millis(1500, false); meter.stop();
let speed = meter
.speed_per_second(1000)
.expect("speed should be available for positive elapsed time");
assert!((speed - 666.6666666666666).abs() < 1e-9);
}
#[test]
fn test_edge_case_zero_count() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(1000, false);
meter.stop();
assert_eq!(meter.speed_per_second(0), Some(0.0));
assert_eq!(meter.speed_per_minute(0), Some(0.0));
}
#[test]
fn test_edge_case_large_count() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(1000, false);
meter.stop();
let large_count = 1_000_000_000;
assert_eq!(
meter.speed_per_second(large_count),
Some(large_count as f64)
);
}
#[test]
fn test_is_running_with_end_time_set() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
assert!(meter.is_running());
assert!(meter.is_running());
meter.stop();
assert!(!meter.is_running()); }
#[test]
fn test_millis_when_not_started() {
let clock = MockClock::new();
let meter = TimeMeter::with_clock(clock.clone());
assert_eq!(meter.millis(), 0); }
#[test]
fn test_millis_uses_current_time_when_running() {
let clock = MockClock::new();
let mut meter = TimeMeter::with_clock(clock.clone());
meter.start();
clock.add_millis(100, false);
let elapsed1 = meter.millis();
assert_eq!(elapsed1, 100);
clock.add_millis(50, false);
let elapsed2 = meter.millis();
assert_eq!(elapsed2, 150);
meter.stop();
clock.add_millis(100, false);
let elapsed3 = meter.millis();
assert_eq!(elapsed3, 150); }