use chrono::NaiveDate;
use json_eval_rs::*;
use serde_json::json;
#[cfg(test)]
mod date_tests {
use super::*;
#[test]
fn test_date_today() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"today": null})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert!(result.is_string());
let date_str = result.as_str().unwrap();
assert!(date_str.ends_with("T00:00:00.000Z"));
assert!(NaiveDate::parse_from_str(&date_str[..10], "%Y-%m-%d").is_ok());
}
#[test]
fn test_date_now() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"now": null})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert!(result.is_string());
let datetime_str = result.as_str().unwrap();
assert!(datetime_str.contains("T"));
assert!(datetime_str.len() > 10);
}
#[test]
fn test_date_component_extraction() {
let mut engine = RLogic::new();
let data = json!({"birthdate": "1990-05-15T10:30:00Z"});
let logic_id = engine
.compile(&json!({"year": {"var": "birthdate"}}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(1990));
let logic_id = engine
.compile(&json!({"month": {"var": "birthdate"}}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
let logic_id = engine
.compile(&json!({"day": {"var": "birthdate"}}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(15));
let logic_id = engine
.compile(&json!({"year": [{"var": "birthdate"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(1990));
let logic_id = engine
.compile(&json!({"month": [{"var": "birthdate"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
let logic_id = engine
.compile(&json!({"day": [{"var": "birthdate"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(15));
}
#[test]
fn test_date_construction() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"date": [2023, 12, 25]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2023-12-25T00:00:00.000Z"));
}
#[test]
fn test_date_arithmetic() {
let mut engine = RLogic::new();
let data = json!({"start": "2023-01-15T00:00:00Z", "end": "2023-01-20T00:00:00Z"});
let logic_id = engine
.compile(&json!({"days": [{"var": "end"}, {"var": "start"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
let logic_id = engine
.compile(&json!({"days": [{"var": "start"}, {"var": "end"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(-5));
}
#[test]
fn test_date_difference_functions() {
let mut engine = RLogic::new();
let data = json!({
"birth": "1990-03-15T00:00:00Z",
"today": "2023-07-10T00:00:00Z"
});
let logic_id = engine
.compile(&json!({"YEARFRAC": [{"var": "birth"}, {"var": "today"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
let years = result.as_f64().unwrap();
assert!((years - 33.8056).abs() < 0.001);
let logic_id = engine
.compile(&json!({"DATEDIF": [{"var": "birth"}, {"var": "today"}, "Y"]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(33));
let logic_id = engine
.compile(&json!({"DATEDIF": [{"var": "birth"}, {"var": "today"}, "M"]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(399));
let logic_id = engine
.compile(&json!({"DAYS": [{"var": "today"}, {"var": "birth"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert!(result.as_f64().unwrap() > 10000.0);
}
#[test]
fn test_date_edge_cases() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"year": "not-a-date"})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(null));
let logic_id = engine.compile(&json!({"month": null})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(null));
let logic_id = engine.compile(&json!({"day": ""})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(null));
let logic_id = engine.compile(&json!({"date": [2023, 13, 32]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2024-02-01T00:00:00.000Z"));
}
#[test]
fn test_date_parsing_formats() {
let mut engine = RLogic::new();
let data = json!({});
let test_cases = vec![
("2023-01-15", 2023, 1, 15),
("2023-01-15T00:00:00Z", 2023, 1, 15),
];
for (date_str, expected_year, expected_month, expected_day) in test_cases {
let logic_id = engine.compile(&json!({"year": date_str})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(expected_year));
let logic_id = engine.compile(&json!({"month": date_str})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(expected_month));
let logic_id = engine.compile(&json!({"day": date_str})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(expected_day));
}
}
#[test]
fn test_date_with_variables() {
let mut engine = RLogic::new();
let data = json!({
"birth_year": 1990,
"birth_month": 5,
"birth_day": 15,
"age_years": 33
});
let logic_id = engine
.compile(&json!({"date": [
{"var": "birth_year"},
{"var": "birth_month"},
{"var": "birth_day"}
]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("1990-05-15T00:00:00.000Z"));
let logic_id = engine
.compile(&json!({"days": [
{"today": null},
{"date": [{"var": "birth_year"}, {"var": "birth_month"}, {"var": "birth_day"}]}
]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
let days = result.as_f64().unwrap();
assert!(days > 1000.0);
}
#[test]
fn test_date_business_logic() {
let mut engine = RLogic::new();
let data = json!({
"hire_date": "2020-03-15T00:00:00Z",
"current_date": "2023-07-10T00:00:00Z"
});
let logic_id = engine
.compile(&json!({"days": [
{"var": "current_date"},
{"var": "hire_date"}
]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
let days = result.as_f64().unwrap();
assert!(days > 1000.0 && days < 1300.0);
}
#[test]
fn test_date_array_operations() {
let mut engine = RLogic::new();
let data = json!({
"dates": [
"2023-01-15T00:00:00Z",
"2023-02-20T00:00:00Z",
"2023-03-10T00:00:00Z"
]
});
let logic_id = engine
.compile(&json!({"map": [
{"var": "dates"},
{"year": {"var": ""}}
]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([2023, 2023, 2023]));
let logic_id = engine.compile(&json!({"max": [1, 2, 3]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(3));
}
#[test]
fn test_date_validation() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"date": [2020, 2, 29]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2020-02-29T00:00:00.000Z"));
let logic_id = engine.compile(&json!({"date": [2019, 2, 29]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2019-03-01T00:00:00.000Z"));
let logic_id = engine.compile(&json!({"date": [2023, 4, 30]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2023-04-30T00:00:00.000Z"));
}
#[test]
fn test_date_negative_days() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"date": [2025, 10, -16]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2025-09-14T00:00:00.000Z"));
let logic_id = engine.compile(&json!({"date": [2025, 10, 0]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2025-09-30T00:00:00.000Z"));
let logic_id = engine.compile(&json!({"date": [2025, -1, 15]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2024-11-15T00:00:00.000Z"));
let logic_id = engine.compile(&json!({"date": [2025, 1, -30]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("2024-12-01T00:00:00.000Z"));
}
#[test]
fn test_date_timezone_handling() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"date": [2023, 1, 1]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert!(result.as_str().unwrap().ends_with("T00:00:00.000Z"));
let logic_id = engine
.compile(&json!({"year": "2023-06-15T14:30:45Z"}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(2023));
}
#[test]
fn test_date_complex_calculations() {
let mut engine = RLogic::new();
let data = json!({
"start_date": "2023-01-01T00:00:00Z",
"periods": 12,
"rate": 0.05
});
let logic_id = engine.compile(&json!({"date": [2024, 1, 1]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert!(result.is_string());
assert!(result.as_str().unwrap().contains("2024"));
let logic_id = engine
.compile(&json!({
"*": [
{"pow": [
{"+": [1, {"var": "rate"}]},
{"/": [{"var": "periods"}, 12]} ]},
1000 ]
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
let final_amount = result.as_f64().unwrap();
assert!((final_amount - 1050.0).abs() < 1.0);
}
}