use super::*;
#[test]
fn test_parse_routing_decision_fast() {
let response = "FAST";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Fast);
}
#[test]
fn test_parse_routing_decision_fast_lowercase() {
let response = "fast";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Fast);
}
#[test]
fn test_parse_routing_decision_fast_in_sentence() {
let response = "I think FAST would be best for this simple task";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Fast);
}
#[test]
fn test_parse_routing_decision_balanced() {
let response = "BALANCED";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Balanced);
}
#[test]
fn test_parse_routing_decision_balanced_lowercase() {
let response = "balanced";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Balanced);
}
#[test]
fn test_parse_routing_decision_balanced_in_sentence() {
let response = "For this coding task, I recommend BALANCED";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Balanced);
}
#[test]
fn test_parse_routing_decision_deep() {
let response = "DEEP";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Deep);
}
#[test]
fn test_parse_routing_decision_deep_lowercase() {
let response = "deep";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Deep);
}
#[test]
fn test_parse_routing_decision_deep_in_sentence() {
let response = "This requires DEEP reasoning and analysis";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Deep);
}
#[test]
fn test_parse_routing_decision_unparseable_returns_error() {
let response = "I'm not sure about this one";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(
result.is_err(),
"Unparseable response should return error, not default to Balanced"
);
let err = result.unwrap_err();
let err_msg = format!("{}", err);
assert!(
err_msg.contains("unparseable") || err_msg.contains("parse"),
"Error message should indicate parse failure, got: {}",
err_msg
);
}
#[test]
fn test_parse_routing_decision_refusal_returns_error() {
let test_cases = vec![
"I cannot help with that request",
"I'm unable to make this decision",
"Sorry, I cannot answer that",
"ERROR: timeout occurred",
"CANNOT process this request",
];
for response in test_cases {
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(
result.is_err(),
"Refusal '{}' should return error, got: {:?}",
response,
result
);
}
}
#[test]
fn test_parse_routing_decision_word_boundary_false_positives() {
let false_positive_cases = vec![
"BREAKFAST", "STEADFAST", "Belfast", "FASTIDIOUS", ];
for response in false_positive_cases {
let result = LlmBasedRouter::parse_routing_decision(response);
if let Ok(target) = result {
assert_ne!(
target,
TargetModel::Fast,
"Response '{}' should not match Fast (contains FAST as substring but not whole word)",
response
);
}
}
}
#[test]
fn test_parse_routing_decision_word_boundary_true_positives() {
let true_positive_cases = vec![
("FAST", TargetModel::Fast),
("fast", TargetModel::Fast),
("Fast", TargetModel::Fast),
(" FAST ", TargetModel::Fast), ("FAST\n", TargetModel::Fast), ("BALANCED", TargetModel::Balanced),
("balanced", TargetModel::Balanced),
("DEEP", TargetModel::Deep),
("deep", TargetModel::Deep),
];
for (response, expected) in true_positive_cases {
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(
result.is_ok(),
"Response '{}' should successfully parse",
response
);
assert_eq!(
result.unwrap(),
expected,
"Response '{}' should match {:?}",
response,
expected
);
}
}
#[test]
fn test_parse_routing_decision_false_positive_cases() {
let test_cases = vec![
(
"I cannot make this decision fast enough",
"contains 'fast' but is a refusal",
),
(
"ERROR: Cannot provide BALANCED response",
"contains 'balanced' but is error",
),
(
"This requires deep thought, but CANNOT decide",
"contains 'deep' but is refusal",
),
(
"UNABLE to determine if FAST is appropriate",
"contains 'fast' but is refusal",
),
];
for (response, description) in test_cases {
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(
result.is_err(),
"Should error for: {} (response: '{}')",
description,
response
);
}
}
#[test]
fn test_parse_routing_decision_position_based_matching() {
let test_cases = vec![
("FAST or BALANCED would work", TargetModel::Fast),
("Choose BALANCED or DEEP", TargetModel::Balanced),
("Not DEEP, use FAST instead", TargetModel::Deep), ];
for (response, expected) in test_cases {
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok(), "Should succeed for: '{}'", response);
assert_eq!(
result.unwrap(),
expected,
"Should match leftmost keyword in: '{}'",
response
);
}
}
#[test]
fn test_parse_routing_decision_malformed_returns_error() {
let test_cases = vec![
"The best choice would be something else",
"Let me think about this carefully...",
"123456789",
"fast balanced deep", ];
for response in test_cases {
let result = LlmBasedRouter::parse_routing_decision(response);
if response.contains("fast") || response.contains("balanced") || response.contains("deep") {
continue;
}
assert!(
result.is_err(),
"Malformed '{}' should return error",
response
);
}
}
#[test]
fn test_parse_routing_decision_empty_returns_error() {
let response = "";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_err(), "Empty response should return error");
let err = result.unwrap_err();
let err_msg = format!("{}", err);
assert!(
err_msg.contains("empty") || err_msg.contains("no response"),
"Error message should indicate empty response, got: {}",
err_msg
);
}
#[test]
fn test_parse_routing_decision_whitespace_returns_error() {
let response = " \n\t ";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(
result.is_err(),
"Whitespace-only response should return error"
);
let err = result.unwrap_err();
let err_msg = format!("{}", err);
assert!(
err_msg.contains("empty") || err_msg.contains("no response"),
"Error message should indicate empty response, got: {}",
err_msg
);
}
#[test]
fn test_parse_routing_decision_multiple_options_first_wins() {
let response = "FAST or BALANCED would work";
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(result.is_ok());
assert_eq!(result.unwrap(), TargetModel::Fast);
}
#[test]
fn test_parse_routing_decision_tier_like_invalid_responses() {
let tier_like_invalid_cases = vec![
"INVALID_TIER",
"SUPER_FAST",
"MEDIUM",
"SLOW",
"QUICK",
"FASTER",
"SLOWER",
"FAST_TIER",
"BALANCED_TIER",
"DEEP_TIER",
"TIER_FAST",
"FASE", "BALANCET", "DEP", "FASTEST", "UNBALANCED", ];
for response in &tier_like_invalid_cases {
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(
result.is_err(),
"Tier-like invalid response '{}' should return error, not succeed. \
This prevents silent failures where LLM hallucinations are accepted as valid tiers.",
response
);
let err = result.unwrap_err();
let err_msg = format!("{}", err);
assert!(
err_msg.to_lowercase().contains("unparseable")
|| err_msg.to_lowercase().contains("parse")
|| err_msg.to_lowercase().contains("invalid"),
"Error for '{}' should indicate parsing failure, got: {}",
response,
err_msg
);
assert!(
err_msg.contains(response),
"Error for '{}' should include the invalid response text for debugging, got: {}",
response,
err_msg
);
}
println!(
"✅ All {} tier-like invalid responses rejected correctly",
tier_like_invalid_cases.len()
);
}
#[test]
fn test_parse_routing_decision_case_sensitivity_for_invalid() {
let case_variations = vec![
"INVALID_TIER",
"invalid_tier",
"Invalid_Tier",
"InVaLiD_tIeR",
];
for response in case_variations {
let result = LlmBasedRouter::parse_routing_decision(response);
assert!(
result.is_err(),
"Invalid tier '{}' should be rejected regardless of case",
response
);
}
}