use super::super::{
daverage_fn, dcount_fn, dcounta_fn, dget_fn, dmax_fn, dmin_fn, dproduct_fn, dstdev_fn,
dstdevp_fn, dsum_fn, dvar_fn, dvarp_fn,
};
use crate::types::{ErrorKind, Value};
fn test_db() -> Value {
let row = |name: &str, age: f64, sales: f64| {
Value::Array(vec![
Value::Text(name.to_string()),
Value::Number(age),
Value::Number(sales),
])
};
Value::Array(vec![
Value::Array(vec![
Value::Text("Name".to_string()),
Value::Text("Age".to_string()),
Value::Text("Sales".to_string()),
]),
row("Alice", 30.0, 100.0),
row("Bob", 25.0, 200.0),
row("Alice", 35.0, 150.0),
])
}
fn criteria_alice() -> Value {
Value::Array(vec![
Value::Array(vec![Value::Text("Name".to_string())]),
Value::Array(vec![Value::Text("Alice".to_string())]),
])
}
fn criteria_age_gt_25() -> Value {
Value::Array(vec![
Value::Array(vec![Value::Text("Age".to_string())]),
Value::Array(vec![Value::Text(">25".to_string())]),
])
}
fn criteria_bob() -> Value {
Value::Array(vec![
Value::Array(vec![Value::Text("Name".to_string())]),
Value::Array(vec![Value::Text("Bob".to_string())]),
])
}
fn criteria_all() -> Value {
Value::Array(vec![
Value::Array(vec![Value::Text("Age".to_string())]),
Value::Array(vec![Value::Text(">=1".to_string())]),
])
}
#[test]
fn dsum_alice_sales() {
let result = dsum_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
assert_eq!(result, Value::Number(250.0));
}
#[test]
fn dsum_field_by_number_index() {
let result = dsum_fn(&[test_db(), Value::Number(3.0), criteria_alice()]);
assert_eq!(result, Value::Number(250.0));
}
#[test]
fn dsum_all_rows() {
let result = dsum_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_all()]);
assert_eq!(result, Value::Number(450.0));
}
#[test]
fn dcount_age_gt_25() {
let result = dcount_fn(&[test_db(), Value::Text("Age".to_string()), criteria_age_gt_25()]);
assert_eq!(result, Value::Number(2.0));
}
#[test]
fn dcount_bob() {
let result = dcount_fn(&[test_db(), Value::Text("Age".to_string()), criteria_bob()]);
assert_eq!(result, Value::Number(1.0));
}
#[test]
fn daverage_alice_sales() {
let result = daverage_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
assert_eq!(result, Value::Number(125.0));
}
#[test]
fn daverage_all_sales() {
let result = daverage_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_all()]);
assert_eq!(result, Value::Number(150.0));
}
#[test]
fn dmax_all_sales() {
let result = dmax_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_all()]);
assert_eq!(result, Value::Number(200.0));
}
#[test]
fn dmax_alice_sales() {
let result = dmax_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
assert_eq!(result, Value::Number(150.0));
}
#[test]
fn dmin_all_age() {
let result = dmin_fn(&[test_db(), Value::Text("Age".to_string()), criteria_all()]);
assert_eq!(result, Value::Number(25.0));
}
#[test]
fn dmin_bob_age() {
let result = dmin_fn(&[test_db(), Value::Text("Age".to_string()), criteria_bob()]);
assert_eq!(result, Value::Number(25.0));
}
#[test]
fn dget_unique_match_returns_value() {
let result = dget_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_bob()]);
assert_eq!(result, Value::Number(200.0));
}
#[test]
fn dget_multiple_matches_returns_num_error() {
let result = dget_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
assert_eq!(result, Value::Error(ErrorKind::Num));
}
#[test]
fn dget_no_match_returns_value_error() {
let criteria_charlie = Value::Array(vec![
Value::Array(vec![Value::Text("Name".to_string())]),
Value::Array(vec![Value::Text("Charlie".to_string())]),
]);
let result = dget_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_charlie]);
assert_eq!(result, Value::Error(ErrorKind::Value));
}
#[test]
fn dproduct_alice_sales() {
let result = dproduct_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
assert_eq!(result, Value::Number(15000.0));
}
#[test]
fn dcounta_all_names() {
let result = dcounta_fn(&[test_db(), Value::Text("Name".to_string()), criteria_all()]);
assert_eq!(result, Value::Number(3.0));
}
#[test]
fn dstdev_alice_sales() {
let result = dstdev_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
if let Value::Number(n) = result {
let expected = 1250.0_f64.sqrt();
assert!((n - expected).abs() < 1e-9, "expected {expected}, got {n}");
} else {
panic!("expected Number, got {result:?}");
}
}
#[test]
fn dstdevp_alice_sales() {
let result = dstdevp_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
assert_eq!(result, Value::Number(25.0));
}
#[test]
fn dvar_alice_sales() {
let result = dvar_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
assert_eq!(result, Value::Number(1250.0));
}
#[test]
fn dvarp_alice_sales() {
let result = dvarp_fn(&[test_db(), Value::Text("Sales".to_string()), criteria_alice()]);
assert_eq!(result, Value::Number(625.0));
}