#[cfg(test)]
mod test {
use radiate_core::MetricSet;
use radiate_expr::{AnyValue, ExprQuery, expr};
use std::time::Duration;
fn f32_of(value: AnyValue<'_>) -> f32 {
value.extract::<f32>().unwrap()
}
fn bool_of(value: AnyValue<'_>) -> bool {
if let AnyValue::Bool(b) = value {
b
} else {
false
}
}
fn u64_of(value: AnyValue<'_>) -> u64 {
value.extract::<u64>().unwrap()
}
#[test]
fn test_rolling_returns_slice_with_expected_window_contents() {
}
#[test]
fn test_rolling_mean() {
let mut expr = expr::select("accuracy").rolling(3).mean();
let mut metrics = MetricSet::default();
metrics.upsert(("accuracy", 1.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 1.0).abs() < 1e-6);
metrics.upsert(("accuracy", 2.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 1.5).abs() < 1e-6);
metrics.upsert(("accuracy", 3.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 2.0).abs() < 1e-6);
metrics.upsert(("accuracy", 4.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 3.0).abs() < 1e-6);
}
#[test]
fn test_rolling_sum() {
let mut expr = expr::select("accuracy").rolling(3).sum();
let mut metrics = MetricSet::default();
metrics.upsert(("accuracy", 1.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 1.0).abs() < 1e-6);
metrics.upsert(("accuracy", 2.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 3.0).abs() < 1e-6);
metrics.upsert(("accuracy", 3.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 6.0).abs() < 1e-6);
metrics.upsert(("accuracy", 4.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 9.0).abs() < 1e-6);
}
#[test]
fn test_rolling_min_and_max() {
let mut min_expr = expr::select("accuracy").rolling(4).min();
let mut max_expr = expr::select("accuracy").rolling(4).max();
let mut metrics = MetricSet::default();
for value in [3.0, 1.0, 4.0, 2.0] {
metrics.upsert(("accuracy", value));
min_expr.dispatch(&metrics).unwrap();
max_expr.dispatch(&metrics).unwrap();
}
assert!((f32_of(min_expr.dispatch(&metrics).unwrap()) - 1.0).abs() < 1e-6);
assert!((f32_of(max_expr.dispatch(&metrics).unwrap()) - 4.0).abs() < 1e-6);
}
#[test]
fn test_rolling_count() {
let mut expr = expr::select("accuracy").rolling(3).count();
let mut metrics = MetricSet::default();
metrics.upsert(("accuracy", 10.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 1);
metrics.upsert(("accuracy", 11.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 2);
metrics.upsert(("accuracy", 12.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 3);
metrics.upsert(("accuracy", 13.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 3);
}
#[test]
fn test_rolling_n_unique() {
let mut expr = expr::select("accuracy").rolling(5).unique().count();
let mut metrics = MetricSet::default();
metrics.upsert(("accuracy", 1.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 1);
metrics.upsert(("accuracy", 2.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 2);
metrics.upsert(("accuracy", 2.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 2);
metrics.upsert(("accuracy", 3.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 3);
metrics.upsert(("accuracy", 1.0));
assert_eq!(u64_of(expr.dispatch(&metrics).unwrap()), 3);
}
#[test]
fn test_lt_comparison_true_and_false() {
let mut expr = expr::select("accuracy").lt(expr::select("loss"));
let mut metrics = MetricSet::default();
metrics.upsert(("accuracy", 0.8));
metrics.upsert(("loss", 1.2));
assert_eq!(bool_of(expr.dispatch(&metrics).unwrap()), true);
metrics.upsert(("accuracy", 2.0));
metrics.upsert(("loss", 1.2));
assert_eq!(bool_of(expr.dispatch(&metrics).unwrap()), false);
}
#[test]
fn test_gte_comparison() {
let mut expr = expr::select("accuracy").gte(expr::select("target"));
let mut metrics = MetricSet::default();
metrics.upsert(("accuracy", 0.95));
metrics.upsert(("target", 0.90));
assert!(bool_of(expr.dispatch(&metrics).unwrap()));
metrics.upsert(("accuracy", 0.85));
metrics.upsert(("target", 0.90));
assert!(!bool_of(expr.dispatch(&metrics).unwrap()));
}
#[test]
fn test_eq_comparison_uses_epsilon() {
let mut expr = expr::select("a").eq(expr::select("b"));
let mut metrics = MetricSet::default();
metrics.upsert(("a", 1.0f32));
metrics.upsert(("b", 1.0f32));
assert!(bool_of(expr.dispatch(&metrics).unwrap()));
}
#[test]
fn test_ne_comparison() {
let mut expr = expr::select("a").ne(expr::select("b"));
let mut metrics = MetricSet::default();
metrics.upsert(("a", 1.0f32));
metrics.upsert(("b", 2.0f32));
assert!(bool_of(expr.dispatch(&metrics).unwrap()));
metrics.upsert(("a", 5.0f32));
metrics.upsert(("b", 5.0f32));
assert!(!bool_of(expr.dispatch(&metrics).unwrap()));
}
#[test]
fn test_metric_projection_uses_metricset_property_mean() {
let mut metrics = MetricSet::default();
metrics.upsert(("accuracy", 1.0));
metrics.upsert(("accuracy", 2.0));
metrics.upsert(("accuracy", 3.0));
}
#[test]
fn test_between_inclusive() {
let mut expr = expr::select("x").between(1.0, 3.0);
let mut metrics = MetricSet::default();
metrics.upsert(("x", 1.0));
assert!(bool_of(expr.dispatch(&metrics).unwrap()));
metrics.upsert(("x", 2.0));
assert!(bool_of(expr.dispatch(&metrics).unwrap()));
metrics.upsert(("x", 3.0));
assert!(bool_of(expr.dispatch(&metrics).unwrap()));
metrics.upsert(("x", 0.99));
assert!(!bool_of(expr.dispatch(&metrics).unwrap()));
metrics.upsert(("x", 3.01));
assert!(!bool_of(expr.dispatch(&metrics).unwrap()));
}
#[test]
fn test_add_expr() {
let mut expr = expr::select("a").add(expr::select("b"));
let mut metrics = MetricSet::default();
metrics.upsert(("a", 2.0));
metrics.upsert(("b", 3.5));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 5.5).abs() < 1e-6);
}
#[test]
fn test_sub_expr() {
let mut expr = expr::select("a").sub(expr::select("b"));
let mut metrics = MetricSet::default();
metrics.upsert(("a", 5.0));
metrics.upsert(("b", 1.5));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 3.5).abs() < 1e-6);
}
#[test]
fn test_mul_expr() {
let mut expr = expr::select("a").mul(2.5);
let mut metrics = MetricSet::default();
metrics.upsert(("a", 4.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 10.0).abs() < 1e-6);
}
#[test]
fn test_div_expr() {
let mut expr = expr::select("a").div(expr::select("b"));
let mut metrics = MetricSet::default();
metrics.upsert(("a", 9.0));
metrics.upsert(("b", 3.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 3.0).abs() < 1e-6);
}
#[test]
fn test_div_by_zero_returns_null() {
let mut expr = expr::select("a").div(expr::select("b"));
let mut metrics = MetricSet::default();
metrics.upsert(("a", 9.0));
metrics.upsert(("b", 0.0));
assert_eq!(expr.dispatch(&metrics).unwrap(), AnyValue::Null);
}
#[test]
fn test_neg_expr() {
let mut expr = expr::select("a").neg();
let mut metrics = MetricSet::default();
metrics.upsert(("a", 4.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) + 4.0).abs() < 1e-6);
}
#[test]
fn test_abs_expr() {
let mut expr = expr::select("a").sub(10.0).abs();
let mut metrics = MetricSet::default();
metrics.upsert(("a", 4.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 6.0).abs() < 1e-6);
metrics.upsert(("a", 14.0));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 4.0).abs() < 1e-6);
}
#[test]
fn test_clamp_expr() {
let mut expr = expr::select("a").clamp(0.1, 0.5);
let mut metrics = MetricSet::default();
metrics.upsert(("a", 0.05));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 0.1).abs() < 1e-6);
metrics.upsert(("a", 0.25));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 0.25).abs() < 1e-6);
metrics.upsert(("a", 0.9));
assert!((f32_of(expr.dispatch(&metrics).unwrap()) - 0.5).abs() < 1e-6);
}
#[test]
fn test_duration_expr() {
let mut expr = expr::select("time").time().rolling(10).min();
let mut metrics = MetricSet::default();
println!("{:#?}", expr);
metrics.upsert(("time", Duration::from_secs(5)));
expr.dispatch(&metrics).unwrap();
metrics.upsert(("time", Duration::from_secs(3)));
expr.dispatch(&metrics).unwrap();
metrics.upsert(("time", Duration::from_secs(8)));
let result = expr.dispatch(&metrics);
assert_eq!(result.unwrap(), AnyValue::Duration(Duration::from_secs(3)));
}
#[test]
fn test_every_expr() {
let mut expr = expr::every(3)
.then(expr::select("accuracy").mean())
.otherwise(0.0);
let mut metrics = MetricSet::default();
let inputs = [1.0, 2.0, 3.0, 4.0, 5.0];
for (i, &value) in inputs.iter().enumerate() {
metrics.upsert(("accuracy", value));
let result = expr.dispatch(&metrics);
println!("Input: {value}, Output: {result:?}");
if i % 3 == 2 {
let expected_mean = inputs[i - 2..=i].iter().sum::<f32>() / 3.0;
assert!((f32_of(result.unwrap()) - expected_mean).abs() < 1e-6);
} else {
assert!((f32_of(result.unwrap()) - 0.0).abs() < 1e-6);
}
}
}
}