feat: project symbol extraction integration test
- extract_project_symbols against tempdir with Rust/TypeScript/Python sources — walk_directory, detect_language, hidden/vendor dir skipping, ProjectSymbol field population, docstring extraction
This commit is contained in:
@@ -5884,6 +5884,96 @@ mod research_extended_tests {
|
||||
assert_eq!(total_calls, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_project_symbols_from_sol_src() {
|
||||
// Point at Sol's own src/context.rs — small, known content
|
||||
use crate::code_index::symbols;
|
||||
|
||||
let dir = tempfile::TempDir::new().unwrap();
|
||||
let src = dir.path().join("src");
|
||||
std::fs::create_dir_all(&src).unwrap();
|
||||
|
||||
// Write a small Rust file
|
||||
std::fs::write(src.join("lib.rs"), r#"
|
||||
/// A greeting function.
|
||||
pub fn hello(name: &str) -> String {
|
||||
format!("Hello, {name}!")
|
||||
}
|
||||
|
||||
/// A simple struct.
|
||||
pub struct Config {
|
||||
pub name: String,
|
||||
pub port: u16,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Self {
|
||||
Self { name: "test".into(), port: 8080 }
|
||||
}
|
||||
}
|
||||
"#).unwrap();
|
||||
|
||||
// Write a TypeScript file
|
||||
std::fs::write(src.join("app.ts"), r#"
|
||||
/** Main application entry point. */
|
||||
export function main(): void {
|
||||
console.log("hello");
|
||||
}
|
||||
|
||||
/** User interface. */
|
||||
export interface User {
|
||||
name: string;
|
||||
email: string;
|
||||
}
|
||||
"#).unwrap();
|
||||
|
||||
// Write a Python file
|
||||
std::fs::write(src.join("util.py"), r#"
|
||||
"""Utility functions."""
|
||||
|
||||
def add(a: int, b: int) -> int:
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
class Calculator:
|
||||
"""A simple calculator."""
|
||||
def multiply(self, a: int, b: int) -> int:
|
||||
return a * b
|
||||
"#).unwrap();
|
||||
|
||||
// Also write a file that should be skipped (hidden dir, node_modules)
|
||||
let hidden = dir.path().join(".hidden");
|
||||
std::fs::create_dir_all(&hidden).unwrap();
|
||||
std::fs::write(hidden.join("secret.rs"), "pub fn secret() {}").unwrap();
|
||||
|
||||
let nm = dir.path().join("node_modules");
|
||||
std::fs::create_dir_all(&nm).unwrap();
|
||||
std::fs::write(nm.join("dep.ts"), "export function dep() {}").unwrap();
|
||||
|
||||
let symbols = symbols::extract_project_symbols(dir.path().to_str().unwrap());
|
||||
|
||||
// Should find symbols from all 3 source files
|
||||
let names: Vec<&str> = symbols.iter().map(|s| s.name.as_str()).collect();
|
||||
assert!(names.contains(&"hello"), "Should find Rust function 'hello'");
|
||||
assert!(names.contains(&"Config"), "Should find Rust struct 'Config'");
|
||||
assert!(names.contains(&"main"), "Should find TS function 'main'");
|
||||
assert!(names.contains(&"add"), "Should find Python function 'add'");
|
||||
assert!(names.contains(&"Calculator"), "Should find Python class 'Calculator'");
|
||||
|
||||
// Should NOT find hidden/vendor files
|
||||
assert!(!names.contains(&"secret"), "Should skip hidden directory");
|
||||
assert!(!names.contains(&"dep"), "Should skip node_modules");
|
||||
|
||||
// Verify ProjectSymbol fields
|
||||
let hello = symbols.iter().find(|s| s.name == "hello").unwrap();
|
||||
assert_eq!(hello.language, "rust");
|
||||
assert_eq!(hello.kind, "function");
|
||||
assert!(hello.signature.contains("pub fn hello"));
|
||||
assert!(hello.docstring.contains("greeting"));
|
||||
assert!(hello.file_path.contains("lib.rs"));
|
||||
assert!(!hello.content.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_research_execute_single_task() {
|
||||
let env_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(".env");
|
||||
|
||||
Reference in New Issue
Block a user