use ai_code_buddy::args::{Args, OutputFormat};
use ai_code_buddy::core::ai_analyzer::{AnalysisRequest, GpuBackend, ProgressUpdate};
use ai_code_buddy::core::git::GitAnalyzer;
use ai_code_buddy::core::review::{CommitStatus, Issue, Review};
use std::fs;
use tempfile::{tempdir, TempDir};
fn create_test_git_repo() -> Result<TempDir, Box<dyn std::error::Error>> {
let dir = tempdir()?;
let repo_path = dir.path();
std::process::Command::new("git")
.arg("init")
.current_dir(repo_path)
.output()?;
fs::write(repo_path.join("test.rs"), "fn main() {}")?;
std::process::Command::new("git")
.args(["add", "."])
.current_dir(repo_path)
.output()?;
std::process::Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_path)
.output()?;
std::process::Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_path)
.output()?;
std::process::Command::new("git")
.args(["commit", "-m", "Initial commit"])
.current_dir(repo_path)
.output()?;
Ok(dir)
}
#[test]
fn test_git_analyzer_creation() {
let temp_dir = create_test_git_repo().unwrap();
let repo_path = temp_dir.path().to_str().unwrap();
let analyzer = GitAnalyzer::new(repo_path);
assert!(analyzer.is_ok());
}
#[test]
fn test_git_analyzer_get_changed_files() {
let temp_dir = create_test_git_repo().unwrap();
let repo_path = temp_dir.path().to_str().unwrap();
let analyzer = GitAnalyzer::new(repo_path).unwrap();
let result = analyzer.get_changed_files("HEAD", "HEAD");
assert!(result.is_ok());
assert_eq!(result.unwrap().len(), 0);
fs::write(temp_dir.path().join("new_file.rs"), "fn new_function() {}").unwrap();
let result = analyzer.get_changed_files("HEAD", "HEAD");
assert!(result.is_ok());
}
#[test]
fn test_git_analyzer_get_file_content() {
let temp_dir = create_test_git_repo().unwrap();
let repo_path = temp_dir.path().to_str().unwrap();
let analyzer = GitAnalyzer::new(repo_path).unwrap();
let result = analyzer.get_file_content("test.rs", "HEAD");
assert!(result.is_ok());
assert_eq!(result.unwrap(), "fn main() {}");
let result = analyzer.get_file_content("nonexistent.rs", "HEAD");
assert!(result.is_err());
}
#[test]
fn test_git_analyzer_get_uncommitted_files() {
let temp_dir = create_test_git_repo().unwrap();
let repo_path = temp_dir.path().to_str().unwrap();
let analyzer = GitAnalyzer::new(repo_path).unwrap();
let result = analyzer.get_uncommitted_files();
assert!(result.is_ok());
}
#[test]
fn test_git_analyzer_get_file_status() {
let temp_dir = create_test_git_repo().unwrap();
let repo_path = temp_dir.path().to_str().unwrap();
let analyzer = GitAnalyzer::new(repo_path).unwrap();
let result = analyzer.get_file_status("test.rs");
assert!(result.is_ok());
}
#[test]
fn test_review_structure() {
let review = Review {
files_count: 5,
issues_count: 10,
critical_issues: 1,
high_issues: 2,
medium_issues: 3,
low_issues: 4,
issues: vec![],
};
assert_eq!(review.files_count, 5);
assert_eq!(review.issues_count, 10);
assert_eq!(review.critical_issues, 1);
assert_eq!(review.high_issues, 2);
assert_eq!(review.medium_issues, 3);
assert_eq!(review.low_issues, 4);
}
#[test]
fn test_review_with_issues() {
let issues = vec![
Issue {
file: "test1.rs".to_string(),
line: 10,
severity: "High".to_string(),
category: "Security".to_string(),
description: "High severity issue".to_string(),
commit_status: CommitStatus::Modified,
},
Issue {
file: "test2.rs".to_string(),
line: 20,
severity: "Medium".to_string(),
category: "Performance".to_string(),
description: "Medium severity issue".to_string(),
commit_status: CommitStatus::Staged,
},
];
let review = Review {
files_count: 2,
issues_count: 2,
critical_issues: 0,
high_issues: 1,
medium_issues: 1,
low_issues: 0,
issues,
};
assert_eq!(review.issues.len(), 2);
assert_eq!(review.high_issues, 1);
assert_eq!(review.medium_issues, 1);
}
#[test]
fn test_args_structure() {
let args = Args {
repo_path: ".".to_string(),
source_branch: "develop".to_string(),
target_branch: "main".to_string(),
cli_mode: false,
verbose: true,
show_credits: false,
output_format: OutputFormat::Json,
exclude_patterns: vec!["*.tmp".to_string()],
include_patterns: vec!["*.rs".to_string()],
use_gpu: true,
force_cpu: false,
parallel: false,
disable_ai: false,
};
assert_eq!(args.source_branch, "develop");
assert_eq!(args.target_branch, "main");
assert_eq!(args.output_format, OutputFormat::Json);
assert!(args.use_gpu);
assert!(args.verbose);
}
#[test]
fn test_commit_status_variants() {
let variants = [
CommitStatus::Committed,
CommitStatus::Staged,
CommitStatus::Modified,
CommitStatus::Untracked,
];
for status in variants {
let issue = Issue {
file: "test.rs".to_string(),
line: 1,
severity: "Low".to_string(),
category: "Test".to_string(),
description: "Test description".to_string(),
commit_status: status,
};
assert_eq!(issue.line, 1);
}
}
#[test]
fn test_gpu_backend_display_formatting() {
assert_eq!(format!("{}", GpuBackend::Metal), "Metal");
assert_eq!(format!("{}", GpuBackend::Cuda), "CUDA");
assert_eq!(format!("{}", GpuBackend::Mkl), "MKL");
assert_eq!(format!("{}", GpuBackend::Cpu), "CPU");
}
#[test]
fn test_issue_field_access() {
let issue = Issue {
file: "src/main.rs".to_string(),
line: 42,
severity: "Critical".to_string(),
category: "Security".to_string(),
description: "Buffer overflow vulnerability".to_string(),
commit_status: CommitStatus::Modified,
};
assert_eq!(issue.file, "src/main.rs");
assert_eq!(issue.line, 42);
assert_eq!(issue.severity, "Critical");
assert_eq!(issue.category, "Security");
assert_eq!(issue.description, "Buffer overflow vulnerability");
}
#[test]
fn test_progress_update_field_access() {
let progress = ProgressUpdate {
current_file: "src/lib.rs".to_string(),
progress: 75.5,
stage: "Analyzing patterns".to_string(),
};
assert_eq!(progress.current_file, "src/lib.rs");
assert_eq!(progress.progress, 75.5);
assert_eq!(progress.stage, "Analyzing patterns");
}
#[test]
fn test_analysis_request_field_access() {
let request = AnalysisRequest {
file_path: "src/utils.rs".to_string(),
content: "pub fn utility_function() {}".to_string(),
language: "rust".to_string(),
commit_status: CommitStatus::Staged,
};
assert_eq!(request.file_path, "src/utils.rs");
assert_eq!(request.content, "pub fn utility_function() {}");
assert_eq!(request.language, "rust");
}
#[test]
fn test_output_format_variants() {
let formats = [
OutputFormat::Summary,
OutputFormat::Detailed,
OutputFormat::Json,
OutputFormat::Markdown,
];
for format in formats {
let args = Args {
repo_path: ".".to_string(),
source_branch: "main".to_string(),
target_branch: "HEAD".to_string(),
cli_mode: false,
verbose: false,
show_credits: false,
output_format: format,
exclude_patterns: vec![],
include_patterns: vec![],
use_gpu: false,
force_cpu: false,
parallel: false,
disable_ai: false,
};
matches!(
args.output_format,
OutputFormat::Summary
| OutputFormat::Detailed
| OutputFormat::Json
| OutputFormat::Markdown
);
}
}
#[test]
fn test_git_analyzer_invalid_repo() {
let result = GitAnalyzer::new("/nonexistent/path");
assert!(result.is_err());
}
#[test]
fn test_issue_serialization() {
let issue = Issue {
file: "test.rs".to_string(),
line: 123,
severity: "High".to_string(),
category: "Security".to_string(),
description: "Test issue description".to_string(),
commit_status: CommitStatus::Modified,
};
let serialized = serde_json::to_string(&issue).unwrap();
let deserialized: Issue = serde_json::from_str(&serialized).unwrap();
assert_eq!(issue.file, deserialized.file);
assert_eq!(issue.line, deserialized.line);
assert_eq!(issue.severity, deserialized.severity);
}
#[test]
fn test_review_serialization() {
let review = Review {
files_count: 3,
issues_count: 5,
critical_issues: 1,
high_issues: 2,
medium_issues: 1,
low_issues: 1,
issues: vec![],
};
let serialized = serde_json::to_string(&review).unwrap();
let deserialized: Review = serde_json::from_str(&serialized).unwrap();
assert_eq!(review.files_count, deserialized.files_count);
assert_eq!(review.issues_count, deserialized.issues_count);
assert_eq!(review.critical_issues, deserialized.critical_issues);
}