use crate::io::file_manager::RealFileBufferManager;
use crate::mcp_server::tools::lsp_helpers::{
definitions::{get_declarations, get_definitions},
symbol_resolution::get_matching_symbol,
};
use crate::project::{ProjectScanner, WorkspaceSession};
use crate::test_utils::{DEFAULT_INDEXING_TIMEOUT, integration::TestProject};
use tracing::info;
#[cfg(feature = "clangd-integration-tests")]
#[tokio::test]
async fn test_definitions_class_symbol() {
let test_project = TestProject::new().await.unwrap();
test_project.cmake_configure().await.unwrap();
let scanner = ProjectScanner::with_default_providers();
let workspace = scanner
.scan_project(&test_project.project_root, 3, None)
.expect("Failed to scan test project");
let clangd_path = crate::test_utils::get_test_clangd_path();
let workspace_session = WorkspaceSession::new(workspace.clone(), clangd_path)
.expect("Failed to create workspace session");
let component_session = workspace_session
.get_component_session(test_project.build_dir.clone())
.await
.unwrap();
component_session
.ensure_indexed(DEFAULT_INDEXING_TIMEOUT)
.await
.unwrap();
let symbol = get_matching_symbol("Math", &component_session)
.await
.expect("Failed to find Math symbol");
let definitions = get_definitions(&symbol.location, &component_session)
.await
.expect("Failed to get definitions");
assert!(!definitions.is_empty());
info!("Found {} definitions for Math class", definitions.len());
for (i, definition) in definitions.iter().enumerate() {
info!(
"Definition {}: {} at {}:{}",
i + 1,
definition.to_compact_range(),
definition.file_path.display(),
definition.range.start.line + 1
);
assert!(
definition.file_path.to_string_lossy().contains("Math")
|| definition.file_path.to_string_lossy().contains("math")
);
}
}
#[cfg(feature = "clangd-integration-tests")]
#[tokio::test]
async fn test_declarations_class_symbol() {
let test_project = TestProject::new().await.unwrap();
test_project.cmake_configure().await.unwrap();
let scanner = ProjectScanner::with_default_providers();
let workspace = scanner
.scan_project(&test_project.project_root, 3, None)
.expect("Failed to scan test project");
let clangd_path = crate::test_utils::get_test_clangd_path();
let workspace_session = WorkspaceSession::new(workspace.clone(), clangd_path)
.expect("Failed to create workspace session");
let component_session = workspace_session
.get_component_session(test_project.build_dir.clone())
.await
.unwrap();
component_session
.ensure_indexed(DEFAULT_INDEXING_TIMEOUT)
.await
.unwrap();
let symbol = get_matching_symbol("Math", &component_session)
.await
.expect("Failed to find Math symbol");
let declarations = get_declarations(&symbol.location, &component_session)
.await
.expect("Failed to get declarations");
assert!(!declarations.is_empty());
info!("Found {} declarations for Math class", declarations.len());
for (i, declaration) in declarations.iter().enumerate() {
info!(
"Declaration {}: {} at {}:{}",
i + 1,
declaration.to_compact_range(),
declaration.file_path.display(),
declaration.range.start.line + 1
);
assert!(
declaration.file_path.to_string_lossy().contains("Math")
|| declaration.file_path.to_string_lossy().contains("math")
);
}
}
#[cfg(feature = "clangd-integration-tests")]
#[tokio::test]
async fn test_definitions_function_symbol() {
let test_project = TestProject::new().await.unwrap();
test_project.cmake_configure().await.unwrap();
let scanner = ProjectScanner::with_default_providers();
let workspace = scanner
.scan_project(&test_project.project_root, 3, None)
.expect("Failed to scan test project");
let clangd_path = crate::test_utils::get_test_clangd_path();
let workspace_session = WorkspaceSession::new(workspace.clone(), clangd_path)
.expect("Failed to create workspace session");
let component_session = workspace_session
.get_component_session(test_project.build_dir.clone())
.await
.unwrap();
component_session
.ensure_indexed(DEFAULT_INDEXING_TIMEOUT)
.await
.unwrap();
let mut file_buffer_manager = RealFileBufferManager::new_real();
let symbol = get_matching_symbol("factorial", &component_session)
.await
.expect("Failed to find factorial symbol");
let definitions = get_definitions(&symbol.location, &component_session)
.await
.expect("Failed to get definitions");
assert!(!definitions.is_empty());
info!(
"Found {} definitions for factorial function",
definitions.len()
);
for (i, definition) in definitions.iter().enumerate() {
let buffer = file_buffer_manager
.get_buffer(&definition.file_path)
.expect("Failed to get file buffer");
let line_content = buffer
.get_line(definition.range.start.line)
.expect("Failed to get line content");
info!(
"Definition {}: {} at {}:{}",
i + 1,
line_content.trim(),
definition.file_path.display(),
definition.range.start.line
);
assert!(line_content.contains("factorial") || line_content.contains("Math::factorial"));
}
}
#[cfg(feature = "clangd-integration-tests")]
#[tokio::test]
async fn test_definitions_method_symbol() {
let test_project = TestProject::new().await.unwrap();
test_project.cmake_configure().await.unwrap();
let scanner = ProjectScanner::with_default_providers();
let workspace = scanner
.scan_project(&test_project.project_root, 3, None)
.expect("Failed to scan test project");
let clangd_path = crate::test_utils::get_test_clangd_path();
let workspace_session = WorkspaceSession::new(workspace.clone(), clangd_path)
.expect("Failed to create workspace session");
let component_session = workspace_session
.get_component_session(test_project.build_dir.clone())
.await
.unwrap();
component_session
.ensure_indexed(DEFAULT_INDEXING_TIMEOUT)
.await
.unwrap();
let mut file_buffer_manager = RealFileBufferManager::new_real();
let symbol = get_matching_symbol("Math::Complex::add", &component_session)
.await
.expect("Failed to find add method symbol");
let definitions = get_definitions(&symbol.location, &component_session)
.await
.expect("Failed to get definitions");
assert!(!definitions.is_empty());
info!("Found {} definitions for add method", definitions.len());
for (i, definition) in definitions.iter().enumerate() {
let buffer = file_buffer_manager
.get_buffer(&definition.file_path)
.expect("Failed to get file buffer");
let line_content = buffer
.get_line(definition.range.start.line)
.expect("Failed to get line content");
info!(
"Definition {}: {} at {}:{}",
i + 1,
line_content.trim(),
definition.file_path.display(),
definition.range.start.line
);
assert!(line_content.contains("add"));
}
}