use json_eval_rs::*;
use serde_json::json;
#[cfg(test)]
mod operator_tests {
use super::*;
#[test]
fn test_arithmetic_operators() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"+": [2, 3, 4]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(9));
let logic_id = engine.compile(&json!({"abs": [-5]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
let logic_id = engine.compile(&json!({"abs": -5})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
let logic_id = engine.compile(&json!({"-": [10, 3, 2]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
let logic_id = engine.compile(&json!({"*": [2, 3, 4]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(24));
let logic_id = engine.compile(&json!({"/": [24, 3, 2]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(4));
}
#[test]
fn test_arithmetic_with_variables() {
let mut engine = RLogic::new();
let data = json!({"a": 10, "b": 5, "c": 2});
let logic_id = engine
.compile(&json!({"+": [{"var": "a"}, {"var": "b"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(15));
let logic_id = engine
.compile(&json!({"*": [{"var": "a"}, {"var": "b"}, {"var": "c"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(100));
}
#[test]
fn test_arithmetic_edge_cases() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"+": [42]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(42));
let logic_id = engine.compile(&json!({"+": []})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(0));
let logic_id = engine.compile(&json!({"/": [10, 0]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(null));
}
#[test]
fn test_comparison_operators() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"==": [5, 5]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({"==": [5, 6]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
let logic_id = engine.compile(&json!({"!=": [5, 6]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({"<": [3, 5]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({">": [7, 5]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({"<=": [5, 5]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({">=": [5, 5]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
}
#[test]
fn test_loose_equality() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"==": [5, "5"]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({"==": [true, 1]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({"==": [null, null]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({"==": [null, 0]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
}
#[test]
fn test_logical_operators() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"and": [true, true, true]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine
.compile(&json!({"and": [true, false, true]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
let logic_id = engine
.compile(&json!({"or": [false, false, true]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine
.compile(&json!({"or": [false, false, false]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
let logic_id = engine.compile(&json!({"!": true})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
let logic_id = engine.compile(&json!({"!": false})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({"length": ["hello"]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
let logic_id = engine.compile(&json!({"len": ["hello"]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
let logic_id = engine.compile(&json!({"ISEMPTY": null})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine.compile(&json!({"ISEMPTY": [null]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
let logic_id = engine
.compile(&json!({"ISEMPTY": [{"var": "missing_var"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
}
#[test]
fn test_logical_short_circuit() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine
.compile(&json!({"and": [false, {"+": [1, "error"]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(false));
let logic_id = engine
.compile(&json!({"or": [true, {"+": [1, "error"]}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true));
}
#[test]
fn test_if_condition() {
let mut engine = RLogic::new();
let data = json!({"value": 10});
let logic_id = engine
.compile(&json!({"if": [{"var": "value"}, "yes", "no"]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("yes"));
let data = json!({"value": 0});
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("no"));
let data = json!({"value": "hello"});
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!("yes"));
}
#[test]
fn test_truthy_falsy_values() {
let mut engine = RLogic::new();
let data = json!({});
let test_cases = vec![
(json!(true), true),
(json!(false), false),
(json!(1), true),
(json!(0), false),
(json!(-1), true),
(json!("hello"), true),
(json!(""), false),
(json!([]), false),
(json!([1, 2, 3]), true),
(json!({}), false),
(json!(null), false),
];
for (value, expected_truthy) in test_cases {
let logic_id = engine
.compile(&json!({"if": [value, true, false]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(
result,
json!(expected_truthy),
"Value {:?} should be truthy: {}",
value,
expected_truthy
);
}
}
#[test]
fn test_nested_expressions() {
let mut engine = RLogic::new();
let data = json!({"a": 2, "b": 3, "c": 4});
let logic_id = engine
.compile(&json!({"+": [{"*": [{"var": "a"}, {"var": "b"}]}, {"var": "c"}]}))
.unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(10));
let logic_id = engine.compile(&json!({"and": [{"<": [{"var": "a"}, {"var": "c"}]}, {">": [{"var": "b"}, {"var": "a"}]}]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(true)); }
#[test]
fn test_operator_precedence() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"+": [2, {"*": [3, 4]}]})).unwrap();
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(14)); }
}