use datalogic_rs::DataLogic;
use serde_json::json;
#[test]
fn test_trace_simple_comparison() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{">=": [{"var": "age"}, 18]}"#, r#"{"age": 25}"#)
.unwrap();
assert_eq!(result.result, json!(true));
assert!(result.expression_tree.expression.contains(">="));
assert!(!result.steps.is_empty());
for step in &result.steps {
assert!(step.result.is_some() || step.error.is_some());
}
}
#[test]
fn test_trace_proposal_example() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(
r#"{"and": [{">=": [{"var": "age"}, 18]}, true]}"#,
r#"{"age": 25}"#,
)
.unwrap();
assert_eq!(result.result, json!(true));
assert!(result.expression_tree.expression.contains("and"));
assert!(!result.expression_tree.children.is_empty());
}
#[test]
fn test_trace_short_circuit_and() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"and": [false, {"var": "expensive"}]}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!(false));
}
#[test]
fn test_trace_short_circuit_or() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"or": [true, {"var": "expensive"}]}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!(true));
}
#[test]
fn test_trace_map_operator() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"map": [[1, 2, 3], {"*": [{"var": ""}, 2]}]}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!([2, 4, 6]));
let iteration_steps: Vec<_> = result
.steps
.iter()
.filter(|s| s.iteration_index.is_some())
.collect();
assert!(!iteration_steps.is_empty());
for step in &iteration_steps {
assert!(step.iteration_total == Some(3));
}
}
#[test]
fn test_trace_filter_operator() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(
r#"{"filter": [[1, 2, 3, 4, 5], {">": [{"var": ""}, 2]}]}"#,
r#"{}"#,
)
.unwrap();
assert_eq!(result.result, json!([3, 4, 5]));
}
#[test]
fn test_trace_reduce_operator() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(
r#"{"reduce": [[1, 2, 3, 4], {"+": [{"var": "accumulator"}, {"var": "current"}]}, 0]}"#,
r#"{}"#,
)
.unwrap();
assert_eq!(result.result, json!(10));
}
#[test]
fn test_trace_if_operator() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(
r#"{"if": [{"var": "active"}, "yes", "no"]}"#,
r#"{"active": true}"#,
)
.unwrap();
assert_eq!(result.result, json!("yes"));
}
#[test]
fn test_trace_nested_operators() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(
r#"{"and": [{">": [{"var": "x"}, 0]}, {"<": [{"var": "x"}, 100]}]}"#,
r#"{"x": 50}"#,
)
.unwrap();
assert_eq!(result.result, json!(true));
assert!(!result.expression_tree.children.is_empty());
}
#[test]
fn test_expression_tree_structure() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{">=": [{"var": "age"}, 18]}"#, r#"{"age": 25}"#)
.unwrap();
assert_eq!(result.expression_tree.id, 0);
assert!(result.expression_tree.expression.contains(">="));
assert_eq!(result.expression_tree.children.len(), 1);
assert!(result.expression_tree.children[0].id > 0);
assert!(
result.expression_tree.children[0]
.expression
.contains("var")
);
}
#[test]
fn test_literals_no_separate_steps() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"==": [{"var": "x"}, 1]}"#, r#"{"x": 1}"#)
.unwrap();
assert_eq!(result.result, json!(true));
assert!(!result.steps.is_empty());
for step in &result.steps {
assert!(step.result.is_some());
}
}
#[test]
fn test_step_context() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"var": "name"}"#, r#"{"name": "Alice"}"#)
.unwrap();
assert_eq!(result.result, json!("Alice"));
assert!(!result.steps.is_empty());
let step = &result.steps[0];
assert!(step.context.get("name").is_some());
}
#[test]
fn test_trace_quantifier_operators() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"all": [[1, 2, 3], {">": [{"var": ""}, 0]}]}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!(true));
let result = engine
.evaluate_json_with_trace(r#"{"some": [[1, 2, 3], {">": [{"var": ""}, 2]}]}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!(true));
let result = engine
.evaluate_json_with_trace(r#"{"none": [[1, 2, 3], {">": [{"var": ""}, 5]}]}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!(true));
}
#[test]
fn test_trace_ternary_operator() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"?:": [true, "yes", "no"]}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!("yes"));
}
#[test]
fn test_trace_coalesce_operator() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"??": [null, null, "found"]}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!("found"));
}
#[test]
fn test_trace_with_error() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"var": "missing.path"}"#, r#"{}"#)
.unwrap();
assert_eq!(result.result, json!(null));
}
#[test]
fn test_trace_arithmetic() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(r#"{"+": [{"*": [{"var": "x"}, 3]}, 4]}"#, r#"{"x": 2}"#)
.unwrap();
assert_eq!(result.result, json!(10));
assert!(!result.steps.is_empty());
assert!(result.expression_tree.expression.contains("+"));
}
#[test]
fn test_trace_string_operators() {
let engine = DataLogic::new();
let result = engine
.evaluate_json_with_trace(
r#"{"cat": ["Hello, ", {"var": "name"}]}"#,
r#"{"name": "World"}"#,
)
.unwrap();
assert_eq!(result.result, json!("Hello, World"));
}