#![cfg_attr(coverage_nightly, coverage(off))]
use tempfile::TempDir;
use std::fs;
#[tokio::test]
async fn test_context_must_output_actual_file_content() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("example.rs");
let expected_code = r#"// This is a comment
fn greet(name: &str) {
println!("Hello, {}!", name);
}
fn main() {
greet("World");
}"#;
fs::write(&test_file, expected_code).unwrap();
let output_file = temp_dir.path().join("output.md");
let result = crate::cli::handlers::utility_handlers::handle_context(
Some("rust".to_string()),
temp_dir.path().to_path_buf(),
Some(output_file.clone()),
crate::cli::handlers::utility_handlers::ContextFormat::Markdown,
false,
false,
).await;
assert!(result.is_ok(), "Context generation failed");
let output = fs::read_to_string(output_file).unwrap();
assert!(output.contains("// This is a comment"),
"Missing comment from source code");
assert!(output.contains("fn greet(name: &str)"),
"Missing greet function signature");
assert!(output.contains("println!(\"Hello, {}!\", name)"),
"Missing println statement");
assert!(output.contains("greet(\"World\")"),
"Missing function call");
assert!(output.contains("```rust"),
"Code not in rust code block");
}
#[tokio::test]
async fn test_ast_items_have_correct_line_numbers() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("structured.rs");
let code = r#"use std::collections::HashMap;
/// Configuration for config.
pub struct Config {
name: String,
}
impl Config {
/// Create a new instance.
pub fn new(name: String) -> Self {
Config { name }
}
}
fn process_data() -> Vec<u8> {
vec![1, 2, 3]
}
/// Trait defining Handler behavior.
pub trait Handler {
fn handle(&self);
}"#;
fs::write(&test_file, code).unwrap();
let output_file = temp_dir.path().join("output.md");
let _ = crate::cli::handlers::utility_handlers::handle_context(
Some("rust".to_string()),
temp_dir.path().to_path_buf(),
Some(output_file.clone()),
crate::cli::handlers::utility_handlers::ContextFormat::Markdown,
false,
false,
).await;
let output = fs::read_to_string(output_file).unwrap();
assert!(output.contains("Config"),
"Struct Config not found in AST");
assert!(output.contains("process_data"),
"Function process_data not found in AST");
assert!(output.contains("Handler"),
"Trait Handler not found in AST");
assert!(output.contains("Struct") || output.contains("struct"),
"Struct type not identified");
assert!(output.contains("Function") || output.contains("fn"),
"Function type not identified");
assert!(output.contains("Trait") || output.contains("trait"),
"Trait type not identified");
}
#[tokio::test]
async fn test_context_shows_code_plus_analysis() {
let temp_dir = TempDir::new().unwrap();
let lib_code = r#"pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 2), 4);
}
}"#;
fs::write(temp_dir.path().join("lib.rs"), lib_code).unwrap();
let output_file = temp_dir.path().join("output.md");
let _ = crate::cli::handlers::utility_handlers::handle_context(
Some("rust".to_string()),
temp_dir.path().to_path_buf(),
Some(output_file.clone()),
crate::cli::handlers::utility_handlers::ContextFormat::Markdown,
false,
false,
).await;
let output = fs::read_to_string(output_file).unwrap();
assert!(output.contains("pub fn add(a: i32, b: i32) -> i32"),
"Missing function signature");
assert!(output.contains("a + b"),
"Missing function body");
assert!(output.contains("Functions") || output.contains("functions"),
"Missing function count");
assert!(output.contains("mod tests") || output.contains("test_add"),
"Test module not included");
}
#[tokio::test]
async fn test_json_format_includes_code() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("simple.rs");
let code = r#"fn hello() {
println!("Hello!");
}"#;
fs::write(&test_file, code).unwrap();
let output_file = temp_dir.path().join("output.json");
let result = crate::cli::handlers::utility_handlers::handle_context(
Some("rust".to_string()),
temp_dir.path().to_path_buf(),
Some(output_file.clone()),
crate::cli::handlers::utility_handlers::ContextFormat::Json,
false,
false,
).await;
assert!(result.is_ok(), "JSON context generation failed");
let output = fs::read_to_string(output_file).unwrap();
assert!(output.contains("simple.rs"),
"File name not in JSON output");
assert!(output.contains("hello"),
"Function name not in JSON output");
}
#[tokio::test]
async fn test_empty_file_handling() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("empty.rs");
fs::write(&test_file, "").unwrap();
let output_file = temp_dir.path().join("output.md");
let result = crate::cli::handlers::utility_handlers::handle_context(
Some("rust".to_string()),
temp_dir.path().to_path_buf(),
Some(output_file.clone()),
crate::cli::handlers::utility_handlers::ContextFormat::Markdown,
false,
false,
).await;
assert!(result.is_ok(), "Failed on empty file");
let output = fs::read_to_string(output_file).unwrap();
assert!(output.contains("empty.rs"), "Empty file not listed");
}
#[tokio::test]
async fn test_mixed_language_project() {
let temp_dir = TempDir::new().unwrap();
let rust_code = "fn main() { println!(\"Rust\"); }";
let python_code = "def main():\n print(\"Python\")";
let js_code = "function main() { console.log(\"JS\"); }";
fs::write(temp_dir.path().join("main.rs"), rust_code).unwrap();
fs::write(temp_dir.path().join("main.py"), python_code).unwrap();
fs::write(temp_dir.path().join("main.js"), js_code).unwrap();
let output_file = temp_dir.path().join("output.md");
let _ = crate::cli::handlers::utility_handlers::handle_context(
None, temp_dir.path().to_path_buf(),
Some(output_file.clone()),
crate::cli::handlers::utility_handlers::ContextFormat::Markdown,
false,
false,
).await;
let output = fs::read_to_string(output_file).unwrap();
assert!(output.contains("main.rs"), "Rust file missing");
assert!(output.contains("main.py"), "Python file missing");
assert!(output.contains("main.js"), "JS file missing");
assert!(output.contains("println!(\"Rust\")"), "Rust code missing");
assert!(output.contains("print(\"Python\")"), "Python code missing");
assert!(output.contains("console.log(\"JS\")"), "JS code missing");
}