use serde_json::json;
#[derive(Debug)]
struct CostResult {
query: String,
complexity_score: usize,
estimated_cost: usize,
depth: usize,
field_count: usize,
}
fn calculate_cost(query: &str) -> anyhow::Result<CostResult> {
let depth = query.matches('{').count() / 2; let field_count = query.split_whitespace().count();
let score = depth * field_count.max(1);
Ok(CostResult {
query: query.to_string(),
complexity_score: score,
estimated_cost: depth * 50, depth,
field_count,
})
}
#[test]
fn test_cost_simple_query() {
let query = "query { users { id } }";
let result = calculate_cost(query).unwrap();
assert!(result.complexity_score > 0);
assert!(result.estimated_cost > 0);
}
#[test]
fn test_cost_complex_query_higher_than_simple() {
let simple = calculate_cost("query { users { id } }").unwrap();
let complex = calculate_cost("query { users { posts { comments } } }").unwrap();
assert!(complex.complexity_score > simple.complexity_score);
}
#[test]
fn test_cost_respects_field_count() {
let few_fields = calculate_cost("query { users { id } }").unwrap();
let many_fields = calculate_cost("query { users { id name email phone address } }").unwrap();
assert!(many_fields.complexity_score >= few_fields.complexity_score);
}
#[test]
fn test_cost_respects_depth() {
let shallow = calculate_cost("query { users { id } }").unwrap();
let deep =
calculate_cost("query { users { posts { comments { author { name } } } } }").unwrap();
assert!(deep.complexity_score > shallow.complexity_score);
}
#[test]
fn test_cost_result_is_deterministic() {
let query = "query { users { id name } }";
let result1 = calculate_cost(query).unwrap();
let result2 = calculate_cost(query).unwrap();
assert_eq!(result1.complexity_score, result2.complexity_score);
}
#[test]
fn test_cost_result_serializes_to_json() {
let query = "query { users { id } }";
let result = calculate_cost(query).unwrap();
let json_output = json!({
"query": result.query,
"complexity_score": result.complexity_score,
"estimated_cost": result.estimated_cost,
"depth": result.depth,
"field_count": result.field_count,
});
assert_eq!(json_output["query"], query);
assert!(json_output["complexity_score"].is_number());
}
#[test]
fn test_cost_is_faster_than_explain() {
let query = "query { users { id } }";
let cost_result = calculate_cost(query).unwrap();
assert!(cost_result.complexity_score > 0);
assert_eq!(cost_result.query, query);
}
#[test]
fn test_cost_with_aliases() {
let query = "query { users: allUsers { id name } }";
let result = calculate_cost(query).unwrap();
assert!(result.complexity_score > 0);
}
#[test]
fn test_cost_with_directives() {
let query = "query { users { id @include(if: true) } }";
let result = calculate_cost(query).unwrap();
assert!(result.complexity_score > 0);
}
#[test]
fn test_cost_zero_for_empty_query() {
let query = "query { }";
let result = calculate_cost(query).unwrap();
assert_eq!(result.complexity_score, 0);
}