use json_eval_rs::*;
use serde_json::json;
#[cfg(test)]
mod config_tests {
use super::*;
#[test]
fn test_custom_config() {
let config = RLogicConfig::new()
.with_tracking(false)
.with_safe_nan(true)
.with_recursion_limit(200);
let mut engine = RLogic::with_config(config);
let logic_id = engine.compile(&json!({"+": [2, 3]})).unwrap();
let data = json!({});
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(5));
}
#[test]
fn test_evaluation_works() {
let mut engine = RLogic::new();
let logic_id = engine.compile(&json!({"+": [2, 3]})).unwrap();
let data = json!({});
let result1 = engine.run(&logic_id, &data).unwrap();
assert_eq!(result1, json!(5));
let result2 = engine.run(&logic_id, &data).unwrap();
assert_eq!(result2, json!(5));
}
#[test]
fn test_safe_nan_handling() {
let config_safe = RLogicConfig::new().with_safe_nan(true);
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"pow": [-1, 0.5]})).unwrap();
let result = engine
.run_with_config(&logic_id, &data, &config_safe)
.unwrap();
assert_eq!(result, json!(0));
let config_unsafe = RLogicConfig::new().with_safe_nan(false);
let result2 = engine
.run_with_config(&logic_id, &data, &config_unsafe)
.unwrap();
assert_eq!(result2, json!(null));
}
#[test]
fn test_recursion_limit() {
let config = RLogicConfig::new().with_recursion_limit(5);
let mut engine = RLogic::with_config(config);
let deep_logic = json!({
"if": [
true,
{"if": [
true,
{"if": [
true,
{"if": [
true,
{"if": [
true,
{"if": [
true,
1,
0
]},
0
]},
0
]},
0
]},
0
]},
0
]
});
let logic_id = engine.compile(&deep_logic).unwrap();
let data = json!({});
let result = engine.run(&logic_id, &data);
assert!(result.is_err());
assert!(result.unwrap_err().contains("Recursion limit"));
}
#[test]
fn test_performance_config() {
let config = RLogicConfig::performance(); let mut engine = RLogic::with_config(config);
let logic_id = engine
.compile(&json!({"+": [{"var": "a"}, {"var": "b"}]}))
.unwrap();
let data = json!({"a": 10, "b": 20});
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(30));
}
#[test]
fn test_safe_config() {
let config = RLogicConfig::safe();
let mut engine = RLogic::with_config(config);
let logic_id = engine.compile(&json!({"pow": [-1, 0.5]})).unwrap();
let data = json!({});
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(0));
}
#[test]
fn test_config_defaults() {
let config = RLogicConfig::default();
assert_eq!(config.enable_tracking, true);
assert_eq!(config.safe_nan_handling, false); assert_eq!(config.recursion_limit, 1000);
}
#[test]
fn test_config_affects_evaluation() {
let data = json!({});
let config_perf = RLogicConfig::performance();
let mut engine_perf = RLogic::with_config(config_perf);
let logic_id1 = engine_perf.compile(&json!({"+": [1, 2]})).unwrap();
engine_perf.run(&logic_id1, &data).unwrap();
engine_perf.run(&logic_id1, &data).unwrap();
let config_safe = RLogicConfig::safe();
let mut engine_safe = RLogic::with_config(config_safe);
let logic_id2 = engine_safe.compile(&json!({"+": [1, 2]})).unwrap();
engine_safe.run(&logic_id2, &data).unwrap();
engine_safe.run(&logic_id2, &data).unwrap();
assert_eq!(engine_perf.run(&logic_id1, &data).unwrap(), json!(3));
assert_eq!(engine_safe.run(&logic_id2, &data).unwrap(), json!(3));
}
#[test]
fn test_config_edge_cases() {
let config = RLogicConfig::new().with_recursion_limit(1000);
let mut engine = RLogic::with_config(config);
let logic_id = engine.compile(&json!({"+": [1, 2]})).unwrap();
let data = json!({});
let result = engine.run(&logic_id, &data).unwrap();
assert_eq!(result, json!(3));
}
#[test]
fn test_config_nan_handling_detailed() {
let data = json!({});
let nan_operations = vec![(json!({"pow": [-1, 0.5]}), "sqrt of negative")];
for (operation, description) in nan_operations {
let config_safe = RLogicConfig::new().with_safe_nan(true);
let mut engine_safe = RLogic::with_config(config_safe);
let logic_id = engine_safe.compile(&operation).unwrap();
let result_safe = engine_safe.run(&logic_id, &data).unwrap();
let config_unsafe = RLogicConfig::new().with_safe_nan(false);
let mut engine_unsafe = RLogic::with_config(config_unsafe);
let logic_id = engine_unsafe.compile(&operation).unwrap();
let result_unsafe = engine_unsafe.run(&logic_id, &data).unwrap();
assert_eq!(
result_safe,
json!(0),
"Safe result for {} should be 0",
description
);
assert_eq!(
result_unsafe,
json!(null),
"Unsafe result for {} should be null",
description
);
}
}
#[test]
fn test_config_isolation() {
let config1 = RLogicConfig::new()
.with_recursion_limit(10)
.with_safe_nan(true);
let config2 = RLogicConfig::new()
.with_recursion_limit(20)
.with_safe_nan(false);
let mut engine1 = RLogic::with_config(config1);
let mut engine2 = RLogic::with_config(config2);
let data = json!({});
let logic_id1 = engine1.compile(&json!({"+": [1, 2]})).unwrap();
let logic_id2 = engine2.compile(&json!({"+": [1, 2]})).unwrap();
let result1 = engine1.run(&logic_id1, &data).unwrap();
let result2 = engine2.run(&logic_id2, &data).unwrap();
assert_eq!(result1, json!(3));
assert_eq!(result2, json!(3));
}
#[test]
fn test_config_runtime_changes() {
let mut engine = RLogic::new();
let data = json!({});
let logic_id = engine.compile(&json!({"pow": [-1, 0.5]})).unwrap();
let result1 = engine.run(&logic_id, &data).unwrap();
assert_eq!(result1, json!(null));
let config_unsafe = RLogicConfig::new().with_safe_nan(false);
let result2 = engine
.run_with_config(&logic_id, &data, &config_unsafe)
.unwrap();
assert_eq!(result2, json!(null)); }
#[test]
fn test_config_complex_scenarios() {
let data = json!({
"nested": {
"value": -1
}
});
let mut engine = RLogic::new();
let logic_id = engine
.compile(&json!({
"+": [
{"pow": [{"var": "nested.value"}, 0.5]}, 10
]
}))
.unwrap();
let config_safe = RLogicConfig::new().with_safe_nan(true);
let result_safe = engine
.run_with_config(&logic_id, &data, &config_safe)
.unwrap();
assert_eq!(result_safe, json!(10));
let config_unsafe = RLogicConfig::new().with_safe_nan(false);
let result_unsafe = engine
.run_with_config(&logic_id, &data, &config_unsafe)
.unwrap();
assert_eq!(result_unsafe, json!(10)); }
}