use std::sync::Arc;
use arrow_array::{ArrayRef, Int64Array};
use datafusion::scalar::ScalarValue;
use uni_plugin::{PluginRegistry, QName};
use uni_plugin_custom::DeclaredPlugin;
#[test]
fn install_aggregate_round_trip() {
let registry = Arc::new(PluginRegistry::new());
let record = DeclaredPlugin {
qname: "mycorp.sumSquares".to_owned(),
kind: "aggregate".to_owned(),
body: "$state + ($x * $x)".to_owned(),
signature_json: serde_json::json!({
"init": "0",
"update": "$state + ($x * $x)",
"finalize": "$state",
"return_type": "int",
"arg_names": ["x"],
})
.to_string(),
dependencies: vec![],
declared_by: "alice".to_owned(),
active: true,
};
uni_plugin_custom::install_aggregate_into_registry(®istry, &record).expect("install ok");
let qn = QName::new("mycorp", "sumsquares");
let entry = registry.aggregate(&qn).expect("registered");
let mut acc = entry.aggregate.create_accumulator();
let col: ArrayRef = Arc::new(Int64Array::from(vec![1_i64, 2, 3, 4]));
acc.update_batch(&[col]).expect("update");
let out = acc.evaluate().expect("evaluate");
assert_eq!(out, ScalarValue::Int64(Some(30)));
}
#[test]
fn install_aggregate_propagates_signature_errors() {
let registry = Arc::new(PluginRegistry::new());
let record = DeclaredPlugin {
qname: "broken.agg".to_owned(),
kind: "aggregate".to_owned(),
body: String::new(),
signature_json: serde_json::json!({
"init": "0",
"finalize": "$state",
"return_type": "int",
"arg_names": ["x"],
})
.to_string(),
dependencies: vec![],
declared_by: "alice".to_owned(),
active: true,
};
let err = uni_plugin_custom::install_aggregate_into_registry(®istry, &record)
.expect_err("missing `update` field should fail");
let msg = err.to_string();
assert!(
msg.to_lowercase().contains("update"),
"expected `update` in error: {msg}"
);
}