// tests/suite/test_time.el — comprehensive tests for runtime/time.el // // Covers time_now, now_millis, unix_timestamp, now_ns, time_format, time_to_parts, // time_add, time_diff, duration helpers, and uuid_new. // ── time_now / now_millis / unix_timestamp_ms ───────────────────────────────── fn test_time_now_basic(_: String) -> String { let t: Int = time_now() // Milliseconds since epoch: must be well past year 2020 (1577836800000) assert_true(t > 1577836800000, "time_now is past 2020-01-01") // Must be before year 2100 (4102444800000) assert_true(t < 4102444800000, "time_now is before 2100-01-01") return "" } fn test_now_millis_basic(_: String) -> String { let t: Int = now_millis() assert_true(t > 1577836800000, "now_millis is past 2020-01-01") assert_true(t < 4102444800000, "now_millis is before 2100-01-01") return "" } fn test_unix_timestamp_ms_basic(_: String) -> String { let t: Int = unix_timestamp_ms() assert_true(t > 1577836800000, "unix_timestamp_ms is past 2020-01-01") assert_true(t < 4102444800000, "unix_timestamp_ms is before 2100-01-01") return "" } fn test_time_now_ms_alias(_: String) -> String { let t: Int = time_now_ms() assert_true(t > 1577836800000, "time_now_ms is past 2020-01-01") assert_true(t < 4102444800000, "time_now_ms is before 2100-01-01") return "" } // ── monotonicity ────────────────────────────────────────────────────────────── fn test_time_monotonic_now_millis(_: String) -> String { let t1: Int = now_millis() let t2: Int = now_millis() assert_true(t2 >= t1, "second call >= first call (monotonic)") return "" } fn test_time_monotonic_time_now(_: String) -> String { let t1: Int = time_now() let t2: Int = time_now() assert_true(t2 >= t1, "time_now is monotonic across calls") return "" } fn test_time_monotonic_now_ns(_: String) -> String { let t1: Int = now_ns() let t2: Int = now_ns() assert_true(t2 >= t1, "now_ns is monotonic across calls") // ns should be much larger than ms (9 digits difference) assert_true(t1 > 1000000000000000000, "now_ns is in nanosecond scale") return "" } // ── unix_timestamp (seconds) ───────────────────────────────────────────────── fn test_unix_timestamp_basic(_: String) -> String { let secs: Int = unix_timestamp() // Must be past 2020-01-01 in seconds (1577836800) assert_true(secs > 1577836800, "unix_timestamp is past 2020-01-01") // Must be before 2100-01-01 in seconds (4102444800) assert_true(secs < 4102444800, "unix_timestamp is before 2100-01-01") // seconds are about 1000x smaller than millis let ms: Int = time_now() assert_true(ms > secs, "milliseconds > seconds") return "" } // ── time_to_parts ───────────────────────────────────────────────────────────── fn test_time_to_parts_basic(_: String) -> String { // Known timestamp: 2024-01-15 12:30:45.123 UTC // 2024-01-15 00:00:00 UTC = epoch + (54 * 365 + 14 leaps) days approximately // Use a precisely known value: 2024-01-15T12:30:45.123Z // epoch_ms = 1705320645123 let ts: Int = 1705320645123 let parts: String = time_to_parts(ts) assert_eq(json_get(parts, "year"), "2024", "year is 2024") assert_eq(json_get(parts, "month"), "1", "month is 1 (January)") assert_eq(json_get(parts, "day"), "15", "day is 15") assert_eq(json_get(parts, "hour"), "12", "hour is 12") assert_eq(json_get(parts, "minute"), "30", "minute is 30") assert_eq(json_get(parts, "second"), "45", "second is 45") assert_eq(json_get(parts, "ms"), "123", "milliseconds is 123") return "" } fn test_time_to_parts_epoch(_: String) -> String { // Unix epoch: 1970-01-01T00:00:00.000Z = timestamp 0 let parts: String = time_to_parts(0) assert_eq(json_get(parts, "year"), "1970", "epoch year is 1970") assert_eq(json_get(parts, "month"), "1", "epoch month is 1") assert_eq(json_get(parts, "day"), "1", "epoch day is 1") assert_eq(json_get(parts, "hour"), "0", "epoch hour is 0") assert_eq(json_get(parts, "minute"), "0", "epoch minute is 0") assert_eq(json_get(parts, "second"), "0", "epoch second is 0") return "" } fn test_time_to_parts_current(_: String) -> String { let ts: Int = time_now() let parts: String = time_to_parts(ts) let year: Int = str_to_int(json_get(parts, "year")) let month: Int = str_to_int(json_get(parts, "month")) let day: Int = str_to_int(json_get(parts, "day")) let hour: Int = str_to_int(json_get(parts, "hour")) let minute: Int = str_to_int(json_get(parts, "minute")) let second: Int = str_to_int(json_get(parts, "second")) assert_true(year >= 2024, "current year >= 2024") assert_true(year < 2100, "current year < 2100") assert_true(month >= 1, "month >= 1") assert_true(month <= 12, "month <= 12") assert_true(day >= 1, "day >= 1") assert_true(day <= 31, "day <= 31") assert_true(hour >= 0, "hour >= 0") assert_true(hour <= 23, "hour <= 23") assert_true(minute >= 0, "minute >= 0") assert_true(minute <= 59, "minute <= 59") assert_true(second >= 0, "second >= 0") assert_true(second <= 59, "second <= 59") return "" } // ── time_format ─────────────────────────────────────────────────────────────── fn test_time_format_iso(_: String) -> String { let ts: Int = 1705320645123 let iso: String = time_format(ts, "ISO") assert_starts_with(iso, "2024-01-15", "ISO format starts with correct date") assert_contains(iso, "T12:30:45", "ISO format has correct time") assert_ends_with(iso, "Z", "ISO format ends with Z") assert_contains(iso, "123", "ISO format includes milliseconds") return "" } fn test_time_format_empty(_: String) -> String { let ts: Int = 1705320645123 let iso: String = time_format(ts, "") assert_starts_with(iso, "2024-01-15", "empty fmt gives ISO format") assert_ends_with(iso, "Z", "empty fmt gives ISO format ending in Z") return "" } fn test_time_format_strftime(_: String) -> String { let ts: Int = 1705320645123 let formatted: String = time_format(ts, "%Y-%m-%d") assert_eq(formatted, "2024-01-15", "strftime %Y-%m-%d") let formatted2: String = time_format(ts, "%H:%M:%S") assert_eq(formatted2, "12:30:45", "strftime %H:%M:%S") return "" } // ── time_add ────────────────────────────────────────────────────────────────── fn test_time_add_basic(_: String) -> String { let base: Int = 1000000000000 assert_int_eq(time_add(base, 1000, "ms"), base + 1000, "add milliseconds") assert_int_eq(time_add(base, 1, "sec"), base + 1000, "add 1 second") assert_int_eq(time_add(base, 1, "min"), base + 60000, "add 1 minute") assert_int_eq(time_add(base, 1, "hour"), base + 3600000, "add 1 hour") assert_int_eq(time_add(base, 1, "day"), base + 86400000, "add 1 day") return "" } fn test_time_add_multiple(_: String) -> String { let base: Int = 1000000000000 assert_int_eq(time_add(base, 60, "sec"), base + 60000, "add 60 seconds") assert_int_eq(time_add(base, 24, "hour"), base + 86400000, "add 24 hours = 1 day") assert_int_eq(time_add(base, 0, "sec"), base, "add 0 seconds") assert_int_eq(time_add(base, -1, "sec"), base - 1000, "add negative seconds") return "" } // ── time_diff ───────────────────────────────────────────────────────────────── fn test_time_diff_basic(_: String) -> String { let t1: Int = 1000000000000 let t2: Int = t1 + 5000 assert_int_eq(time_diff(t1, t2, "ms"), 5000, "diff in ms") assert_int_eq(time_diff(t1, t2, "sec"), 5, "diff in seconds") return "" } fn test_time_diff_larger(_: String) -> String { let t1: Int = 1000000000000 let t2: Int = t1 + 3600000 assert_int_eq(time_diff(t1, t2, "min"), 60, "diff of 1 hour in minutes") assert_int_eq(time_diff(t1, t2, "hour"), 1, "diff of 1 hour in hours") assert_int_eq(time_diff(t1, t2, "ms"), 3600000, "diff of 1 hour in ms") return "" } fn test_time_diff_zero(_: String) -> String { let t: Int = 1000000000000 assert_int_eq(time_diff(t, t, "ms"), 0, "same timestamp: diff is 0") assert_int_eq(time_diff(t, t, "sec"), 0, "same timestamp: diff in sec is 0") return "" } // ── Duration helpers ────────────────────────────────────────────────────────── fn test_duration_helpers_basic(_: String) -> String { assert_int_eq(duration_seconds(1), 1000000000, "1 second = 1e9 ns") assert_int_eq(duration_millis(1), 1000000, "1 ms = 1e6 ns") assert_int_eq(duration_nanos(42), 42, "nanos identity") assert_int_eq(duration_to_seconds(1000000000), 1, "1e9 ns = 1 second") assert_int_eq(duration_to_millis(1000000), 1, "1e6 ns = 1 ms") assert_int_eq(duration_to_nanos(42), 42, "nanos identity roundtrip") return "" } fn test_instant_helpers_basic(_: String) -> String { let i: Int = unix_seconds(1000) assert_int_eq(i, 1000000000000, "unix_seconds(1000) = 1e12 ns") let ms_i: Int = unix_millis(5000) assert_int_eq(ms_i, 5000000000, "unix_millis(5000) = 5e9 ns") assert_int_eq(instant_to_unix_seconds(1000000000000), 1000, "instant to seconds") assert_int_eq(instant_to_unix_millis(5000000000), 5000, "instant to millis") return "" } // ── uuid_new / uuid_v4 ──────────────────────────────────────────────────────── fn test_uuid_new_basic(_: String) -> String { let u: String = uuid_new() assert_int_eq(str_len(u), 36, "UUID has 36 characters") assert_eq(str_char_at(u, 8), "-", "UUID has dash at position 8") assert_eq(str_char_at(u, 13), "-", "UUID has dash at position 13") assert_eq(str_char_at(u, 18), "-", "UUID has dash at position 18") assert_eq(str_char_at(u, 23), "-", "UUID has dash at position 23") return "" } fn test_uuid_uniqueness(_: String) -> String { let u1: String = uuid_new() let u2: String = uuid_new() let u3: String = uuid_v4() assert_false(str_eq(u1, u2), "consecutive UUIDs are different") assert_false(str_eq(u1, u3), "uuid_new and uuid_v4 produce different values") assert_false(str_eq(u2, u3), "three consecutive UUIDs are all different") assert_int_eq(str_len(u3), 36, "uuid_v4 also produces 36-char UUID") return "" } // ── time_from_parts ─────────────────────────────────────────────────────────── fn test_time_from_parts_basic(_: String) -> String { // time_from_parts(secs, ns, tz) = secs * 1000 + ns / 1000000 let ts: Int = time_from_parts(1000, 0, "UTC") assert_int_eq(ts, 1000000, "1000 secs = 1000000 ms") let ts2: Int = time_from_parts(0, 500000000, "UTC") assert_int_eq(ts2, 500, "500ms in nanoseconds -> 500ms") let ts3: Int = time_from_parts(1705320645, 123000000, "UTC") assert_int_eq(ts3, 1705320645123, "known timestamp with ms component") return "" } // ── instant_to_iso8601 ──────────────────────────────────────────────────────── fn test_instant_to_iso8601_basic(_: String) -> String { let ts_ms: Int = 1705320645123 let ts_ns: Int = ts_ms * 1000000 let iso: String = instant_to_iso8601(ts_ns) assert_starts_with(iso, "2024-01-15", "instant_to_iso8601 correct date") assert_ends_with(iso, "Z", "instant_to_iso8601 ends with Z") return "" }