#[cfg(test)]
mod tests {
use crate::parser::query_builder::{
Condition, QueryBuilder, build_insert_placeholders_for_entries_with_types,
build_where_clause,
};
use serde_json::json;
use std::collections::HashMap;
#[test]
fn build_where_clause_casts_uuid_comparisons_to_text_by_default() {
let conditions: Vec<Condition> = vec![Condition::eq(
"workspace_id",
json!("550e8400-e29b-41d4-a716-446655440000"),
)];
let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");
assert_eq!(clause, " WHERE t.\"workspace_id\"::text = $1::text");
assert_eq!(values, vec![json!("550e8400-e29b-41d4-a716-446655440000")]);
}
#[test]
fn build_where_clause_can_disable_uuid_text_casts() {
let conditions: Vec<Condition> = vec![
Condition::eq(
"workspace_id",
json!("550e8400-e29b-41d4-a716-446655440000"),
)
.with_uuid_value_text_cast(false),
];
let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");
assert_eq!(clause, " WHERE t.\"workspace_id\" = $1");
assert_eq!(values, vec![json!("550e8400-e29b-41d4-a716-446655440000")]);
}
#[test]
fn query_builder_struct_builds_where_clause() {
let query_builder = QueryBuilder::new()
.with_start_index(3)
.with_condition(Condition::eq("workspace_id", json!("workspace-1")));
let (clause, values) = query_builder
.build_where_clause()
.expect("where clause from QueryBuilder");
assert_eq!(clause, " WHERE t.\"workspace_id\" = $3");
assert_eq!(values, vec![json!("workspace-1")]);
}
#[test]
fn build_insert_placeholders_adds_jsonb_cast_with_column_types() {
let entries = vec![
("\"payload\"".to_string(), json!({"source": "test"})),
(
"\"created_at\"".to_string(),
json!("2024-01-15T12:00:00.000Z"),
),
];
let column_types = HashMap::from([
("payload".to_string(), "jsonb".to_string()),
(
"created_at".to_string(),
"timestamp with time zone".to_string(),
),
]);
let (placeholders, bind_values) =
build_insert_placeholders_for_entries_with_types(&entries, Some(&column_types));
assert_eq!(placeholders, vec!["$1::jsonb", "$2::timestamptz"]);
assert_eq!(bind_values.len(), 2);
}
#[test]
fn build_where_clause_emits_pg_cast_for_string_values_against_numeric_columns() {
let conditions: Vec<Condition> =
vec![Condition::eq("cache_hit_ratio", json!("0.75")).with_pg_cast(Some("float8"))];
let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");
assert_eq!(clause, " WHERE t.\"cache_hit_ratio\" = $1::float8");
assert_eq!(values, vec![json!("0.75")]);
}
#[test]
fn build_where_clause_skips_pg_cast_for_native_numbers() {
let conditions: Vec<Condition> =
vec![Condition::eq("cache_hit_ratio", json!(0.75)).with_pg_cast(Some("float8"))];
let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");
assert_eq!(clause, " WHERE t.\"cache_hit_ratio\" = $1");
assert_eq!(values, vec![json!(0.75)]);
}
#[test]
fn build_where_clause_renders_in_list_with_pg_cast() {
let conditions: Vec<Condition> = vec![
Condition::new(
"total_requests",
crate::parser::query_builder::ConditionOperator::In,
vec![json!("1"), json!("2"), json!(3)],
false,
)
.with_pg_cast(Some("int8")),
];
let (clause, values) = build_where_clause(&conditions, 1).expect("where clause");
assert_eq!(
clause,
" WHERE t.\"total_requests\" IN ($1::int8, $2::int8, $3)"
);
assert_eq!(values, vec![json!("1"), json!("2"), json!(3)]);
}
#[test]
fn build_where_clause_uuid_cast_takes_precedence_over_pg_cast() {
let conditions: Vec<Condition> = vec![
Condition::eq(
"workspace_id",
json!("550e8400-e29b-41d4-a716-446655440000"),
)
.with_pg_cast(Some("text")),
];
let (clause, _values) = build_where_clause(&conditions, 1).expect("where clause");
assert_eq!(clause, " WHERE t.\"workspace_id\"::text = $1::text");
}
#[test]
fn build_insert_placeholders_preserves_null_without_binding() {
let entries = vec![
("\"payload\"".to_string(), json!(null)),
("\"title\"".to_string(), json!("hello")),
];
let column_types = HashMap::from([("payload".to_string(), "jsonb".to_string())]);
let (placeholders, bind_values) =
build_insert_placeholders_for_entries_with_types(&entries, Some(&column_types));
assert_eq!(placeholders, vec!["NULL", "$1"]);
assert_eq!(bind_values.len(), 1);
assert_eq!(*bind_values[0], json!("hello"));
}
}