use json_eval_rs::*;
use serde_json::json;
#[cfg(test)]
mod array_tests {
use super::*;
#[test]
fn test_array_map() {
let mut engine = RLogic::new();
let data = json!({"numbers": [1, 2, 3, 4, 5]});
let logic_id = engine
.compile(&json!({"map": [{"var": "numbers"}, {"*": [{"var": ""}, 2]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([2, 4, 6, 8, 10]));
let logic_id = engine
.compile(&json!({"map": [{"var": "numbers"}, {"cat": [{"var": ""}, "x"]} ]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(["1x", "2x", "3x", "4x", "5x"]));
}
#[test]
fn test_array_filter() {
let mut engine = RLogic::new();
let data = json!({"numbers": [1, 2, 3, 4, 5, 6]});
let logic_id = engine
.compile(&json!({"filter": [{"var": "numbers"}, {"==": [{"%": [{"var": ""}, 2]}, 0]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([2, 4, 6]));
let logic_id = engine
.compile(&json!({"filter": [{"var": "numbers"}, {">": [{"var": ""}, 3]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([4, 5, 6]));
}
#[test]
fn test_array_reduce() {
let mut engine = RLogic::new();
let data = json!({"numbers": [1, 2, 3, 4, 5]});
let logic_id = engine.compile(&json!({"reduce": [{"var": "numbers"}, {"+": [{"var": "accumulator"}, {"var": "current"}]}, 0]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(15));
let logic_id = engine.compile(&json!({"reduce": [{"var": "numbers"}, {"if": [{">": [{"var": "current"}, {"var": "accumulator"}]}, {"var": "current"}, {"var": "accumulator"}]}, 0]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
}
#[test]
fn test_array_quantifiers() {
let mut engine = RLogic::new();
let data = json!({"numbers": [1, 2, 3, 4, 5]});
let logic_id = engine
.compile(&json!({"all": [{"var": "numbers"}, {"==": [{"%": [{"var": ""}, 2]}, 0]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
let logic_id = engine
.compile(&json!({"some": [{"var": "numbers"}, {"==": [{"%": [{"var": ""}, 2]}, 0]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine
.compile(&json!({"none": [{"var": "numbers"}, {"<": [{"var": ""}, 0]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
}
#[test]
fn test_array_merge() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine
.compile(&json!({"merge": [[1, 2], [3, 4], [5]]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([1, 2, 3, 4, 5]));
let logic_id = engine
.compile(&json!({"merge": [["a", "b"], [1, 2], [true, null]]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(["a", "b", 1, 2, true, null]));
}
#[test]
fn test_array_in() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine
.compile(&json!({"in": [3, [1, 2, 3, 4, 5]]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine
.compile(&json!({"in": [6, [1, 2, 3, 4, 5]]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
let logic_id = engine
.compile(&json!({"in": ["world", "hello world"]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine
.compile(&json!({"in": ["foo", "hello world"]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
}
#[test]
fn test_array_operations_edge_cases() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine
.compile(&json!({"map": [[], {"*": [{"var": ""}, 2]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([]));
let logic_id = engine
.compile(&json!({"filter": [[], {">": [{"var": ""}, 0]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([]));
let logic_id = engine
.compile(
&json!({"reduce": [[], {"+": [{"var": "accumulator"}, {"var": "current"}]}, 0]}),
)
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(0));
let logic_id = engine
.compile(&json!({"all": [[], {">": [{"var": ""}, 0]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine
.compile(&json!({"some": [[], {">": [{"var": ""}, 0]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
let logic_id = engine
.compile(&json!({"none": [[], {">": [{"var": ""}, 0]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
}
#[test]
fn test_array_operations_with_objects() {
let mut engine = RLogic::new();
let data = json!({"users": [
{"name": "Alice", "age": 30, "active": true},
{"name": "Bob", "age": 25, "active": false},
{"name": "Charlie", "age": 35, "active": true}
]});
let logic_id = engine
.compile(&json!({"map": [{"var": "users"}, {"var": "name"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(["Alice", "Bob", "Charlie"]));
let logic_id = engine
.compile(&json!({"filter": [{"var": "users"}, {"var": "active"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(
result,
json!([
{"name": "Alice", "age": 30, "active": true},
{"name": "Charlie", "age": 35, "active": true}
])
);
let logic_id = engine
.compile(&json!({"reduce": [
{"map": [{"var": "users"}, {"var": "age"}]},
{"+": [{"var": "accumulator"}, {"var": "current"}]},
0
]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(90)); }
#[test]
fn test_array_operations_errors() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine
.compile(&json!({"map": ["not_array", {"var": ""}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([]));
let logic_id = engine
.compile(&json!({"filter": ["not_array", {"var": ""}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([]));
let logic_id = engine
.compile(&json!({"reduce": ["not_array", {"var": ""}, 0]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(0));
}
#[test]
fn test_array_sum() {
let mut engine = RLogic::new();
let data = json!({"values": [1, 2, 3, 4, 5]});
let logic_id = engine
.compile(&json!({"sum": [{"var": "values"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(15));
let data = json!({"items": [
{"value": 10},
{"value": 20},
{"value": 30}
]});
let logic_id = engine
.compile(&json!({"sum": [{"var": "items"}, "value"]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(60));
}
#[test]
fn test_array_for_loop() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine
.compile(&json!({"FOR": [0, 3, {"+": [{"var": "$loopIteration"}, 1]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([1, 2, 3]));
let logic_id = engine
.compile(&json!({"FOR": [1, 4, {"*": [{"var": "$loopIteration"}, 2]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([2, 4, 6]));
}
#[test]
fn test_real_world_table_processing() {
let mut engine = RLogic::new();
let data = json!({
"riders": [
{"code": "RIDER_A", "premium": 100000, "loading": 1.05},
{"code": "RIDER_B", "premium": 200000, "loading": 1.10},
{"code": "RIDER_C", "premium": 150000, "loading": 1.08}
],
"frequency": 12,
"discount_rate": 0.95
});
let logic_id = engine
.compile(&json!({
"*": [
{"sum": [
{"map": [
{"var": "riders"},
{"*": [{"var": "premium"}, {"var": "loading"}]}
]}
]},
{"var": "frequency"},
{"var": "discount_rate"}
]
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
let expected = (105000.0 + 220000.0 + 162000.0) * 12.0 * 0.95;
assert!((result.as_f64().unwrap() - expected).abs() < 0.01);
}
#[test]
fn test_nested_array_operations() {
let mut engine = RLogic::new();
let data = json!({
"products": [
{
"name": "Product A",
"variants": [{"price": 100}, {"price": 150}]
},
{
"name": "Product B",
"variants": [{"price": 200}, {"price": 250}, {"price": 300}]
}
]
});
let logic_id = engine
.compile(&json!({
"map": [
{"var": "products"},
{"map": [{"var": "variants"}, {"var": "price"}]}
]
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert!(result.is_array());
let arr = result.as_array().unwrap();
assert_eq!(arr.len(), 2);
assert_eq!(arr[0], json!([100, 150]));
assert_eq!(arr[1], json!([200, 250, 300]));
}
#[test]
fn test_array_operations_with_nulls() {
let mut engine = RLogic::new();
let data = json!({
"values": [10, null, 20, null, 30]
});
let logic_id = engine
.compile(&json!({"sum": [{"var": "values"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(60));
let logic_id = engine
.compile(&json!({
"filter": [
{"var": "values"},
{"!=": [{"var": ""}, null]}
]
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([10, 20, 30]));
let logic_id = engine
.compile(&json!({
"map": [
{"var": "values"},
{"*": [{"var": ""}, 2]}
]
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!([20, 0, 40, 0, 60]));
}
#[test]
fn test_array_conditional_operations() {
let mut engine = RLogic::new();
let data = json!({
"transactions": [
{"amount": 1000, "type": "credit"},
{"amount": 500, "type": "debit"},
{"amount": 2000, "type": "credit"},
{"amount": 300, "type": "debit"}
]
});
let logic_id = engine
.compile(&json!({
"reduce": [
{"map": [
{"var": "transactions"},
{"if": [
{"==": [{"var": "type"}, "credit"]},
{"var": "amount"},
{"-": [0, {"var": "amount"}]}
]}
]},
{"+": [{"var": "accumulator"}, {"var": "current"}]},
0
]
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(2200)); }
#[test]
fn test_array_with_large_dataset() {
let mut engine = RLogic::new();
let mut items = Vec::new();
for i in 0..1000 {
items.push(json!({
"id": i,
"value": i * 10,
"category": if i % 2 == 0 { "even" } else { "odd" }
}));
}
let data = json!({"items": items});
let logic_id = engine
.compile(&json!({
"sum": [
{"map": [
{"filter": [
{"var": "items"},
{"==": [{"var": "category"}, "even"]}
]},
{"var": "value"}
]}
]
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
let expected = 10.0 * (0..500).sum::<i32>() as f64 * 2.0;
assert_eq!(result.as_f64().unwrap(), expected);
}
#[test]
fn test_array_grouping_simulation() {
let mut engine = RLogic::new();
let data = json!({
"sales": [
{"product": "A", "amount": 100},
{"product": "B", "amount": 200},
{"product": "A", "amount": 150},
{"product": "B", "amount": 300}
]
});
let logic_id = engine
.compile(&json!({
"sum": [
{"map": [
{"filter": [
{"var": "sales"},
{"==": [{"var": "product"}, "A"]}
]},
{"var": "amount"}
]}
]
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(250));
let logic_id = engine
.compile(&json!({
"length": {"filter": [
{"var": "sales"},
{"==": [{"var": "product"}, "B"]}
]}
}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(2));
}
#[test]
fn test_array_edge_case_empty_operations() {
let mut engine = RLogic::new();
let data = json!({
"empty": [],
"single": [42],
"mixed": [1, null, "", 0, false]
});
let test_cases = vec![
(json!({"sum": [{"var": "empty"}]}), json!(0)),
(json!({"length": {"var": "empty"}}), json!(0)),
(
json!({"merge": [{"var": "empty"}, {"var": "empty"}]}),
json!([]),
),
];
for (logic, expected) in test_cases {
let logic_id = engine.compile(&logic).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, expected, "Failed for logic: {:?}", logic);
}
let logic_id = engine
.compile(&json!({"sum": [{"var": "single"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(42));
}
}