use skillet::{evaluate, Value};
fn as_number(v: Value) -> f64 {
match v { Value::Number(n) => n, _ => panic!("Expected number, got {:?}", v) }
}
fn as_datetime(v: Value) -> i64 {
match v { Value::DateTime(ts) => ts, _ => panic!("Expected datetime, got {:?}", v) }
}
fn as_bool(v: Value) -> bool {
match v { Value::Boolean(b) => b, _ => panic!("Expected boolean, got {:?}", v) }
}
fn as_string(v: Value) -> String {
match v { Value::String(s) => s, _ => panic!("Expected string, got {:?}", v) }
}
#[test]
fn test_now_function() {
let result = evaluate("=NOW()").unwrap();
assert!(matches!(result, Value::DateTime(_)));
let timestamp = as_datetime(result);
assert!(timestamp > 1577836800); assert!(timestamp < 1893456000); }
#[test]
fn test_date_function() {
let result = evaluate("=DATE()").unwrap();
assert!(matches!(result, Value::DateTime(_)));
}
#[test]
fn test_time_function() {
let result = evaluate("=TIME()").unwrap();
let seconds = as_number(result);
assert!(seconds >= 0.0);
assert!(seconds < 86400.0); }
#[test]
fn test_year_month_day_functions() {
let year = as_number(evaluate("=YEAR(NOW())").unwrap());
let month = as_number(evaluate("=MONTH(NOW())").unwrap());
let day = as_number(evaluate("=DAY(NOW())").unwrap());
assert!(year >= 2024.0 && year <= 2026.0);
assert!(month >= 1.0 && month <= 12.0);
assert!(day >= 1.0 && day <= 31.0);
}
#[test]
fn test_dateadd_function() {
let now = as_datetime(evaluate("=NOW()").unwrap());
let future = as_datetime(evaluate("=DATEADD(NOW(), 7, \"days\")").unwrap());
let diff_days = (future - now) / 86400; assert!((diff_days - 7).abs() < 1);
let future_hours = as_datetime(evaluate("=DATEADD(NOW(), 24, \"hours\")").unwrap());
let diff_hours = (future_hours - now) / 3600; assert!((diff_hours - 24).abs() < 1); }
#[test]
fn test_datediff_function() {
let diff = as_number(evaluate("=DATEDIFF(NOW(), DATEADD(NOW(), 7, \"days\"), \"days\")").unwrap());
assert_eq!(diff, 7.0);
let diff_hours = as_number(evaluate("=DATEDIFF(NOW(), DATEADD(NOW(), 24, \"hours\"), \"hours\")").unwrap());
assert_eq!(diff_hours, 24.0);
let diff_reverse = as_number(evaluate("=DATEDIFF(DATEADD(NOW(), 7, \"days\"), NOW(), \"days\")").unwrap());
assert_eq!(diff_reverse, -7.0);
}
#[test]
fn test_substring_function() {
assert_eq!(as_string(evaluate("=SUBSTRING(\"Hello World\", 0, 5)").unwrap()), "Hello");
assert_eq!(as_string(evaluate("=SUBSTRING(\"Hello World\", 6)").unwrap()), "World");
assert_eq!(as_string(evaluate("=SUBSTRING(\"Hello 🌍\", 6, 2)").unwrap()), "🌍");
assert_eq!(as_string(evaluate("=SUBSTRING(\"Hello\", 10, 5)").unwrap()), "");
assert_eq!(as_string(evaluate("=SUBSTRING(\"Hello\", 0, 0)").unwrap()), "");
}
#[test]
fn test_type_checking_functions() {
assert!(as_bool(evaluate("=ISNUMBER(42)").unwrap()));
assert!(as_bool(evaluate("=ISNUMBER(3.14)").unwrap()));
assert!(!as_bool(evaluate("=ISNUMBER(\"hello\")").unwrap()));
assert!(!as_bool(evaluate("=ISNUMBER(TRUE)").unwrap()));
assert!(!as_bool(evaluate("=ISNUMBER(NULL)").unwrap()));
assert!(as_bool(evaluate("=ISTEXT(\"hello\")").unwrap()));
assert!(as_bool(evaluate("=ISTEXT(\"\")").unwrap()));
assert!(!as_bool(evaluate("=ISTEXT(42)").unwrap()));
assert!(!as_bool(evaluate("=ISTEXT(TRUE)").unwrap()));
assert!(!as_bool(evaluate("=ISTEXT(NULL)").unwrap()));
}
#[test]
fn test_complex_datetime_expressions() {
let years_diff = as_number(evaluate("=DATEDIFF(DATEADD(NOW(), -365, \"days\"), NOW(), \"years\")").unwrap());
assert!(years_diff >= 0.0 && years_diff <= 2.0);
let next_year = as_number(evaluate("=YEAR(DATEADD(NOW(), 1, \"years\"))").unwrap());
let current_year = as_number(evaluate("=YEAR(NOW())").unwrap());
assert_eq!(next_year, current_year + 1.0);
}
#[test]
fn test_string_and_datetime_together() {
let year_str = as_string(evaluate("=CONCAT(\"Year: \", YEAR(NOW()))").unwrap());
assert!(year_str.starts_with("Year: "));
assert!(year_str.contains("202")); }