#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_levenshtein_distance() {
assert_eq!(levenshtein_distance("", ""), 0);
assert_eq!(levenshtein_distance("", "abc"), 3);
assert_eq!(levenshtein_distance("abc", ""), 3);
assert_eq!(levenshtein_distance("abc", "abc"), 0);
assert_eq!(levenshtein_distance("abc", "ab"), 1);
assert_eq!(levenshtein_distance("analyze", "analize"), 1);
assert_eq!(levenshtein_distance("satd", "std"), 1); }
#[test]
fn test_common_mistake_suggestions() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["agent".to_string(), "analyze".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("pmat analyze"));
let result = suggester.suggest_command(&["analize".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze"));
let result = suggester.suggest_command(&["complexity".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze complexity"));
}
#[test]
fn test_analyze_subcommand_suggestions() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["analyze".to_string(), "std".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("satd"));
}
#[test]
fn test_no_suggestion_for_valid_commands() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["analyze".to_string()]);
assert!(result.is_none());
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod extended_tests {
use super::*;
#[test]
fn test_get_help_examples() {
let examples = CommandSuggester::get_help_examples();
assert!(examples.contains("EXAMPLES"));
assert!(examples.contains("pmat analyze complexity"));
assert!(examples.contains("pmat analyze satd"));
assert!(examples.contains("pmat analyze dead-code"));
assert!(examples.contains("pmat context"));
assert!(examples.contains("pmat quality-gate"));
assert!(examples.contains("pmat agent start"));
}
#[test]
fn test_command_suggester_default() {
let suggester = CommandSuggester::default();
let result = suggester.suggest_command(&["analize".to_string()]);
assert!(result.is_some());
}
#[test]
fn test_suggest_command_empty_args() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&[]);
assert!(result.is_none());
}
#[test]
fn test_suggest_main_command_typo() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["genrate".to_string()]);
if let Some(suggestion) = result {
assert!(suggestion.contains("generate"));
}
}
#[test]
fn test_suggest_satd_typos() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["stad".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("satd"));
let result = suggester.suggest_command(&["sadt".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("satd"));
}
#[test]
fn test_suggest_analyse_british_spelling() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["analyse".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze"));
}
#[test]
fn test_suggest_analyze_subcommands() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["analyze".to_string(), "deadcode".to_string()]);
if let Some(suggestion) = result {
assert!(suggestion.contains("dead-code") || suggestion.contains("analyze"));
}
let result = suggester.suggest_command(&["analyze".to_string(), "duplicate".to_string()]);
if let Some(suggestion) = result {
assert!(suggestion.contains("duplicates") || suggestion.contains("analyze"));
}
}
#[test]
fn test_suggest_complexity_shortcut() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["complexity".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze complexity"));
}
#[test]
fn test_suggest_dead_code_shortcut() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["dead-code".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze dead-code"));
}
#[test]
fn test_suggest_tdg_shortcut() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["tdg".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze tdg"));
}
#[test]
fn test_levenshtein_distance_single_char() {
assert_eq!(levenshtein_distance("a", "a"), 0);
assert_eq!(levenshtein_distance("a", "b"), 1);
assert_eq!(levenshtein_distance("a", ""), 1);
assert_eq!(levenshtein_distance("", "a"), 1);
}
#[test]
fn test_levenshtein_distance_insertions() {
assert_eq!(levenshtein_distance("abc", "abcd"), 1);
assert_eq!(levenshtein_distance("abc", "xabc"), 1);
assert_eq!(levenshtein_distance("abc", "abxc"), 1);
}
#[test]
fn test_levenshtein_distance_deletions() {
assert_eq!(levenshtein_distance("abcd", "abc"), 1);
assert_eq!(levenshtein_distance("abcd", "bcd"), 1);
assert_eq!(levenshtein_distance("abcd", "abd"), 1);
}
#[test]
fn test_levenshtein_distance_substitutions() {
assert_eq!(levenshtein_distance("abc", "xbc"), 1);
assert_eq!(levenshtein_distance("abc", "axc"), 1);
assert_eq!(levenshtein_distance("abc", "abx"), 1);
}
#[test]
fn test_levenshtein_distance_mixed_operations() {
assert_eq!(levenshtein_distance("kitten", "sitting"), 3);
assert_eq!(levenshtein_distance("saturday", "sunday"), 3);
}
#[test]
fn test_calculate_cell_distance_match() {
let matrix = vec![vec![0, 1, 2], vec![1, 0, 1], vec![2, 1, 0]];
let result = calculate_cell_distance(&matrix, 2, 2, true);
assert_eq!(result, 0); }
#[test]
fn test_calculate_cell_distance_no_match() {
let matrix = vec![vec![0, 1, 2], vec![1, 1, 2], vec![2, 2, 1]];
let result = calculate_cell_distance(&matrix, 2, 2, false);
assert_eq!(result, 2); }
#[test]
fn test_initialize_distance_matrix_small() {
let matrix = initialize_distance_matrix(2, 3);
assert_eq!(matrix.len(), 3); assert_eq!(matrix[0].len(), 4); assert_eq!(matrix[0][0], 0);
assert_eq!(matrix[0][3], 3);
assert_eq!(matrix[2][0], 2);
}
#[test]
fn test_initialize_distance_matrix_zero() {
let matrix = initialize_distance_matrix(0, 0);
assert_eq!(matrix.len(), 1);
assert_eq!(matrix[0].len(), 1);
assert_eq!(matrix[0][0], 0);
}
#[test]
fn test_suggest_no_match_far_typo() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["xyzzy".to_string()]);
let _ = result; }
#[test]
fn test_suggest_valid_command_no_suggestion() {
let suggester = CommandSuggester::new();
for cmd in [
"analyze", "generate", "scaffold", "context", "demo", "agent", "refactor", "enforce",
] {
let result = suggester.suggest_command(&[cmd.to_string()]);
assert!(
result.is_none(),
"Valid command '{}' should not get suggestion",
cmd
);
}
}
#[test]
fn test_suggest_analize_complexity_combined() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["analize".to_string(), "complexity".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze complexity"));
}
#[test]
fn test_suggest_analize_satd_combined() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["analize".to_string(), "satd".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze satd"));
}
#[test]
fn test_suggest_analize_dead_code_combined() {
let suggester = CommandSuggester::new();
let result = suggester.suggest_command(&["analize".to_string(), "dead-code".to_string()]);
assert!(result.is_some());
assert!(result.unwrap().contains("analyze dead-code"));
}
#[test]
fn test_command_suggester_main_commands_count() {
let suggester = CommandSuggester::new();
assert!(suggester.main_commands.contains(&"analyze".to_string()));
assert!(suggester.main_commands.contains(&"generate".to_string()));
assert!(suggester.main_commands.contains(&"context".to_string()));
}
#[test]
fn test_command_suggester_analyze_subcommands_count() {
let suggester = CommandSuggester::new();
assert!(suggester
.analyze_subcommands
.contains(&"complexity".to_string()));
assert!(suggester.analyze_subcommands.contains(&"satd".to_string()));
assert!(suggester
.analyze_subcommands
.contains(&"dead-code".to_string()));
assert!(suggester.analyze_subcommands.contains(&"tdg".to_string()));
}
#[test]
fn test_levenshtein_distance_unicode() {
let dist = levenshtein_distance("hello", "hëllo");
assert!(dist <= 2, "Expected distance <= 2, got {}", dist);
assert_eq!(levenshtein_distance("\u{30c6}\u{30b9}\u{30c8}", "\u{30c6}\u{30b9}\u{30c8}"), 0);
}
#[test]
fn test_levenshtein_distance_case_sensitive() {
assert_eq!(levenshtein_distance("Abc", "abc"), 1);
assert_eq!(levenshtein_distance("ABC", "abc"), 3);
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}