test: add tests for resolve_callee_to_symbol_id

- Test that call edges are resolved to qualified symbol IDs
- Test cross-module resolution and fan-in/fan-out metric computation
- 2 new test cases covering callee resolution functionality
This commit is contained in:
2026-02-15 13:06:05 +03:00
parent 0396a53e0c
commit 5c93cbfb3a

View File

@@ -0,0 +1,76 @@
//! Tests for resolve_callee_to_symbol_id functionality
//!
//! Verifies that call expressions are correctly resolved to qualified symbol IDs.
use std::path::Path;
use wtismycode_core::{Config, scanner::FileScanner, python_analyzer::PythonAnalyzer};
#[test]
fn test_resolve_callee_to_symbol_id() {
let config_path = "tests/golden/test_project/wtismycode.toml";
let config = Config::load_from_file(Path::new(config_path)).expect("Failed to load config");
let project_root = Path::new("tests/golden/test_project");
let scanner = FileScanner::new(config.clone());
let python_files = scanner.scan_python_files(project_root).expect("Failed to scan");
let analyzer = PythonAnalyzer::new(config);
let mut parsed_modules = Vec::new();
for file_path in python_files {
parsed_modules.push(analyzer.parse_module(&file_path).expect("Failed to parse"));
}
let model = analyzer.resolve_symbols(&parsed_modules).expect("Failed to resolve");
// Verify that symbol call edges exist and have been resolved
assert!(!model.edges.symbol_call_edges.is_empty(), "Should have symbol call edges");
// Check that at least some edges reference known symbols (resolved correctly)
let resolved_count = model.edges.symbol_call_edges.iter()
.filter(|edge| model.symbols.contains_key(&edge.to_id))
.count();
println!("Total call edges: {}", model.edges.symbol_call_edges.len());
println!("Resolved to known symbols: {}", resolved_count);
// At least some calls should resolve to known symbols
assert!(resolved_count > 0, "At least some calls should resolve to known symbol IDs");
// Verify that same-module calls are resolved with module:: prefix
for edge in &model.edges.symbol_call_edges {
assert!(edge.from_id.contains("::"), "from_id should be qualified: {}", edge.from_id);
// to_id should also be qualified (module::symbol format)
assert!(edge.to_id.contains("::"), "to_id should be qualified: {}", edge.to_id);
}
}
#[test]
fn test_callee_resolution_cross_module() {
let config_path = "tests/golden/test_project/wtismycode.toml";
let config = Config::load_from_file(Path::new(config_path)).expect("Failed to load config");
let project_root = Path::new("tests/golden/test_project");
let scanner = FileScanner::new(config.clone());
let python_files = scanner.scan_python_files(project_root).expect("Failed to scan");
let analyzer = PythonAnalyzer::new(config);
let mut parsed_modules = Vec::new();
for file_path in python_files {
parsed_modules.push(analyzer.parse_module(&file_path).expect("Failed to parse"));
}
let model = analyzer.resolve_symbols(&parsed_modules).expect("Failed to resolve");
// Check that modules have outbound/inbound relationships
let modules_with_outbound = model.modules.values()
.filter(|m| !m.outbound_modules.is_empty())
.count();
println!("Modules with outbound deps: {}", modules_with_outbound);
// Verify fan-in/fan-out metrics were computed
let symbols_with_metrics = model.symbols.values()
.filter(|s| s.metrics.fan_in > 0 || s.metrics.fan_out > 0)
.count();
println!("Symbols with non-zero metrics: {}", symbols_with_metrics);
assert!(symbols_with_metrics > 0, "Some symbols should have fan-in or fan-out > 0");
}