From 6678a485c3b9b2fef32317a461e309a95bf68dad Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 06:21:37 +0000 Subject: [PATCH 1/4] Add comprehensive tests for `stdlib::time` module functions Added unit tests to `src/stdlib/time.rs` to verify the functionality of previously untested native functions including `native_today`, `native_create_date`, `native_add_days`, and `native_days_between`. These tests cover positive validation paths and explicit failure modes (such as invalid month or day bounds in `create_date`, or adding negative days in `add_days`). Co-authored-by: logbie <1138960+logbie@users.noreply.github.com> --- src/stdlib/time.rs | 107 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/stdlib/time.rs b/src/stdlib/time.rs index 416fbc88..ac6aaf38 100644 --- a/src/stdlib/time.rs +++ b/src/stdlib/time.rs @@ -234,3 +234,110 @@ pub fn register_time(env: &mut Environment) { env.define_native("days_between", native_days_between); env.define_native("current_date", native_current_date); } + +#[cfg(test)] +mod tests { + use super::*; + use chrono::NaiveDate; + + #[test] + fn test_native_today() { + let result = native_today(vec![]); + assert!(result.is_ok()); + if let Value::Date(d) = result.unwrap() { + let expected = Local::now().date_naive(); + assert_eq!(*d, expected); + } else { + panic!("Expected Date variant"); + } + } + + #[test] + fn test_native_create_date_valid() { + let args = vec![ + Value::Number(2023.0), + Value::Number(10.0), + Value::Number(25.0), + ]; + let result = native_create_date(args); + assert!(result.is_ok()); + if let Value::Date(d) = result.unwrap() { + assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); + } else { + panic!("Expected Date variant"); + } + } + + #[test] + fn test_native_create_date_invalid_month() { + let args = vec![ + Value::Number(2023.0), + Value::Number(13.0), // Invalid month + Value::Number(25.0), + ]; + let result = native_create_date(args); + assert!(result.is_err()); + } + + #[test] + fn test_native_create_date_invalid_day() { + let args = vec![ + Value::Number(2023.0), + Value::Number(10.0), + Value::Number(32.0), // Invalid day + ]; + let result = native_create_date(args); + assert!(result.is_err()); + } + + #[test] + fn test_native_add_days() { + let start_date = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); + let args = vec![ + Value::Date(start_date), + Value::Number(5.0), + ]; + let result = native_add_days(args); + assert!(result.is_ok()); + if let Value::Date(d) = result.unwrap() { + assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 30).unwrap()); + } else { + panic!("Expected Date variant"); + } + } + + #[test] + fn test_native_add_days_negative() { + let start_date = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); + let args = vec![ + Value::Date(start_date), + Value::Number(-5.0), + ]; + let result = native_add_days(args); + assert!(result.is_ok()); + if let Value::Date(d) = result.unwrap() { + assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 20).unwrap()); + } else { + panic!("Expected Date variant"); + } + } + + #[test] + fn test_native_days_between() { + let date1 = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 20).unwrap()); + let date2 = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); + + // date1 is older, date2 is newer + let args = vec![ + Value::Date(date1), + Value::Date(date2), + ]; + let result = native_days_between(args); + assert!(result.is_ok()); + if let Value::Number(n) = result.unwrap() { + assert_eq!(n, 5.0); + } else { + panic!("Expected Number variant"); + } + } +} From 61e28e1753fb61671ca7337c06877bdd66a4d8e6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 06:27:34 +0000 Subject: [PATCH 2/4] fix: Formatting of `stdlib::time.rs` and correct native function testing Ran `cargo fmt` to address the CI failures related to formatting in the newly added tests for `src/stdlib/time.rs`. The code is now correctly formatted and CI should pass. Co-authored-by: logbie <1138960+logbie@users.noreply.github.com> --- src/stdlib/time.rs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/stdlib/time.rs b/src/stdlib/time.rs index ac6aaf38..53d10fb0 100644 --- a/src/stdlib/time.rs +++ b/src/stdlib/time.rs @@ -293,10 +293,7 @@ mod tests { #[test] fn test_native_add_days() { let start_date = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); - let args = vec![ - Value::Date(start_date), - Value::Number(5.0), - ]; + let args = vec![Value::Date(start_date), Value::Number(5.0)]; let result = native_add_days(args); assert!(result.is_ok()); if let Value::Date(d) = result.unwrap() { @@ -309,10 +306,7 @@ mod tests { #[test] fn test_native_add_days_negative() { let start_date = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); - let args = vec![ - Value::Date(start_date), - Value::Number(-5.0), - ]; + let args = vec![Value::Date(start_date), Value::Number(-5.0)]; let result = native_add_days(args); assert!(result.is_ok()); if let Value::Date(d) = result.unwrap() { @@ -328,10 +322,7 @@ mod tests { let date2 = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); // date1 is older, date2 is newer - let args = vec![ - Value::Date(date1), - Value::Date(date2), - ]; + let args = vec![Value::Date(date1), Value::Date(date2)]; let result = native_days_between(args); assert!(result.is_ok()); if let Value::Number(n) = result.unwrap() { From 45b9ae93867fb3436a17daf4e3be6c739cf947b7 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 08:05:43 +0000 Subject: [PATCH 3/4] test: Move `stdlib::time` tests to integration file and fix race condition Following PR feedback, the inline tests originally added to `src/stdlib/time.rs` have been removed and appended to the existing integration test file `tests/time_stdlib_test.rs`. The code was correctly formatted using `cargo fmt`, and a midnight-rollover race condition in `test_native_today` was resolved by capturing the expected date before calling the function under test. Co-authored-by: logbie <1138960+logbie@users.noreply.github.com> --- src/stdlib/time.rs | 98 --------------------------------------- tests/time_stdlib_test.rs | 96 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 98 deletions(-) diff --git a/src/stdlib/time.rs b/src/stdlib/time.rs index 53d10fb0..416fbc88 100644 --- a/src/stdlib/time.rs +++ b/src/stdlib/time.rs @@ -234,101 +234,3 @@ pub fn register_time(env: &mut Environment) { env.define_native("days_between", native_days_between); env.define_native("current_date", native_current_date); } - -#[cfg(test)] -mod tests { - use super::*; - use chrono::NaiveDate; - - #[test] - fn test_native_today() { - let result = native_today(vec![]); - assert!(result.is_ok()); - if let Value::Date(d) = result.unwrap() { - let expected = Local::now().date_naive(); - assert_eq!(*d, expected); - } else { - panic!("Expected Date variant"); - } - } - - #[test] - fn test_native_create_date_valid() { - let args = vec![ - Value::Number(2023.0), - Value::Number(10.0), - Value::Number(25.0), - ]; - let result = native_create_date(args); - assert!(result.is_ok()); - if let Value::Date(d) = result.unwrap() { - assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); - } else { - panic!("Expected Date variant"); - } - } - - #[test] - fn test_native_create_date_invalid_month() { - let args = vec![ - Value::Number(2023.0), - Value::Number(13.0), // Invalid month - Value::Number(25.0), - ]; - let result = native_create_date(args); - assert!(result.is_err()); - } - - #[test] - fn test_native_create_date_invalid_day() { - let args = vec![ - Value::Number(2023.0), - Value::Number(10.0), - Value::Number(32.0), // Invalid day - ]; - let result = native_create_date(args); - assert!(result.is_err()); - } - - #[test] - fn test_native_add_days() { - let start_date = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); - let args = vec![Value::Date(start_date), Value::Number(5.0)]; - let result = native_add_days(args); - assert!(result.is_ok()); - if let Value::Date(d) = result.unwrap() { - assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 30).unwrap()); - } else { - panic!("Expected Date variant"); - } - } - - #[test] - fn test_native_add_days_negative() { - let start_date = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); - let args = vec![Value::Date(start_date), Value::Number(-5.0)]; - let result = native_add_days(args); - assert!(result.is_ok()); - if let Value::Date(d) = result.unwrap() { - assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 20).unwrap()); - } else { - panic!("Expected Date variant"); - } - } - - #[test] - fn test_native_days_between() { - let date1 = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 20).unwrap()); - let date2 = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); - - // date1 is older, date2 is newer - let args = vec![Value::Date(date1), Value::Date(date2)]; - let result = native_days_between(args); - assert!(result.is_ok()); - if let Value::Number(n) = result.unwrap() { - assert_eq!(n, 5.0); - } else { - panic!("Expected Number variant"); - } - } -} diff --git a/tests/time_stdlib_test.rs b/tests/time_stdlib_test.rs index 29e9846a..5ef69861 100644 --- a/tests/time_stdlib_test.rs +++ b/tests/time_stdlib_test.rs @@ -88,3 +88,99 @@ fn test_native_create_time_invalid_values() { let result = native_create_time(args); assert!(result.is_err(), "create_time should fail with second >= 60"); } + +use chrono::{Local, NaiveDate}; +use std::rc::Rc; +use wfl::stdlib::time::{native_add_days, native_create_date, native_days_between, native_today}; + +#[test] +fn test_native_today() { + let expected = Local::now().date_naive(); + let result = native_today(vec![]); + assert!(result.is_ok()); + if let Value::Date(d) = result.unwrap() { + assert_eq!(*d, expected); + } else { + panic!("Expected Date variant"); + } +} + +#[test] +fn test_native_create_date_valid() { + let args = vec![ + Value::Number(2023.0), + Value::Number(10.0), + Value::Number(25.0), + ]; + let result = native_create_date(args); + assert!(result.is_ok()); + if let Value::Date(d) = result.unwrap() { + assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); + } else { + panic!("Expected Date variant"); + } +} + +#[test] +fn test_native_create_date_invalid_month() { + let args = vec![ + Value::Number(2023.0), + Value::Number(13.0), // Invalid month + Value::Number(25.0), + ]; + let result = native_create_date(args); + assert!(result.is_err()); +} + +#[test] +fn test_native_create_date_invalid_day() { + let args = vec![ + Value::Number(2023.0), + Value::Number(10.0), + Value::Number(32.0), // Invalid day + ]; + let result = native_create_date(args); + assert!(result.is_err()); +} + +#[test] +fn test_native_add_days() { + let start_date = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); + let args = vec![Value::Date(start_date), Value::Number(5.0)]; + let result = native_add_days(args); + assert!(result.is_ok()); + if let Value::Date(d) = result.unwrap() { + assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 30).unwrap()); + } else { + panic!("Expected Date variant"); + } +} + +#[test] +fn test_native_add_days_negative() { + let start_date = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); + let args = vec![Value::Date(start_date), Value::Number(-5.0)]; + let result = native_add_days(args); + assert!(result.is_ok()); + if let Value::Date(d) = result.unwrap() { + assert_eq!(*d, NaiveDate::from_ymd_opt(2023, 10, 20).unwrap()); + } else { + panic!("Expected Date variant"); + } +} + +#[test] +fn test_native_days_between() { + let date1 = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 20).unwrap()); + let date2 = Rc::new(NaiveDate::from_ymd_opt(2023, 10, 25).unwrap()); + + // date1 is older, date2 is newer + let args = vec![Value::Date(date1), Value::Date(date2)]; + let result = native_days_between(args); + assert!(result.is_ok()); + if let Value::Number(n) = result.unwrap() { + assert_eq!(n, 5.0); + } else { + panic!("Expected Number variant"); + } +} From 0fb1aea12c62ddf82f397bc98e1add84c0bb2839 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 03:48:18 +0000 Subject: [PATCH 4/4] test: Add `day = 0` test case to `stdlib::time` invalid day testing Added a boundary test checking that `day = 0` correctly yields an error in `native_create_date`, completing the boundary check alongside the `day = 32` invalid case. Co-authored-by: logbie <1138960+logbie@users.noreply.github.com> --- tests/time_stdlib_test.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/time_stdlib_test.rs b/tests/time_stdlib_test.rs index 5ef69861..bb7c6888 100644 --- a/tests/time_stdlib_test.rs +++ b/tests/time_stdlib_test.rs @@ -141,6 +141,14 @@ fn test_native_create_date_invalid_day() { ]; let result = native_create_date(args); assert!(result.is_err()); + + let args_zero = vec![ + Value::Number(2023.0), + Value::Number(10.0), + Value::Number(0.0), // Invalid day (too low) + ]; + let result_zero = native_create_date(args_zero); + assert!(result_zero.is_err()); } #[test]