use serde_json::json;
use tellaro_query_language::Tql;
#[test]
fn test_filter_basic_equality() {
let tql = Tql::new();
let data = vec![
json!({"status": "active", "count": 10}),
json!({"status": "inactive", "count": 5}),
json!({"status": "active", "count": 20}),
];
let results = tql
.query(&data, "status = 'active'")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
assert!(results.iter().all(|r| r["status"] == "active"));
}
#[test]
fn test_filter_empty_results_list() {
let tql = Tql::new();
let data: Vec<serde_json::Value> = vec![];
let results = tql
.query(&data, "status = 'active'")
.expect("Query should succeed");
assert_eq!(results.len(), 0);
}
#[test]
fn test_filter_no_requirements_returns_all() {
let tql = Tql::new();
let data = vec![json!({"name": "test1"}), json!({"name": "test2"})];
let results = tql.query(&data, "").expect("Query should succeed");
assert_eq!(results.len(), 2);
}
#[test]
fn test_filter_contains_match() {
let tql = Tql::new();
let data = vec![
json!({"message": "hello world"}),
json!({"message": "goodbye"}),
];
let results = tql
.query(&data, "message contains 'world'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["message"], "hello world");
}
#[test]
fn test_filter_not_contains() {
let tql = Tql::new();
let data = vec![
json!({"message": "hello world"}),
json!({"message": "goodbye"}),
];
let results = tql
.query(&data, "message !contains 'world'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["message"], "goodbye");
}
#[test]
fn test_filter_startswith() {
let tql = Tql::new();
let data = vec![
json!({"message": "hello world"}),
json!({"message": "world hello"}),
];
let results = tql
.query(&data, "message startswith 'hello'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["message"], "hello world");
}
#[test]
fn test_filter_not_startswith() {
let tql = Tql::new();
let data = vec![
json!({"message": "hello world"}),
json!({"message": "world hello"}),
];
let results = tql
.query(&data, "message !startswith 'hello'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["message"], "world hello");
}
#[test]
fn test_filter_endswith() {
let tql = Tql::new();
let data = vec![
json!({"message": "hello world"}),
json!({"message": "world hello"}),
];
let results = tql
.query(&data, "message endswith 'world'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["message"], "hello world");
}
#[test]
fn test_filter_not_endswith() {
let tql = Tql::new();
let data = vec![
json!({"message": "hello world"}),
json!({"message": "world hello"}),
];
let results = tql
.query(&data, "message !endswith 'world'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["message"], "world hello");
}
#[test]
fn test_filter_equals_string() {
let tql = Tql::new();
let data = vec![json!({"status": "test"}), json!({"status": "other"})];
let results = tql
.query(&data, "status = 'test'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["status"], "test");
}
#[test]
fn test_filter_equals_numeric() {
let tql = Tql::new();
let data = vec![json!({"value": 42}), json!({"value": 43})];
let results = tql
.query(&data, "value = 42")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["value"], 42);
}
#[test]
fn test_filter_equals_boolean_true() {
let tql = Tql::new();
let data = vec![json!({"active": true}), json!({"active": false})];
let results = tql
.query(&data, "active = true")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["active"], true);
}
#[test]
fn test_filter_equals_boolean_false() {
let tql = Tql::new();
let data = vec![json!({"active": true}), json!({"active": false})];
let results = tql
.query(&data, "active = false")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["active"], false);
}
#[test]
fn test_filter_not_equals() {
let tql = Tql::new();
let data = vec![json!({"status": "test"}), json!({"status": "other"})];
let results = tql
.query(&data, "status != 'test'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["status"], "other");
}
#[test]
fn test_filter_greater_than() {
let tql = Tql::new();
let data = vec![json!({"value": 15}), json!({"value": 5})];
let results = tql
.query(&data, "value > 10")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["value"], 15);
}
#[test]
fn test_filter_greater_than_or_equal() {
let tql = Tql::new();
let data = vec![
json!({"value": 10}),
json!({"value": 15}),
json!({"value": 5}),
];
let results = tql
.query(&data, "value >= 10")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
}
#[test]
fn test_filter_less_than() {
let tql = Tql::new();
let data = vec![json!({"value": 5}), json!({"value": 15})];
let results = tql
.query(&data, "value < 10")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["value"], 5);
}
#[test]
fn test_filter_less_than_or_equal() {
let tql = Tql::new();
let data = vec![
json!({"value": 10}),
json!({"value": 5}),
json!({"value": 15}),
];
let results = tql
.query(&data, "value <= 10")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
}
#[test]
fn test_get_field_value_simple() {
let tql = Tql::new();
let data = vec![json!({"name": "test", "value": 42})];
let results = tql
.query(&data, "name = 'test'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
}
#[test]
fn test_get_field_value_nested() {
let tql = Tql::new();
let data = vec![json!({"user": {"name": "John", "age": 30}})];
let results = tql
.query(&data, "user.name = 'John'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
}
#[test]
fn test_get_field_value_deeply_nested() {
let tql = Tql::new();
let data = vec![json!({"source": {"geo": {"country": "US", "city": "Seattle"}}})];
let results = tql
.query(&data, "source.geo.country = 'US'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
}
#[test]
fn test_get_missing_field() {
let tql = Tql::new();
let data = vec![json!({"name": "test"})];
let results = tql
.query(&data, "missing = 'value'")
.expect("Query should succeed");
assert_eq!(results.len(), 0);
}
#[test]
fn test_get_missing_nested_field() {
let tql = Tql::new();
let data = vec![json!({"user": {"name": "John"}})];
let results = tql
.query(&data, "user.missing = 'value'")
.expect("Query should succeed");
assert_eq!(results.len(), 0);
}
#[test]
fn test_filter_multiple_requirements_and() {
let tql = Tql::new();
let data = vec![
json!({"status": "active", "type": "user"}),
json!({"status": "active", "type": "admin"}),
json!({"status": "inactive", "type": "user"}),
];
let results = tql
.query(&data, "status = 'active' AND type = 'user'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["status"], "active");
assert_eq!(results[0]["type"], "user");
}
#[test]
fn test_filter_with_contains_multiple() {
let tql = Tql::new();
let data = vec![
json!({"message": "error occurred"}),
json!({"message": "success"}),
json!({"message": "warning: check error"}),
];
let results = tql
.query(&data, "message contains 'error'")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
assert!(results
.iter()
.all(|r| r["message"].as_str().unwrap().contains("error")));
}
#[test]
fn test_filter_missing_field_in_record() {
let tql = Tql::new();
let data = vec![
json!({"name": "Alice"}),
json!({"age": 30}),
json!({"name": "Bob"}),
];
let results = tql
.query(&data, "name = 'Alice'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["name"], "Alice");
}
#[test]
fn test_filter_null_values() {
let tql = Tql::new();
let data = vec![
json!({"status": "active"}),
json!({"status": null}),
json!({"status": "inactive"}),
];
let results = tql
.query(&data, "status = 'active'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["status"], "active");
}
#[test]
fn test_filter_empty_string_values() {
let tql = Tql::new();
let data = vec![
json!({"name": "Alice"}),
json!({"name": ""}),
json!({"name": "Bob"}),
];
let results = tql.query(&data, "name = ''").expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["name"], "");
}
#[test]
fn test_filter_with_nested_field() {
let tql = Tql::new();
let data = vec![
json!({"user": {"name": "Alice"}}),
json!({"user": {"name": "Bob"}}),
json!({"user": {}}),
];
let results = tql
.query(&data, "user.name = 'Alice'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
}
#[test]
fn test_filter_large_dataset() {
let tql = Tql::new();
let data: Vec<serde_json::Value> = (0..1000)
.map(|i| json!({"id": i, "value": i * 10}))
.collect();
let results = tql
.query(&data, "value > 500")
.expect("Query should succeed");
assert!(results.iter().all(|r| r["value"].as_i64().unwrap() > 500));
assert!(results.len() < data.len());
}
#[test]
fn test_filter_with_lowercase_mutator() {
let tql = Tql::new();
let data = vec![
json!({"name": "ALICE"}),
json!({"name": "alice"}),
json!({"name": "Alice"}),
json!({"name": "bob"}),
];
let results = tql
.query(&data, "name | lowercase = 'alice'")
.expect("Query should succeed");
assert_eq!(results.len(), 3);
}
#[test]
fn test_filter_with_uppercase_mutator() {
let tql = Tql::new();
let data = vec![
json!({"name": "alice"}),
json!({"name": "ALICE"}),
json!({"name": "bob"}),
];
let results = tql
.query(&data, "name | uppercase = 'ALICE'")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
}
#[test]
fn test_filter_with_trim_mutator() {
let tql = Tql::new();
let data = vec![
json!({"name": " alice "}),
json!({"name": "alice"}),
json!({"name": "bob"}),
];
let results = tql
.query(&data, "name | trim = 'alice'")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
}
#[test]
fn test_filter_with_chained_mutators() {
let tql = Tql::new();
let data = vec![
json!({"text": " HELLO "}),
json!({"text": "hello"}),
json!({"text": "WORLD"}),
];
let results = tql
.query(&data, "text | trim | lowercase = 'hello'")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
}
#[test]
fn test_filter_preserves_all_fields() {
let tql = Tql::new();
let data = vec![
json!({"name": "Alice", "age": 30, "city": "NYC", "_id": "1", "_score": 1.5}),
json!({"name": "Bob", "age": 25, "city": "LA", "_id": "2", "_score": 2.0}),
];
let results = tql
.query(&data, "name = 'Alice'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["age"], 30);
assert_eq!(results[0]["city"], "NYC");
}
#[test]
fn test_filter_no_matches() {
let tql = Tql::new();
let data = vec![json!({"status": "active"}), json!({"status": "pending"})];
let results = tql
.query(&data, "status = 'archived'")
.expect("Query should succeed");
assert_eq!(results.len(), 0);
}
#[test]
fn test_filter_all_match() {
let tql = Tql::new();
let data = vec![
json!({"type": "user"}),
json!({"type": "user"}),
json!({"type": "user"}),
];
let results = tql
.query(&data, "type = 'user'")
.expect("Query should succeed");
assert_eq!(results.len(), 3);
}
#[test]
fn test_filter_with_and_logic() {
let tql = Tql::new();
let data = vec![
json!({"status": "active", "role": "admin"}),
json!({"status": "active", "role": "user"}),
json!({"status": "inactive", "role": "admin"}),
];
let results = tql
.query(&data, "status = 'active' AND role = 'admin'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["status"], "active");
assert_eq!(results[0]["role"], "admin");
}
#[test]
fn test_filter_with_or_logic() {
let tql = Tql::new();
let data = vec![
json!({"status": "active"}),
json!({"status": "inactive"}),
json!({"status": "pending"}),
];
let results = tql
.query(&data, "status = 'active' OR status = 'pending'")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
}
#[test]
fn test_filter_with_negation() {
let tql = Tql::new();
let data = vec![
json!({"status": "active"}),
json!({"status": "inactive"}),
json!({"status": "pending"}),
];
let results = tql
.query(&data, "status != 'active'")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
assert!(results.iter().all(|r| r["status"] != "active"));
}
#[test]
fn test_filter_with_array_contains() {
let tql = Tql::new();
let data = vec![
json!({"tags": ["python", "django"]}),
json!({"tags": ["javascript", "react"]}),
json!({"tags": ["python", "flask"]}),
];
let results = tql
.query(&data, "tags contains 'python'")
.expect("Query should succeed");
assert_eq!(results.len(), 2);
}
#[test]
fn test_filter_value_in_array_field() {
let tql = Tql::new();
let data = vec![
json!({"tags": ["python", "django"]}),
json!({"tags": ["javascript", "react"]}),
];
let results = tql
.query(&data, "'python' in tags")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
}
#[test]
fn test_filter_numeric_string_coercion() {
let tql = Tql::new();
let data = vec![json!({"value": 42}), json!({"value": 43})];
let results = tql
.query(&data, "value = '42'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
}
#[test]
fn test_deeply_nested_field_with_mutator() {
let tql = Tql::new();
let data = vec![
json!({"user": {"profile": {"name": "ALICE"}}}),
json!({"user": {"profile": {"name": "bob"}}}),
];
let results = tql
.query(&data, "user.profile.name | lowercase = 'alice'")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
}
#[test]
fn test_complex_and_or_expression() {
let tql = Tql::new();
let data = vec![
json!({"status": "active", "role": "admin", "level": 5}),
json!({"status": "active", "role": "user", "level": 3}),
json!({"status": "inactive", "role": "admin", "level": 4}),
json!({"status": "inactive", "role": "user", "level": 2}),
];
let results = tql
.query(&data, "(status = 'active' AND role = 'admin') OR level > 4")
.expect("Query should succeed");
assert_eq!(results.len(), 1);
assert_eq!(results[0]["status"], "active");
assert_eq!(results[0]["role"], "admin");
}