use std::collections::HashMap;
use skillet::{Value, evaluate_with_custom};
fn test_http_server_jsonpath_eval(expression: &str, arguments: HashMap<String, serde_json::Value>) -> Result<Value, String> {
let mut vars = HashMap::new();
let json_str = serde_json::to_string(&arguments).unwrap_or_default();
vars.insert("arguments".to_string(), Value::Json(json_str));
for (key, value) in arguments {
match skillet::json_to_value(value) {
Ok(v) => {
let sanitized_key = key.chars()
.map(|c| if c.is_alphanumeric() || c == '_' { c } else { '_' })
.collect::<String>();
vars.insert(sanitized_key, v);
}
Err(e) => return Err(format!("Error converting variable '{}': {}", key, e)),
}
}
evaluate_with_custom(expression, &vars)
.map_err(|e| e.to_string())
}
fn approx_eq(a: f64, b: f64) -> bool {
(a - b).abs() < 1e-9
}
#[test]
fn test_http_server_jsonpath_sum() {
let mut arguments = HashMap::new();
arguments.insert("accounts".to_string(), serde_json::json!([
{"id": 1, "amount": 300.1},
{"id": 4, "amount": 890.1}
]));
let result = test_http_server_jsonpath_eval("SUM(JQ(:arguments, \"$.accounts[*].amount\"))", arguments).unwrap();
if let Value::Number(sum) = result {
assert!(approx_eq(sum, 1190.2));
} else {
panic!("Expected number result, got: {:?}", result);
}
}
#[test]
fn test_http_server_jsonpath_avg() {
let mut arguments = HashMap::new();
arguments.insert("scores".to_string(), serde_json::json!([
{"value": 85},
{"value": 92},
{"value": 78},
{"value": 95}
]));
let result = test_http_server_jsonpath_eval("AVG(JQ(:arguments, \"$.scores[*].value\"))", arguments).unwrap();
if let Value::Number(avg) = result {
assert!(approx_eq(avg, 87.5));
} else {
panic!("Expected number result, got: {:?}", result);
}
}
#[test]
fn test_http_server_jsonpath_max() {
let mut arguments = HashMap::new();
arguments.insert("temperatures".to_string(), serde_json::json!([
{"reading": 22.5},
{"reading": 31.2},
{"reading": 18.7},
{"reading": 29.8}
]));
let result = test_http_server_jsonpath_eval("MAX(JQ(:arguments, \"$.temperatures[*].reading\"))", arguments).unwrap();
if let Value::Number(max_val) = result {
assert!(approx_eq(max_val, 31.2));
} else {
panic!("Expected number result, got: {:?}", result);
}
}
#[test]
fn test_http_server_jsonpath_min() {
let mut arguments = HashMap::new();
arguments.insert("prices".to_string(), serde_json::json!([
{"cost": 15.99},
{"cost": 8.50},
{"cost": 23.75},
{"cost": 12.30}
]));
let result = test_http_server_jsonpath_eval("MIN(JQ(:arguments, \"$.prices[*].cost\"))", arguments).unwrap();
if let Value::Number(min_val) = result {
assert!(approx_eq(min_val, 8.5));
} else {
panic!("Expected number result, got: {:?}", result);
}
}
#[test]
fn test_http_server_jsonpath_nested() {
let mut arguments = HashMap::new();
arguments.insert("departments".to_string(), serde_json::json!([
{
"name": "Sales",
"employees": [
{"salary": 50000},
{"salary": 55000}
]
},
{
"name": "Engineering",
"employees": [
{"salary": 75000},
{"salary": 80000},
{"salary": 70000}
]
}
]));
let result = test_http_server_jsonpath_eval("SUM(JQ(:arguments, \"$.departments[*].employees[*].salary\"))", arguments).unwrap();
if let Value::Number(total_salary) = result {
assert!(approx_eq(total_salary, 330000.0));
} else {
panic!("Expected number result, got: {:?}", result);
}
}
#[test]
fn test_http_server_jsonpath_with_filter() {
let mut arguments = HashMap::new();
arguments.insert("products".to_string(), serde_json::json!([
{"name": "A", "price": 10, "category": "electronics"},
{"name": "B", "price": 20, "category": "books"},
{"name": "C", "price": 30, "category": "electronics"},
{"name": "D", "price": 15, "category": "books"}
]));
let result = test_http_server_jsonpath_eval("SUM(JQ(:arguments, \"$.products[?(@.category == 'electronics')].price\"))", arguments).unwrap();
if let Value::Number(electronics_total) = result {
assert!(approx_eq(electronics_total, 40.0));
} else {
panic!("Expected number result, got: {:?}", result);
}
}
#[test]
fn test_http_server_jsonpath_complex_expression() {
let mut arguments = HashMap::new();
arguments.insert("sales".to_string(), serde_json::json!([
{"amount": 100},
{"amount": 200}
]));
arguments.insert("bonus".to_string(), serde_json::json!(50));
let result = test_http_server_jsonpath_eval("SUM(JQ(:arguments, \"$.sales[*].amount\")) + :bonus", arguments).unwrap();
if let Value::Number(total) = result {
assert!(approx_eq(total, 350.0));
} else {
panic!("Expected number result, got: {:?}", result);
}
}
#[test]
fn test_http_server_jsonpath_error_handling() {
let mut arguments = HashMap::new();
arguments.insert("data".to_string(), serde_json::json!({"valid": "data"}));
let result = test_http_server_jsonpath_eval("SUM(JQ(:arguments, \"$.invalid[*].path\"))", arguments).unwrap();
if let Value::Number(sum) = result {
assert!(approx_eq(sum, 0.0));
} else {
panic!("Expected number result, got: {:?}", result);
}
}