#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
fn sample_registry() -> CommandRegistry {
let mut registry = CommandRegistry::new("2.0.0");
let complexity_sub = CommandMetadata::builder("complexity")
.short_description("Analyze code complexity")
.long_description("Calculate cyclomatic complexity for all functions")
.tags(["quality", "metrics", "complexity"])
.build();
let satd_sub = CommandMetadata::builder("satd")
.short_description("Find technical debt")
.long_description("Detect TODO/FIXME/HACK comments indicating technical debt")
.tags(["quality", "debt", "satd"])
.build();
registry.register(
CommandMetadata::builder("analyze")
.short_description("Analyze code metrics")
.long_description("Run various code analysis tools on your project")
.aliases(["a", "an"])
.subcommand(complexity_sub)
.subcommand(satd_sub)
.category("analysis")
.tags(["quality", "metrics"])
.related("context")
.build(),
);
registry.register(
CommandMetadata::builder("context")
.short_description("Generate project context")
.long_description("Generate AI-friendly project context using AST analysis")
.aliases(["ctx"])
.category("generation")
.tags(["generation", "ast", "context"])
.related("analyze")
.build(),
);
registry.register(
CommandMetadata::builder("quality-gate")
.short_description("Run quality gates")
.long_description("Check code quality against configured thresholds")
.aliases(["qg", "gate"])
.category("quality")
.tags(["quality", "ci", "gate"])
.build(),
);
registry
}
mod nlp_tests {
use super::*;
#[test]
fn test_nlp_processor_creation() {
let nlp = HelpNlpProcessor::new();
let tokens = nlp.preprocess("analyze code complexity");
assert!(!tokens.is_empty());
}
#[test]
fn test_preprocess_removes_stop_words() {
let nlp = HelpNlpProcessor::new();
let tokens = nlp.preprocess("run the pmat command");
assert!(tokens.is_empty() || !tokens.contains(&"the".to_string()));
}
#[test]
fn test_term_frequency() {
let nlp = HelpNlpProcessor::new();
let tf = nlp.term_frequency("code code code analysis");
let code_freq = tf.get("code").unwrap_or(&0.0);
let analysis_freq = tf.get("analysi").unwrap_or(&0.0);
assert!(
code_freq > analysis_freq,
"code freq {} should be > analysis freq {}",
code_freq,
analysis_freq
);
}
#[test]
fn test_bm25_score() {
let nlp = HelpNlpProcessor::new();
let score1 = nlp.bm25_score("complexity", "analyze complexity metrics", 1.2, 0.75);
let score2 = nlp.bm25_score("complexity", "generate context ast", 1.2, 0.75);
assert!(score1 > score2);
}
}
mod graph_tests {
use super::*;
#[test]
fn test_graph_creation() {
let graph = CommandGraph::new();
assert!(graph.command_to_node.is_empty());
}
#[test]
fn test_build_from_registry() {
let registry = sample_registry();
let mut graph = CommandGraph::new();
graph.build_from_registry(®istry);
assert!(graph.command_to_node.contains_key("analyze"));
assert!(graph.command_to_node.contains_key("context"));
assert!(graph.command_to_node.contains_key("analyze complexity"));
}
#[test]
fn test_pagerank_importance() {
let registry = sample_registry();
let mut graph = CommandGraph::new();
graph.build_from_registry(®istry);
let importance = graph.importance("analyze");
assert!(importance >= 0.0);
}
#[test]
fn test_top_k_important() {
let registry = sample_registry();
let mut graph = CommandGraph::new();
graph.build_from_registry(®istry);
let top = graph.top_k_important(3);
assert!(top.len() <= 3);
}
}
mod unified_help_tests {
use super::*;
#[test]
fn test_unified_help_creation() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
assert!(!help.command_docs.is_empty());
}
#[test]
fn test_lookup_exact_match() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
let response = help.lookup("analyze");
assert!(matches!(response, HelpResponse::Exact(_)));
}
#[test]
fn test_lookup_fuzzy_match() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
let response = help.lookup("analize");
assert!(matches!(response, HelpResponse::DidYouMean { .. }));
}
#[test]
fn test_lookup_semantic_search() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
let response = help.lookup("how to check code quality");
match response {
HelpResponse::SearchResults { results, .. } => {
assert!(!results.is_empty());
}
_ => panic!("Expected SearchResults"),
}
}
#[test]
fn test_search_returns_relevant_results() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
let results = help.search("complexity", 3);
assert!(!results.is_empty());
assert!(
results[0].command.contains("complexity")
|| results[0].description.to_lowercase().contains("complex")
);
}
#[test]
fn test_search_ranking() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
let results = help.search("technical debt", 5);
let satd_result = results.iter().find(|r| r.command.contains("satd"));
assert!(satd_result.is_some());
}
#[test]
fn test_get_important_commands() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
let important = help.get_important_commands(5);
assert!(!important.is_empty());
}
#[test]
fn test_get_by_tag() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
let quality_cmds = help.get_by_tag("quality");
assert!(!quality_cmds.is_empty());
}
#[test]
fn test_get_by_category() {
let registry = sample_registry();
let help = UnifiedHelpService::new(registry);
let analysis_cmds = help.get_by_category("analysis");
assert_eq!(analysis_cmds.len(), 1);
assert_eq!(analysis_cmds[0].name, "analyze");
}
}
mod levenshtein_tests {
use super::*;
#[test]
fn test_levenshtein_identical() {
assert_eq!(levenshtein("test", "test"), 0);
}
#[test]
fn test_levenshtein_one_char() {
assert_eq!(levenshtein("test", "fest"), 1); assert_eq!(levenshtein("test", "tests"), 1); assert_eq!(levenshtein("test", "tes"), 1); }
#[test]
fn test_levenshtein_empty() {
assert_eq!(levenshtein("", "test"), 4);
assert_eq!(levenshtein("test", ""), 4);
assert_eq!(levenshtein("", ""), 0);
}
}
}