Files
wtismycode/wtismycode-core/tests/enhanced_analysis.rs

131 lines
5.6 KiB
Rust

//! Enhanced analysis tests for WTIsMyCode
//!
//! These tests verify that the enhanced analysis functionality works correctly
//! with complex code that includes integrations, calls, and docstrings.
use std::fs;
use std::path::Path;
use wtismycode_core::{Config, scanner::FileScanner, python_analyzer::PythonAnalyzer};
#[test]
fn test_enhanced_analysis_with_integrations() {
// Print current directory for debugging
let current_dir = std::env::current_dir().unwrap();
println!("Current directory: {:?}", current_dir);
// Try different paths for the config file
let possible_paths = [
"tests/golden/test_project/wtismycode.toml",
"../tests/golden/test_project/wtismycode.toml",
];
let config_path = possible_paths.iter().find(|&path| {
Path::new(path).exists()
}).expect("Could not find config file in any expected location");
println!("Using config path: {:?}", config_path);
let config = Config::load_from_file(Path::new(config_path)).expect("Failed to load config");
// Initialize scanner with the correct root path
let project_root = Path::new("tests/golden/test_project");
let scanner = FileScanner::new(config.clone());
// Scan for Python files
let python_files = scanner.scan_python_files(project_root)
.expect("Failed to scan Python files");
println!("Found Python files: {:?}", python_files);
// Should find both example.py and advanced_example.py
assert_eq!(python_files.len(), 2);
// Initialize Python analyzer
let analyzer = PythonAnalyzer::new(config.clone());
// Parse each Python file
let mut parsed_modules = Vec::new();
for file_path in python_files {
println!("Parsing file: {:?}", file_path);
match analyzer.parse_module(&file_path) {
Ok(module) => {
println!("Successfully parsed module: {:?}", module.module_path);
println!("Imports: {:?}", module.imports);
println!("Symbols: {:?}", module.symbols.len());
println!("Calls: {:?}", module.calls.len());
parsed_modules.push(module);
},
Err(e) => {
panic!("Failed to parse {}: {}", file_path.display(), e);
}
}
}
println!("Parsed {} modules", parsed_modules.len());
// Resolve symbols and build project model
let project_model = analyzer.resolve_symbols(&parsed_modules)
.expect("Failed to resolve symbols");
println!("Project model modules: {}", project_model.modules.len());
println!("Project model files: {}", project_model.files.len());
println!("Project model symbols: {}", project_model.symbols.len());
// Add assertions to verify the project model
assert!(!project_model.modules.is_empty());
assert!(!project_model.files.is_empty());
assert!(!project_model.symbols.is_empty());
// Check that we have the right number of modules (2 files = 2 modules)
assert_eq!(project_model.modules.len(), 2);
// Check that we have the right number of files
assert_eq!(project_model.files.len(), 2);
// Check that we have the right number of symbols
// The actual number might be less due to deduplication or other factors
// but should be at least the sum of symbols from both files minus duplicates
assert!(project_model.symbols.len() >= 10);
// Check specific details about the advanced example module
let mut found_advanced_module = false;
for (_, module) in project_model.modules.iter() {
if module.path.contains("advanced_example.py") {
found_advanced_module = true;
break;
}
}
assert!(found_advanced_module);
// Check that we found the UserService class with DB integration
let user_service_symbol = project_model.symbols.values().find(|s| s.id.ends_with("::UserService"));
assert!(user_service_symbol.is_some());
assert_eq!(user_service_symbol.unwrap().kind, wtismycode_core::model::SymbolKind::Class);
// Check that we found the NotificationService class with queue integration
let notification_service_symbol = project_model.symbols.values().find(|s| s.id.ends_with("::NotificationService"));
assert!(notification_service_symbol.is_some());
assert_eq!(notification_service_symbol.unwrap().kind, wtismycode_core::model::SymbolKind::Class);
// Check that we found the fetch_external_user_data function with HTTP integration
let fetch_external_user_data_symbol = project_model.symbols.values().find(|s| s.id.ends_with("::fetch_external_user_data"));
assert!(fetch_external_user_data_symbol.is_some());
assert_eq!(fetch_external_user_data_symbol.unwrap().kind, wtismycode_core::model::SymbolKind::Function);
// Check file imports
let mut found_advanced_file = false;
for (_, file_doc) in project_model.files.iter() {
if file_doc.path.contains("advanced_example.py") {
found_advanced_file = true;
assert!(!file_doc.imports.is_empty());
// Should have imports for requests, sqlite3, redis, typing
let import_names: Vec<&String> = file_doc.imports.iter().collect();
assert!(import_names.contains(&&"requests".to_string()));
assert!(import_names.contains(&&"sqlite3".to_string()));
assert!(import_names.contains(&&"redis".to_string()));
assert!(import_names.contains(&&"typing.List".to_string()) || import_names.contains(&&"typing".to_string()));
break;
}
}
assert!(found_advanced_file);
}