#![allow(missing_docs)]
use std::thread;
use std::time::Duration;
#[test]
fn test_std_008_now_positive() {
let result = ruchy::stdlib::time::now();
assert!(result.is_ok(), "now() should succeed");
let timestamp = result.unwrap();
assert!(timestamp > 0, "Timestamp should be positive");
}
#[test]
fn test_std_008_now_reasonable_range() {
let result = ruchy::stdlib::time::now();
assert!(result.is_ok(), "now() should succeed");
let timestamp = result.unwrap();
assert!(
timestamp > 1_577_836_800_000,
"Timestamp should be after 2020-01-01"
);
assert!(
timestamp < 4_102_444_800_000,
"Timestamp should be before 2100-01-01"
);
}
#[test]
fn test_std_008_now_monotonic() {
let first = ruchy::stdlib::time::now().unwrap();
thread::sleep(Duration::from_millis(10));
let second = ruchy::stdlib::time::now().unwrap();
assert!(
second >= first,
"Second timestamp should be >= first timestamp"
);
}
#[test]
fn test_std_008_elapsed_millis_zero() {
let start = ruchy::stdlib::time::now().unwrap();
let result = ruchy::stdlib::time::elapsed_millis(start);
assert!(result.is_ok(), "elapsed_millis should succeed");
let elapsed = result.unwrap();
assert!(elapsed < 100, "Immediate elapsed should be small (< 100ms)");
}
#[test]
fn test_std_008_elapsed_millis_positive() {
let start = ruchy::stdlib::time::now().unwrap();
thread::sleep(Duration::from_millis(50));
let result = ruchy::stdlib::time::elapsed_millis(start);
assert!(result.is_ok(), "elapsed_millis should succeed");
let elapsed = result.unwrap();
assert!(elapsed >= 40, "Elapsed should be >= 40ms (50ms sleep)");
assert!(
elapsed < 200,
"Elapsed should be < 200ms (reasonable tolerance)"
);
}
#[test]
fn test_std_008_elapsed_millis_increases() {
let start = ruchy::stdlib::time::now().unwrap();
thread::sleep(Duration::from_millis(10));
let first_elapsed = ruchy::stdlib::time::elapsed_millis(start).unwrap();
thread::sleep(Duration::from_millis(10));
let second_elapsed = ruchy::stdlib::time::elapsed_millis(start).unwrap();
assert!(
second_elapsed > first_elapsed,
"Second elapsed should be greater than first"
);
}
#[test]
fn test_std_008_sleep_millis_basic() {
let start = ruchy::stdlib::time::now().unwrap();
let result = ruchy::stdlib::time::sleep_millis(50);
let elapsed = ruchy::stdlib::time::elapsed_millis(start).unwrap();
assert!(result.is_ok(), "sleep_millis should succeed");
assert!(elapsed >= 40, "Sleep should be >= 40ms");
assert!(elapsed < 150, "Sleep should be < 150ms (with tolerance)");
}
#[test]
fn test_std_008_sleep_millis_zero() {
let result = ruchy::stdlib::time::sleep_millis(0);
assert!(result.is_ok(), "sleep_millis(0) should succeed");
}
#[test]
fn test_std_008_sleep_millis_large() {
let result = std::panic::catch_unwind(|| ruchy::stdlib::time::sleep_millis(1));
assert!(result.is_ok(), "sleep_millis should not panic");
}
#[test]
fn test_std_008_duration_secs_conversion() {
let result = ruchy::stdlib::time::duration_secs(1000);
assert!(result.is_ok(), "duration_secs should succeed");
let secs = result.unwrap();
assert!((secs - 1.0).abs() < 0.01, "1000ms should be ~1.0 seconds");
}
#[test]
fn test_std_008_duration_secs_zero() {
let result = ruchy::stdlib::time::duration_secs(0);
assert!(result.is_ok(), "duration_secs should succeed");
let secs = result.unwrap();
assert_eq!(secs, 0.0, "0ms should be 0.0 seconds");
}
#[test]
fn test_std_008_duration_secs_fractional() {
let result = ruchy::stdlib::time::duration_secs(1500);
assert!(result.is_ok(), "duration_secs should succeed");
let secs = result.unwrap();
assert!((secs - 1.5).abs() < 0.01, "1500ms should be ~1.5 seconds");
}
#[test]
fn test_std_008_format_duration_milliseconds() {
let result = ruchy::stdlib::time::format_duration(500);
assert!(result.is_ok(), "format_duration should succeed");
let formatted = result.unwrap();
assert_eq!(formatted, "500ms", "500ms should format as '500ms'");
}
#[test]
fn test_std_008_format_duration_seconds() {
let result = ruchy::stdlib::time::format_duration(5000);
assert!(result.is_ok(), "format_duration should succeed");
let formatted = result.unwrap();
assert_eq!(formatted, "5s", "5000ms should format as '5s'");
}
#[test]
fn test_std_008_format_duration_minutes() {
let result = ruchy::stdlib::time::format_duration(150_000);
assert!(result.is_ok(), "format_duration should succeed");
let formatted = result.unwrap();
assert_eq!(formatted, "2m 30s", "150000ms should format as '2m 30s'");
}
#[test]
fn test_std_008_format_duration_hours() {
let result = ruchy::stdlib::time::format_duration(5_400_000);
assert!(result.is_ok(), "format_duration should succeed");
let formatted = result.unwrap();
assert_eq!(formatted, "1h 30m", "5400000ms should format as '1h 30m'");
}
#[test]
fn test_std_008_format_duration_days() {
let result = ruchy::stdlib::time::format_duration(183_600_000);
assert!(result.is_ok(), "format_duration should succeed");
let formatted = result.unwrap();
assert_eq!(formatted, "2d 3h", "183600000ms should format as '2d 3h'");
}
#[test]
fn test_std_008_parse_duration_milliseconds() {
let result = ruchy::stdlib::time::parse_duration("500ms");
assert!(result.is_ok(), "parse_duration should succeed");
let millis = result.unwrap();
assert_eq!(millis, 500, "'500ms' should parse to 500");
}
#[test]
fn test_std_008_parse_duration_seconds() {
let result = ruchy::stdlib::time::parse_duration("5s");
assert!(result.is_ok(), "parse_duration should succeed");
let millis = result.unwrap();
assert_eq!(millis, 5000, "'5s' should parse to 5000");
}
#[test]
fn test_std_008_parse_duration_complex() {
let result = ruchy::stdlib::time::parse_duration("1h 30m");
assert!(result.is_ok(), "parse_duration should succeed");
let millis = result.unwrap();
assert_eq!(millis, 5_400_000, "'1h 30m' should parse to 5400000");
}
#[test]
fn test_std_008_parse_duration_invalid() {
let result = ruchy::stdlib::time::parse_duration("invalid");
assert!(
result.is_err(),
"parse_duration should fail for invalid format"
);
let error = result.unwrap_err();
assert!(!error.is_empty(), "Error message should not be empty");
}
#[cfg(test)]
mod property_tests {
use super::*;
use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(20))]
#[test]
fn test_std_008_now_never_panics(iterations in 1usize..100) {
for _ in 0..iterations {
let _ = ruchy::stdlib::time::now();
}
}
#[test]
fn test_std_008_elapsed_always_positive(delay_ms in 0u64..100) {
let start = ruchy::stdlib::time::now().unwrap();
thread::sleep(Duration::from_millis(delay_ms));
let elapsed = ruchy::stdlib::time::elapsed_millis(start).unwrap();
assert!(elapsed >= u128::from(delay_ms), "Elapsed time should be at least the sleep duration");
}
#[test]
fn test_std_008_format_parse_roundtrip(millis in 0u128..1_000_000_000) {
if let Ok(formatted) = ruchy::stdlib::time::format_duration(millis) {
if let Ok(parsed) = ruchy::stdlib::time::parse_duration(&formatted) {
let diff = millis.abs_diff(parsed);
prop_assert!(
diff < 1000,
"Roundtrip difference should be < 1000ms: {} vs {}",
millis,
parsed
);
}
}
}
}
}