#[cfg(feature = "ast")]
mod ast_tests {
use car_memgine::MemgineEngine;
use std::path::Path;
#[test]
fn ingest_car_ast_crate() {
let mut engine = MemgineEngine::new(None);
let ast_src = Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.join("car-ast/src");
let count = engine.ingest_codebase(&ast_src);
assert!(
count >= 20,
"expected >= 20 symbols from car-ast, got {}",
count
);
assert_eq!(engine.code_symbol_count(), count);
let results = engine.query_code_symbols("ParsedFile", 10);
assert!(!results.is_empty(), "should find ParsedFile in graph");
let names: Vec<_> = results.iter().map(|r| r.0.name.as_str()).collect();
assert!(
names.contains(&"ParsedFile"),
"results should include ParsedFile, got {:?}",
names
);
let results = engine.query_code_symbols("extract", 10);
assert!(!results.is_empty(), "should find extract functions");
let results = engine.query_code_symbols("Span", 10);
assert!(!results.is_empty(), "should find Span");
println!("Ingested {} symbols from car-ast/src", count);
println!("Top results for 'ParsedFile':");
for (meta, score) in engine.query_code_symbols("ParsedFile", 5) {
println!(
" [{:.3}] {} {} ({}:{})",
score, meta.kind, meta.name, meta.file_path, meta.start_line
);
}
}
#[test]
fn ingest_and_query_graph_traversal() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(
dir.path().join("models.rs"),
r#"
pub struct User {
pub id: u64,
pub name: String,
}
impl User {
pub fn new(id: u64, name: String) -> Self {
Self { id, name }
}
pub fn display_name(&self) -> &str {
&self.name
}
}
pub struct UserStore {
users: Vec<User>,
}
impl UserStore {
pub fn new() -> Self {
Self { users: Vec::new() }
}
pub fn add(&mut self, user: User) {
self.users.push(user);
}
pub fn find_by_id(&self, id: u64) -> Option<&User> {
self.users.iter().find(|u| u.id == id)
}
}
"#,
)
.unwrap();
std::fs::write(
dir.path().join("handler.rs"),
r#"
use crate::models::{User, UserStore};
pub fn handle_create_user(store: &mut UserStore, id: u64, name: &str) {
let user = User::new(id, name.to_string());
store.add(user);
}
pub fn handle_get_user(store: &UserStore, id: u64) -> Option<String> {
store.find_by_id(id).map(|u| u.display_name().to_string())
}
"#,
)
.unwrap();
let mut engine = MemgineEngine::new(None);
let count = engine.ingest_codebase(dir.path());
assert!(count >= 8, "expected >= 8 symbols, got {}", count);
let results = engine.query_code_symbols("User", 10);
assert!(!results.is_empty());
let results = engine.query_code_symbols("handle", 10);
let names: Vec<_> = results.iter().map(|r| r.0.name.as_str()).collect();
assert!(
names.iter().any(|n| n.starts_with("handle_")),
"should find handler functions, got {:?}",
names
);
}
}