use super::*;
use std::collections::HashMap;
#[test]
fn test_batch_config_default() {
let config = BatchConfig::default();
assert_eq!(config.max_batch_size, 1000);
assert_eq!(config.max_depth, 10);
assert!(config.parallel_execution);
assert!(config.deduplicate_queries);
}
#[test]
fn test_batch_loader_creation() {
let loader = BatchLoader::new();
assert_eq!(loader.config.max_batch_size, 1000);
let custom_config = BatchConfig {
max_batch_size: 500,
max_depth: 5,
parallel_execution: false,
deduplicate_queries: false,
};
let custom_loader = BatchLoader::with_config(custom_config);
assert_eq!(custom_loader.config.max_batch_size, 500);
assert_eq!(custom_loader.config.max_depth, 5);
assert!(!custom_loader.config.parallel_execution);
assert!(!custom_loader.config.deduplicate_queries);
}
#[test]
fn test_row_to_json_conversion_logic() {
let _loader = BatchLoader::new();
let test_cases = vec![
("String", serde_json::Value::String("test".to_string())),
(
"Number",
serde_json::Value::Number(serde_json::Number::from(42)),
),
("Bool", serde_json::Value::Bool(true)),
("Null", serde_json::Value::Null),
];
for (type_name, value) in test_cases {
match value {
serde_json::Value::String(s) => assert_eq!(s, "test"),
serde_json::Value::Number(n) => assert_eq!(n.as_i64(), Some(42)),
serde_json::Value::Bool(b) => assert!(b),
serde_json::Value::Null => assert!(value.is_null()),
_ => panic!("Unexpected type: {}", type_name),
}
}
}
#[test]
fn test_batch_result_structure() {
let mut records: HashMap<String, HashMap<Value, JsonValue>> = HashMap::new();
let mut user_records = HashMap::new();
user_records.insert(
Value::Number(serde_json::Number::from(1)),
serde_json::json!({
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}),
);
records.insert("users".to_string(), user_records);
let result = BatchLoadResult {
records,
query_count: 1,
record_count: 1,
};
assert_eq!(result.query_count, 1);
assert_eq!(result.record_count, 1);
assert!(result.records.contains_key("users"));
let user_data = result.records.get("users").unwrap();
let user_record = user_data
.get(&Value::Number(serde_json::Number::from(1)))
.unwrap();
assert_eq!(user_record["name"], "John Doe");
assert_eq!(user_record["email"], "john@example.com");
}
#[test]
fn test_group_by_parent_id_logic() {
let loader = BatchLoader::new();
let results = vec![
serde_json::json!({
"id": 1,
"user_id": 10,
"title": "Post 1"
}),
serde_json::json!({
"id": 2,
"user_id": 10,
"title": "Post 2"
}),
serde_json::json!({
"id": 3,
"user_id": 20,
"title": "Post 3"
}),
];
let parent_ids = vec![
Value::Number(serde_json::Number::from(10)),
Value::Number(serde_json::Number::from(20)),
Value::Number(serde_json::Number::from(30)), ];
let grouped = loader.group_by_parent_id(results, "user_id", &parent_ids);
assert!(grouped.is_ok());
let grouped = grouped.unwrap();
let user_10_posts = grouped
.get(&Value::Number(serde_json::Number::from(10)))
.unwrap();
assert_eq!(user_10_posts.len(), 2);
let user_20_posts = grouped
.get(&Value::Number(serde_json::Number::from(20)))
.unwrap();
assert_eq!(user_20_posts.len(), 1);
let user_30_posts = grouped
.get(&Value::Number(serde_json::Number::from(30)))
.unwrap();
assert_eq!(user_30_posts.len(), 0);
}
#[tokio::test]
async fn test_cache_stats() {
let loader = BatchLoader::new();
let stats = loader.cache_stats().await;
assert_eq!(stats.cached_queries, 0);
assert_eq!(stats.total_cached_records, 0);
loader.clear_cache().await;
let stats_after_clear = loader.cache_stats().await;
assert_eq!(stats_after_clear.cached_queries, 0);
}
#[test]
fn test_postgresql_type_conversion_patterns() {
let string_val = Some("test".to_string());
let json_val = string_val.map_or(JsonValue::Null, JsonValue::String);
assert_eq!(json_val, JsonValue::String("test".to_string()));
let int_val = Some(42i64);
let json_val = int_val.map_or(JsonValue::Null, |v| {
JsonValue::Number(serde_json::Number::from(v))
});
assert_eq!(json_val, JsonValue::Number(serde_json::Number::from(42)));
let int32_val = Some(24i32);
let json_val = int32_val.map_or(JsonValue::Null, |v| {
JsonValue::Number(serde_json::Number::from(v))
});
assert_eq!(json_val, JsonValue::Number(serde_json::Number::from(24)));
let float_val = Some(3.14f64);
let json_val = float_val.map_or(JsonValue::Null, |v| {
JsonValue::Number(serde_json::Number::from_f64(v).unwrap_or(serde_json::Number::from(0)))
});
assert!(json_val.is_number());
let bool_val = Some(true);
let json_val = bool_val.map_or(JsonValue::Null, JsonValue::Bool);
assert_eq!(json_val, JsonValue::Bool(true));
let uuid_val = Some(uuid::Uuid::new_v4());
let json_val = uuid_val.map_or(JsonValue::Null, |v| JsonValue::String(v.to_string()));
assert!(json_val.is_string());
let datetime_val = Some(chrono::Utc::now());
let json_val = datetime_val.map_or(JsonValue::Null, |v| JsonValue::String(v.to_rfc3339()));
assert!(json_val.is_string());
let null_val: Option<String> = None;
let json_val = null_val.map_or(JsonValue::Null, JsonValue::String);
assert_eq!(json_val, JsonValue::Null);
}
#[test]
fn test_error_handling_patterns() {
let db_error = "Connection failed";
let orm_error = OrmError::Database(format!("Batch query failed: {}", db_error));
match orm_error {
OrmError::Database(msg) => {
assert!(msg.contains("Batch query failed"));
assert!(msg.contains("Connection failed"));
}
_ => panic!("Expected Database error"),
}
let conversion_error = "Invalid column type";
let orm_error = OrmError::Database(format!(
"Failed to convert row to JSON: {}",
conversion_error
));
match orm_error {
OrmError::Database(msg) => {
assert!(msg.contains("Failed to convert row to JSON"));
assert!(msg.contains("Invalid column type"));
}
_ => panic!("Expected Database error"),
}
}