use runmat_builtins::{StringArray, Tensor, Value};
#[path = "support/mod.rs"]
mod test_helpers;
use test_helpers::execute_source;
#[test]
fn datetime_construction_and_component_access_work_in_scripts() {
let vars =
execute_source("d = datetime(2024, 3, 14); y = year(d); m = month(d); daynum = day(d);")
.unwrap();
assert!(vars
.iter()
.any(|value| matches!(value, Value::Object(obj) if obj.class_name == "datetime")));
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 2024.0).abs() < f64::EPSILON)));
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 3.0).abs() < f64::EPSILON)));
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 14.0).abs() < f64::EPSILON)));
}
#[test]
fn datetime_string_and_indexing_work_for_arrays() {
let vars = execute_source(
"d = datetime([2024 2025], [1 6], [15 20]); d2 = d(2); y = year(d2); s = string(d);",
)
.unwrap();
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 2025.0).abs() < f64::EPSILON)));
assert!(vars.iter().any(|value| match value {
Value::StringArray(StringArray { data, .. }) => {
data.iter().any(|text| text == "15-Jan-2024")
&& data.iter().any(|text| text == "20-Jun-2025")
}
_ => false,
}));
}
#[test]
fn datetime_comparisons_and_format_assignment_work() {
let vars = execute_source(
"a = datetime(2024, 1, 1); \
b = datetime(2024, 1, 2); \
ok = a < b; \
a.Format = 'yyyy-MM-dd'; \
c = char(a);",
)
.unwrap();
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 1.0).abs() < f64::EPSILON)));
assert!(vars.iter().any(|value| match value {
Value::CharArray(array) => {
let rendered: String = array.data.iter().collect();
rendered.trim_end() == "2024-01-01"
}
_ => false,
}));
}
#[test]
fn datetime_addition_and_subtraction_return_day_deltas() {
let vars = execute_source(
"t0 = datetime(2024, 4, 9); \
t1 = t0 + 7; \
delta = t1 - t0;",
)
.unwrap();
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 7.0).abs() < f64::EPSILON)));
}
#[test]
fn datetime_subtraction_between_scalars_uses_object_overload_path() {
let vars = execute_source(
"t0 = datetime(2024, 4, 9); \
t1 = datetime(2024, 4, 16); \
delta = t1 - t0;",
)
.unwrap();
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 7.0).abs() < f64::EPSILON)));
}
#[test]
fn datetime_legacy_conversion_helpers_execute_in_scripts() {
let vars = execute_source(
"n = datenum(2024, 3, 14); \
v = datevec(n); \
w = weekday(n); \
e = eomday(2024, 2); \
s = datestr(n, 'yyyy-MM-dd'); \
ok = isbetween(n, n - 1, n + 1);",
)
.unwrap();
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 5.0).abs() < f64::EPSILON)));
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 29.0).abs() < f64::EPSILON)));
assert!(vars.iter().any(|value| match value {
Value::CharArray(array) => {
let rendered: String = array.data.iter().collect();
rendered.trim_end() == "2024-03-14"
}
_ => false,
}));
}
#[test]
fn calendar_duration_helpers_execute_in_scripts() {
let vars = execute_source(
"t = datetime(2024, 1, 31); \
c = calmonths(1); \
shifted = t + c; \
shifted.Format = 'yyyy-MM-dd'; \
txt = char(shifted); \
m = calmonths(c); \
p = iscalendarduration(c);",
)
.unwrap();
assert!(vars.iter().any(|value| match value {
Value::CharArray(array) => {
let rendered: String = array.data.iter().collect();
rendered.trim_end() == "2024-02-29"
}
_ => false,
}));
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 1.0).abs() < f64::EPSILON)));
assert!(vars.iter().any(|value| matches!(value, Value::Bool(true))));
}
#[test]
fn business_day_helpers_execute_in_scripts() {
let vars = execute_source(
"f = fbusdate(2024, 6); \
l = lbusdate(2024, 6); \
span = daysdif(f, l); \
count = days252bus(f, f + 3); \
mask = isbusday([f f + 1]);",
)
.unwrap();
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 739_406.0).abs() < f64::EPSILON)));
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 25.0).abs() < f64::EPSILON)));
assert!(vars
.iter()
.any(|value| matches!(value, Value::Num(n) if (*n - 4.0).abs() < f64::EPSILON)));
assert!(vars.iter().any(
|value| matches!(value, Value::Tensor(Tensor { data, .. }) if data == &vec![1.0, 1.0])
));
}