use oli_server::tools::code::parser::CodeParser;
use std::fs;
use tempfile::tempdir;
#[test]
fn test_generate_llm_friendly_ast() {
if std::env::var("SKIP_INTEGRATION").is_ok() {
return;
}
let temp_dir = tempfile::tempdir().unwrap();
let rust_file_path = temp_dir.path().join("test.rs");
std::fs::write(
&rust_file_path,
r#"
struct TestStruct {
field1: i32,
field2: String,
}
fn main() {
println!("Hello, world!");
}
"#,
)
.unwrap();
let mut parser = CodeParser::new().expect("Failed to create CodeParser");
let query = "Show me the TestStruct implementation";
let ast_data = parser
.generate_llm_friendly_ast(temp_dir.path(), query)
.expect("Failed to generate AST");
assert!(ast_data.contains("Code Structure Analysis"));
assert!(ast_data.contains("Query:"));
assert!(ast_data.contains("test.rs"));
assert!(ast_data.contains("TestStruct"));
assert!(ast_data.contains("AST Summary"));
assert!(ast_data.contains("Analyzed"));
temp_dir.close().unwrap();
}
#[test]
fn test_parse_codebase() {
if std::env::var("SKIP_INTEGRATION").is_ok() {
return;
}
let temp_dir = tempfile::tempdir().unwrap();
let rust_file_path = temp_dir.path().join("code_parser_test.rs");
std::fs::write(
&rust_file_path,
r#"
struct CodeParser {
languages: HashMap<String, Vec<String>>,
parser: Parser,
}
impl CodeParser {
pub fn new() -> Result<Self> {
Ok(Self {
languages: HashMap::new(),
parser: Parser::new(),
})
}
pub fn parse_file(&mut self, path: &Path) -> Result<CodeAST> {
// Implementation...
todo!()
}
}
"#,
)
.unwrap();
let mut parser = CodeParser::new().expect("Failed to create CodeParser");
let query = "Show me the CodeParser implementation";
let asts = parser
.parse_codebase(temp_dir.path(), query)
.expect("Failed to parse codebase");
assert!(!asts.is_empty(), "Expected to find at least one file");
let found_code_parser = asts.iter().any(|ast| {
ast.path.contains("code_parser_test.rs")
|| (ast.language == "rust"
&& ast.children.iter().any(|child| {
child
.name
.as_ref()
.is_some_and(|name| name.contains("CodeParser"))
}))
});
assert!(
found_code_parser,
"Did not find CodeParser in the parsed AST"
);
temp_dir.close().unwrap();
}
#[test]
fn test_parse_file_with_tree_sitter() {
if std::env::var("SKIP_INTEGRATION").is_ok() {
return;
}
let temp_dir = tempfile::tempdir().unwrap();
let rust_file_path = temp_dir.path().join("test_tree_sitter.rs");
std::fs::write(
&rust_file_path,
r#"
struct TestStruct {
field1: i32,
field2: String,
}
impl TestStruct {
fn new() -> Self {
Self {
field1: 0,
field2: String::new(),
}
}
}
fn main() {
let test = TestStruct::new();
println!("Test program");
}
"#,
)
.unwrap();
let mut parser = CodeParser::new().expect("Failed to create CodeParser");
let ast = parser
.parse_file(&rust_file_path)
.expect("Failed to parse file");
assert_eq!(ast.kind, "file");
assert_eq!(ast.language, "rust");
assert!(!ast.children.is_empty(), "Expected to find AST nodes");
let struct_nodes: Vec<_> = ast
.children
.iter()
.filter(|node| node.kind == "struct" || node.kind == "struct_item")
.collect();
let function_nodes: Vec<_> = ast
.children
.iter()
.filter(|node| node.kind == "function" || node.kind == "function_item")
.collect();
assert!(
!struct_nodes.is_empty() || !function_nodes.is_empty(),
"Expected to find either struct or function nodes"
);
temp_dir.close().unwrap();
}
#[test]
fn test_parse_javascript_file() {
if std::env::var("SKIP_INTEGRATION").is_ok() {
return;
}
let temp_dir = tempdir().unwrap();
let file_path = temp_dir.path().join("test.js");
fs::write(
&file_path,
r#"
class TestClass {
constructor(value) {
this.value = value;
}
getValue() {
return this.value;
}
}
function testFunction() {
return "test";
}
const arrowFunc = () => {
return "arrow";
};
const obj = {
method() {
return this;
}
};
export const exportedVar = 42;
"#,
)
.unwrap();
let mut parser = CodeParser::new().unwrap();
let ast = parser.parse_file(&file_path).unwrap();
assert_eq!(ast.language, "javascript");
assert_eq!(ast.kind, "file");
let child_kinds: Vec<_> = ast.children.iter().map(|c| c.kind.as_str()).collect();
assert!(
child_kinds.contains(&"class") || child_kinds.contains(&"class_declaration"),
"Expected to find class declarations"
);
temp_dir.close().unwrap();
}
#[test]
fn test_extract_search_terms() {
let parser = CodeParser::new().unwrap();
let terms = parser.extract_search_terms("Find the TestStruct implementation");
assert!(terms.contains(&"TestStruct".to_string()));
let terms = parser.extract_search_terms("How does the parse_file function work?");
assert!(terms.contains(&"parse_file".to_string()));
let terms = parser.extract_search_terms("Show me how CodeParser uses tree_sitter");
assert!(terms.contains(&"CodeParser".to_string()));
assert!(terms.contains(&"tree_sitter".to_string()));
let terms = parser.extract_search_terms("Show me the function and class definitions");
assert!(!terms.contains(&"function".to_string()));
assert!(!terms.contains(&"class".to_string()));
}
#[test]
fn test_determine_relevant_files() {
let parser = CodeParser::new().unwrap();
let patterns = parser.determine_relevant_files("Check 'main.rs' for the entry point");
assert!(patterns.iter().any(|p| p.contains("main.rs")));
let patterns = parser.determine_relevant_files("Show me the Rust code structure");
assert!(patterns.iter().any(|p| p.ends_with(".rs")));
let patterns = parser.determine_relevant_files("Analyze JavaScript components");
assert!(
patterns.iter().any(|p| p.ends_with(".js")) || patterns.iter().any(|p| p.ends_with(".jsx"))
);
let patterns = parser.determine_relevant_files("Parse Python classes");
assert!(patterns.iter().any(|p| p.ends_with(".py")));
}
#[test]
fn test_parallel_processing() {
if std::env::var("SKIP_INTEGRATION").is_ok() {
return;
}
let temp_dir = tempdir().unwrap();
let file1_path = temp_dir.path().join("file1.rs");
fs::write(&file1_path, "struct File1 { field: i32 }").unwrap();
let file2_path = temp_dir.path().join("file2.rs");
fs::write(&file2_path, "struct File2 { field: i32 }").unwrap();
let file3_path = temp_dir.path().join("file3.rs");
fs::write(&file3_path, "struct File3 { field: i32 }").unwrap();
let subdir_path = temp_dir.path().join("subdir");
fs::create_dir(&subdir_path).unwrap();
let file4_path = subdir_path.join("file4.rs");
fs::write(&file4_path, "struct File4 { field: i32 }").unwrap();
let mut parser = CodeParser::new().unwrap();
let query = "Find all structs";
let asts = parser.parse_codebase(temp_dir.path(), query).unwrap();
assert!(!asts.is_empty(), "Expected to find at least some files");
temp_dir.close().unwrap();
}