use crate::transpiler::nosql::qdrant::ToQdrant;
#[test]
fn test_qdrant_search() {
use crate::ast::*;
let mut cmd = Qail::get("points");
cmd.columns.push(Expr::Named("id".to_string()));
cmd.columns.push(Expr::Named("score".to_string()));
cmd.cages.push(Cage {
kind: CageKind::Filter,
conditions: vec![
Condition {
left: Expr::Named("vector".to_string()),
op: Operator::Fuzzy,
value: Value::String("cute cat".to_string()),
is_array_unnest: false,
},
Condition {
left: Expr::Named("city".to_string()),
op: Operator::Eq,
value: Value::String("London".to_string()),
is_array_unnest: false,
},
],
logical_op: LogicalOp::And,
});
cmd.cages.push(Cage {
kind: CageKind::Limit(10),
conditions: vec![],
logical_op: LogicalOp::And,
});
let qdrant = cmd.to_qdrant_search();
assert!(qdrant.contains("{{EMBED:cute cat}}"));
assert!(qdrant.contains("\"filter\": { \"must\": ["));
assert!(qdrant.contains("\"key\": \"city\", \"match\": { \"value\": \"London\" }"));
}
#[test]
fn test_qdrant_or_filter_output() {
use crate::ast::{Operator, Qail};
let qdrant = Qail::get("points")
.or_filter("city", Operator::Eq, "London")
.or_filter("country", Operator::Eq, "UK")
.to_qdrant_search();
assert!(
qdrant.contains("\"should\": ["),
"Expected should group: {qdrant}"
);
}
#[test]
fn test_qdrant_and_plus_or_filter_output() {
use crate::ast::{Operator, Qail};
let qdrant = Qail::get("points")
.filter("is_active", Operator::Eq, true)
.or_filter("city", Operator::Eq, "London")
.or_filter("country", Operator::Eq, "UK")
.to_qdrant_search();
assert!(
qdrant.contains("\"must\": ["),
"Expected must group: {qdrant}"
);
assert!(
qdrant.contains("\"should\": ["),
"Expected should group: {qdrant}"
);
}
#[test]
fn test_qdrant_multiple_or_cages_remain_separate_groups() {
use crate::ast::{Cage, CageKind, Condition, Expr, LogicalOp, Operator, Qail, Value};
let qdrant = Qail {
table: "points".to_string(),
cages: vec![
Cage {
kind: CageKind::Filter,
conditions: vec![Condition {
left: Expr::Named("tenant_id".to_string()),
op: Operator::Eq,
value: Value::String("t1".to_string()),
is_array_unnest: false,
}],
logical_op: LogicalOp::And,
},
Cage {
kind: CageKind::Filter,
conditions: vec![
Condition {
left: Expr::Named("city".to_string()),
op: Operator::Eq,
value: Value::String("London".to_string()),
is_array_unnest: false,
},
Condition {
left: Expr::Named("city".to_string()),
op: Operator::Eq,
value: Value::String("Paris".to_string()),
is_array_unnest: false,
},
],
logical_op: LogicalOp::Or,
},
Cage {
kind: CageKind::Filter,
conditions: vec![
Condition {
left: Expr::Named("country".to_string()),
op: Operator::Eq,
value: Value::String("UK".to_string()),
is_array_unnest: false,
},
Condition {
left: Expr::Named("country".to_string()),
op: Operator::Eq,
value: Value::String("FR".to_string()),
is_array_unnest: false,
},
],
logical_op: LogicalOp::Or,
},
],
..Default::default()
}
.to_qdrant_search();
let should_count = qdrant.matches("\"should\": [").count();
assert!(
should_count >= 2,
"Expected multiple nested OR groups, got {should_count}: {qdrant}"
);
}