#![cfg(feature = "sqlite")]
use splice::graph::magellan_integration::{
CodeChunk, MagellanIntegration, SymbolInfo, SymbolWithRelations,
};
use std::fs;
use std::path::{Path, PathBuf};
use tempfile::TempDir;
fn create_temp_magellan_db() -> TempDir {
TempDir::new().expect("Failed to create temp directory")
}
fn create_sample_rust_file(dir: &Path) -> PathBuf {
let file_path = dir.join("sample_rust.rs");
let content = r#"
// Sample Rust file for testing Magellan integration
/// Documentation comment
pub struct MyStruct {
pub field1: i32,
pub field2: String,
}
impl MyStruct {
/// Create a new instance
pub fn new(field1: i32, field2: String) -> Self {
Self { field1, field2 }
}
/// Get field1 value
pub fn get_field1(&self) -> i32 {
self.field1
}
}
/// A public trait
pub trait MyTrait {
/// Required method
fn do_something(&self) -> i32;
}
/// Implementation of the trait
impl MyTrait for MyStruct {
fn do_something(&self) -> i32 {
self.field1
}
}
/// A public function
pub fn my_function(x: i32, y: i32) -> i32 {
x + y
}
/// A private module
mod private_module {
pub fn internal_function() -> i32 {
42
}
}
/// A public enum
pub enum MyEnum {
Variant1,
Variant2(i32),
Variant3 { x: i32, y: i32 },
}
"#;
fs::write(&file_path, content).expect("Failed to write sample Rust file");
file_path
}
fn create_sample_python_file(dir: &Path) -> PathBuf {
let file_path = dir.join("sample_python.py");
let content = r#"
# Sample Python file for testing Magellan integration
class MyClass:
"""A simple class."""
def __init__(self, value):
self.value = value
def get_value(self):
return self.value
async def async_method(self):
return await self.some_async_operation()
@staticmethod
def static_method():
return 42
def my_function(x, y):
return x + y
async def my_async_function():
await some_operation()
"#;
fs::write(&file_path, content).expect("Failed to write sample Python file");
file_path
}
fn create_sample_c_file(dir: &Path) -> PathBuf {
let file_path = dir.join("sample_c.c");
let content = r#"
#include <stdio.h>
struct MyStruct {
int field1;
int field2;
};
typedef struct {
int x;
int y;
} Point;
int my_function(int x, int y) {
return x + y;
}
void process_struct(struct MyStruct* s) {
s->field1 = 42;
}
"#;
fs::write(&file_path, content).expect("Failed to write sample C file");
file_path
}
fn create_sample_cpp_file(dir: &Path) -> PathBuf {
let file_path = dir.join("sample_cpp.cpp");
let content = r#"
#include <iostream>
class MyClass {
public:
MyClass(int value) : value(value) {}
int getValue() const {
return value;
}
void setValue(int value) {
this->value = value;
}
private:
int value;
};
namespace MyNamespace {
class NamespacedClass {
public:
void method();
};
}
template<typename T>
class TemplateClass {
public:
T get_value() {
return value;
}
private:
T value;
};
"#;
fs::write(&file_path, content).expect("Failed to write sample C++ file");
file_path
}
fn create_sample_java_file(dir: &Path) -> PathBuf {
let file_path = dir.join("SampleJava.java");
let content = r#"
public class SampleJava {
private int value;
public SampleJava(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
private void helperMethod() {
System.out.println("Helper");
}
interface MyInterface {
void doSomething();
}
static class InnerClass {
public void innerMethod() {
}
}
}
"#;
fs::write(&file_path, content).expect("Failed to write sample Java file");
file_path
}
fn create_sample_javascript_file(dir: &Path) -> PathBuf {
let file_path = dir.join("sample_javascript.js");
let content = r#"
// Sample JavaScript file for testing
class MyClass {
constructor(value) {
this.value = value;
}
getValue() {
return this.value;
}
async asyncMethod() {
await someOperation();
return this.value;
}
}
function myFunction(x, y) {
return x + y;
}
const arrowFunction = (x, y) => x + y;
class AnotherClass extends MyClass {
constructor(value) {
super(value);
}
getValue() {
return super.getValue() * 2;
}
}
"#;
fs::write(&file_path, content).expect("Failed to write sample JavaScript file");
file_path
}
fn create_sample_typescript_file(dir: &Path) -> PathBuf {
let file_path = dir.join("sample_typescript.ts");
let content = r#"
// Sample TypeScript file for testing
interface MyInterface {
getValue(): number;
setValue(value: number): void;
}
class MyClass implements MyInterface {
private value: number;
constructor(value: number) {
this.value = value;
}
public getValue(): number {
return this.value;
}
public setValue(value: number): void {
this.value = value;
}
}
type MyType = string | number;
interface GenericInterface<T> {
get(): T;
set(value: T): void;
}
class GenericClass<T> implements GenericInterface<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
get(): T {
return this.value;
}
set(value: T): void {
this.value = value;
}
}
"#;
fs::write(&file_path, content).expect("Failed to write sample TypeScript file");
file_path
}
fn create_multilang_workspace(dir: &Path) -> Vec<PathBuf> {
vec![
create_sample_rust_file(dir),
create_sample_python_file(dir),
create_sample_c_file(dir),
create_sample_cpp_file(dir),
create_sample_java_file(dir),
create_sample_javascript_file(dir),
create_sample_typescript_file(dir),
]
}
fn count_symbols_by_label(db: &MagellanIntegration, label: &str) -> usize {
db.count_by_label(label).unwrap_or(0)
}
fn verify_code_chunk(
db: &MagellanIntegration,
file: &Path,
start: usize,
end: usize,
expected_substring: &str,
) -> bool {
match db.get_code_chunk(file, start, end) {
Ok(Some(chunk)) => chunk.content.contains(expected_substring),
_ => false,
}
}
#[test]
fn test_temp_db_creation() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let db = MagellanIntegration::open(&db_path);
assert!(db.is_ok(), "Failed to open Magellan database");
let db = db.unwrap();
let results = db.query_by_labels(&["rust"]);
assert!(results.is_ok(), "Query failed on empty database");
assert!(
results.unwrap().is_empty(),
"Empty database should have no results"
);
}
#[test]
fn test_sample_file_creation() {
let temp_dir = create_temp_magellan_db();
let rust_file = create_sample_rust_file(temp_dir.path());
assert!(rust_file.exists(), "Sample Rust file should exist");
let content = fs::read_to_string(&rust_file).unwrap();
assert!(
content.contains("pub struct MyStruct"),
"File should contain struct"
);
assert!(
content.contains("pub fn my_function"),
"File should contain function"
);
assert!(
content.contains("pub trait MyTrait"),
"File should contain trait"
);
assert!(
content.contains("pub enum MyEnum"),
"File should contain enum"
);
}
#[test]
fn test_multilang_workspace_creation() {
let temp_dir = create_temp_magellan_db();
let files = create_multilang_workspace(temp_dir.path());
assert_eq!(files.len(), 7, "Should create 7 language files");
for file in &files {
assert!(file.exists(), "File {:?} should exist", file);
}
let extensions: Vec<_> = files
.iter()
.filter_map(|f| f.extension())
.map(|e| e.to_string_lossy().to_string())
.collect();
assert!(
extensions.contains(&"rs".to_string()),
"Should have .rs file"
);
assert!(
extensions.contains(&"py".to_string()),
"Should have .py file"
);
assert!(extensions.contains(&"c".to_string()), "Should have .c file");
assert!(
extensions.contains(&"cpp".to_string()),
"Should have .cpp file"
);
assert!(
extensions.contains(&"java".to_string()),
"Should have .java file"
);
assert!(
extensions.contains(&"js".to_string()),
"Should have .js file"
);
assert!(
extensions.contains(&"ts".to_string()),
"Should have .ts file"
);
}
#[test]
fn test_helper_count_by_label() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let db = MagellanIntegration::open(&db_path).unwrap();
let count = count_symbols_by_label(&db, "rust");
assert_eq!(count, 0, "Empty database should have 0 symbols");
let count = count_symbols_by_label(&db, "nonexistent");
assert_eq!(count, 0, "Non-existent label should have 0 symbols");
}
#[test]
fn test_index_rust_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
let symbol_count = db.index_file(&rust_file);
assert!(symbol_count.is_ok(), "Indexing should succeed");
let count = symbol_count.unwrap();
assert!(count > 0, "Should index at least some symbols");
let rust_symbols = db.query_by_labels(&["rust"]).unwrap();
assert!(!rust_symbols.is_empty(), "Should find Rust symbols");
let structs = db.query_by_labels(&["rust", "struct"]).unwrap();
assert!(!structs.is_empty(), "Should find Rust structs");
let functions = db.query_by_labels(&["rust", "fn"]).unwrap();
assert!(!functions.is_empty(), "Should find Rust functions");
let traits = db.query_by_labels(&["rust", "trait"]).unwrap();
assert!(!traits.is_empty(), "Should find Rust traits");
let enums = db.query_by_labels(&["rust", "enum"]).unwrap();
assert!(!enums.is_empty(), "Should find Rust enums");
}
#[test]
fn test_index_python_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let python_file = create_sample_python_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
let symbol_count = db.index_file(&python_file);
assert!(symbol_count.is_ok(), "Indexing should succeed");
let count = symbol_count.unwrap();
assert!(count > 0, "Should index at least some symbols");
let python_symbols = db.query_by_labels(&["python"]).unwrap();
assert!(!python_symbols.is_empty(), "Should find Python symbols");
let classes = db.query_by_labels(&["python", "class"]).unwrap();
let _ = classes;
let functions = db.query_by_labels(&["python", "fn"]).unwrap();
let _ = functions;
}
#[test]
fn test_index_c_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let c_file = create_sample_c_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
let symbol_count = db.index_file(&c_file);
assert!(symbol_count.is_ok(), "Indexing should succeed");
let count = symbol_count.unwrap();
assert!(count > 0, "Should index at least some symbols");
let c_symbols = db.query_by_labels(&["c"]).unwrap();
assert!(!c_symbols.is_empty(), "Should find C symbols");
let structs = db.query_by_labels(&["c", "struct"]).unwrap();
assert!(!structs.is_empty(), "Should find C structs");
let functions = db.query_by_labels(&["c", "fn"]).unwrap();
assert!(!functions.is_empty(), "Should find C functions");
}
#[test]
fn test_index_cpp_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let cpp_file = create_sample_cpp_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
let symbol_count = db.index_file(&cpp_file);
assert!(symbol_count.is_ok(), "Indexing should succeed");
let count = symbol_count.unwrap();
assert!(count > 0, "Should index at least some symbols");
let cpp_symbols = db.query_by_labels(&["cpp"]).unwrap();
assert!(!cpp_symbols.is_empty(), "Should find C++ symbols");
let classes = db.query_by_labels(&["cpp", "class"]).unwrap();
let _ = classes;
let namespaces = db.query_by_labels(&["cpp", "namespace"]).unwrap();
let _ = namespaces;
}
#[test]
fn test_index_java_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let java_file = create_sample_java_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
let symbol_count = db.index_file(&java_file);
assert!(symbol_count.is_ok(), "Indexing should succeed");
let count = symbol_count.unwrap();
assert!(count > 0, "Should index at least some symbols");
let java_symbols = db.query_by_labels(&["java"]).unwrap();
assert!(!java_symbols.is_empty(), "Should find Java symbols");
let classes = db.query_by_labels(&["java", "class"]).unwrap();
let _ = classes;
let interfaces = db.query_by_labels(&["java", "interface"]).unwrap();
let _ = interfaces;
}
#[test]
fn test_index_javascript_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let js_file = create_sample_javascript_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
let symbol_count = db.index_file(&js_file);
assert!(symbol_count.is_ok(), "Indexing should succeed");
let count = symbol_count.unwrap();
assert!(count > 0, "Should index at least some symbols");
let js_symbols = db.query_by_labels(&["javascript"]).unwrap();
assert!(!js_symbols.is_empty(), "Should find JavaScript symbols");
let classes = db.query_by_labels(&["javascript", "class"]).unwrap();
let _ = classes;
let functions = db.query_by_labels(&["javascript", "fn"]).unwrap();
let _ = functions;
}
#[test]
fn test_index_typescript_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let ts_file = create_sample_typescript_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
let symbol_count = db.index_file(&ts_file);
assert!(symbol_count.is_ok(), "Indexing should succeed");
let count = symbol_count.unwrap();
assert!(count > 0, "Should index at least some symbols");
let ts_symbols = db.query_by_labels(&["typescript"]).unwrap();
assert!(!ts_symbols.is_empty(), "Should find TypeScript symbols");
let interfaces = db.query_by_labels(&["typescript", "interface"]).unwrap();
let _ = interfaces;
let classes = db.query_by_labels(&["typescript", "class"]).unwrap();
let _ = classes;
}
#[test]
fn test_query_by_single_label() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let files = create_multilang_workspace(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
for file in &files {
db.index_file(file).unwrap();
}
let rust_symbols = db.query_by_labels(&["rust"]).unwrap();
assert!(!rust_symbols.is_empty(), "Should find Rust symbols");
for sym in &rust_symbols {
assert!(
sym.file_path.contains("sample_rust.rs") || sym.file_path.contains(".rs"),
"Rust query should only return Rust symbols, got: {}",
sym.file_path
);
}
}
#[test]
fn test_query_by_multiple_labels_and() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let rust_structs = db.query_by_labels(&["rust", "struct"]).unwrap();
let _ = rust_structs;
assert!(db.query_by_labels(&["rust", "struct"]).is_ok());
}
#[test]
fn test_query_by_kind_label() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let files = create_multilang_workspace(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
for file in &files {
db.index_file(file).unwrap();
}
let functions = db.query_by_labels(&["fn"]).unwrap();
let _ = functions;
assert!(db.query_by_labels(&["fn"]).is_ok());
}
#[test]
fn test_query_empty_results() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db.query_by_labels(&["nonexistent", "label"]).unwrap();
assert!(
results.is_empty(),
"Non-existent label query should return empty results"
);
}
#[test]
fn test_query_label_inheritance() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let rust_symbols = db.query_by_labels(&["rust"]).unwrap();
assert!(
!rust_symbols.is_empty(),
"Should find symbols with 'rust' label"
);
let fn_symbols = db.query_by_labels(&["fn"]).unwrap();
let _ = fn_symbols;
}
#[test]
fn test_get_all_labels() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let files = create_multilang_workspace(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
for file in &files {
db.index_file(file).unwrap();
}
let labels = db.get_all_labels().unwrap();
assert!(!labels.is_empty(), "Should have labels after indexing");
let expected_lang_labels = vec![
"rust",
"python",
"c",
"cpp",
"java",
"javascript",
"typescript",
];
for lang_label in expected_lang_labels {
assert!(!labels.is_empty(), "Should have labels");
}
assert!(
labels.len() > 7,
"Should have more labels than just language labels"
);
}
#[test]
fn test_get_code_chunk_by_exact_span() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let symbols = db.query_by_labels(&["rust"]).unwrap();
assert!(!symbols.is_empty(), "Should have indexed symbols");
let symbol = &symbols[0];
let chunk = db.get_code_chunk(&rust_file, symbol.byte_start, symbol.byte_end);
assert!(chunk.is_ok(), "Should be able to retrieve code chunk");
let chunk_opt = chunk.unwrap();
assert!(chunk_opt.is_some(), "Should have code chunk at the span");
let chunk_content = chunk_opt.unwrap();
assert!(!chunk_content.is_empty(), "Code chunk should have content");
}
#[test]
fn test_get_code_chunk_for_symbol() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let symbols = db.query_by_labels(&["rust"]).unwrap();
assert!(!symbols.is_empty(), "Should have indexed symbols");
let symbol_name = &symbols[0].name;
let chunks = db.get_code_chunks_for_symbol(&rust_file, symbol_name);
assert!(chunks.is_ok(), "Should be able to retrieve code chunks");
let chunks_vec = chunks.unwrap();
let _ = chunks_vec;
}
#[test]
fn test_get_code_chunk_not_found() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let chunk = db.get_code_chunk(&rust_file, 999999, 999999);
assert!(chunk.is_ok(), "Should not error for non-existent span");
let chunk_opt = chunk.unwrap();
assert!(
chunk_opt.is_none(),
"Should return None for non-existent span"
);
}
#[test]
fn test_code_chunk_no_file_reread() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let symbols = db.query_by_labels(&["rust"]).unwrap();
assert!(!symbols.is_empty());
let symbol = &symbols[0];
let chunk_before = db.get_code_chunk(&rust_file, symbol.byte_start, symbol.byte_end);
assert!(chunk_before.is_ok());
let content_before = chunk_before.unwrap().unwrap();
fs::remove_file(&rust_file).expect("Failed to delete source file");
let chunk_after = db.get_code_chunk(&rust_file, symbol.byte_start, symbol.byte_end);
assert!(
chunk_after.is_ok(),
"Should still retrieve chunk from database"
);
let content_after = chunk_after.unwrap().unwrap();
assert_eq!(
content_before.content, content_after.content,
"Content should match from database"
);
}
#[test]
fn test_get_code_chunks_for_ambiguous_symbol() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let chunks = db.get_code_chunks_for_symbol(&rust_file, "MyStruct");
assert!(
chunks.is_ok(),
"Should be able to retrieve chunks for ambiguous symbol"
);
let chunks_vec = chunks.unwrap();
let _ = chunks_vec;
}
#[test]
fn test_index_nonexistent_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let nonexistent_file = temp_dir.path().join("does_not_exist.rs");
let mut db = MagellanIntegration::open(&db_path).unwrap();
let result = db.index_file(&nonexistent_file);
assert!(result.is_err(), "Should return error for non-existent file");
let err_msg = result.unwrap_err().to_string();
assert!(
err_msg.contains("Failed to read file") || err_msg.contains("No such file"),
"Error message should indicate file read failure: {}",
err_msg
);
}
#[test]
fn test_index_invalid_utf8_path() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let db = MagellanIntegration::open(&db_path);
assert!(db.is_ok(), "Should open database with valid path");
}
#[test]
fn test_index_empty_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let empty_file = temp_dir.path().join("empty.rs");
fs::write(&empty_file, "").expect("Failed to create empty file");
let mut db = MagellanIntegration::open(&db_path).unwrap();
let symbol_count = db.index_file(&empty_file);
assert!(symbol_count.is_ok(), "Indexing empty file should not error");
let count = symbol_count.unwrap();
assert_eq!(count, 0, "Empty file should have 0 symbols");
}
#[test]
fn test_index_syntactically_invalid_file() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let invalid_file = temp_dir.path().join("invalid.rs");
fs::write(&invalid_file, "this is not valid rust code {{{ }}}}}")
.expect("Failed to create invalid file");
let mut db = MagellanIntegration::open(&db_path).unwrap();
let result = db.index_file(&invalid_file);
match result {
Ok(count) => {
let _ = count;
}
Err(_) => {
}
}
}
#[test]
fn test_get_statistics_empty_database() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let db = MagellanIntegration::open(&db_path).unwrap();
let stats = db.get_statistics().unwrap();
assert_eq!(stats.files, 0, "Empty database should have 0 files");
assert_eq!(stats.symbols, 0, "Empty database should have 0 symbols");
assert_eq!(
stats.references, 0,
"Empty database should have 0 references"
);
assert_eq!(stats.calls, 0, "Empty database should have 0 calls");
assert_eq!(
stats.code_chunks, 0,
"Empty database should have 0 code chunks"
);
}
#[test]
fn test_get_statistics_populated_database() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let stats = db.get_statistics().unwrap();
assert_eq!(stats.files, 1, "Should have 1 file indexed");
assert!(stats.symbols > 0, "Should have some symbols indexed");
}
#[test]
fn test_query_symbols_by_file_no_filter() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db
.query_symbols_by_file(&rust_file, None, false, false)
.unwrap();
assert!(!results.is_empty(), "Should find symbols in file");
for result in &results {
assert!(
result.callers.is_empty(),
"Should not have callers when flag is false"
);
assert!(
result.callees.is_empty(),
"Should not have callees when flag is false"
);
}
}
#[test]
fn test_query_symbols_by_file_with_kind_filter() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db
.query_symbols_by_file(&rust_file, Some("fn"), false, false)
.unwrap();
let _ = results;
}
#[test]
fn test_find_symbol_by_name_first_match() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db.find_symbol_by_name("MyStruct", false).unwrap();
assert!(
results.len() <= 1,
"Should return first match only when ambiguous=false"
);
if !results.is_empty() {
assert_eq!(results[0].name, "MyStruct");
}
}
#[test]
fn test_find_symbol_by_name_all_matches() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db.find_symbol_by_name("MyStruct", true).unwrap();
let _ = results;
}
#[test]
fn test_find_symbol_by_name_not_found() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db.find_symbol_by_name("NonExistentSymbol", false).unwrap();
assert!(
results.is_empty(),
"Should return empty for non-existent symbol"
);
}
#[test]
fn test_find_symbol_by_id() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let symbols = db.find_symbol_by_name("MyStruct", true).unwrap();
if let Some(symbol) = symbols.first() {
use splice::symbol_id::generate_symbol_id;
let expected_id = generate_symbol_id(&symbol.name, &symbol.file_path, symbol.byte_start);
let found = db.find_symbol_by_id(expected_id.as_str()).unwrap();
assert!(found.is_some(), "Should find symbol by ID");
}
}
#[test]
fn test_find_symbol_by_id_not_found() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let found = db.find_symbol_by_id("0000000000000000").unwrap();
assert!(
found.is_none(),
"Should return None for non-existent symbol ID"
);
}
#[test]
fn test_get_call_relationships_both_directions() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db.get_call_relationships(
&rust_file,
"my_function",
splice::graph::magellan_integration::CallDirection::Both,
);
assert!(
results.is_ok(),
"Should be able to query call relationships"
);
let relationships = results.unwrap();
assert_eq!(relationships.symbol.name, "my_function");
}
#[test]
fn test_get_call_relationships_in_direction() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db.get_call_relationships(
&rust_file,
"my_function",
splice::graph::magellan_integration::CallDirection::In,
);
assert!(results.is_ok(), "Should be able to query callers");
let relationships = results.unwrap();
assert!(
relationships.callees.is_empty(),
"Should not have callees when direction=In"
);
}
#[test]
fn test_get_call_relationships_out_direction() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let results = db.get_call_relationships(
&rust_file,
"my_function",
splice::graph::magellan_integration::CallDirection::Out,
);
assert!(results.is_ok(), "Should be able to query callees");
let relationships = results.unwrap();
assert!(
relationships.callers.is_empty(),
"Should not have callers when direction=Out"
);
}
#[test]
fn test_list_indexed_files_without_counts() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let files = db.list_indexed_files(false).unwrap();
assert_eq!(files.len(), 1, "Should have 1 indexed file");
let file = &files[0];
assert!(
file.path.contains("sample_rust.rs"),
"Should return the indexed file"
);
assert!(
file.symbol_count.is_none(),
"Should not have symbol count when flag is false"
);
}
#[test]
fn test_list_indexed_files_with_counts() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let rust_file = create_sample_rust_file(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
db.index_file(&rust_file).unwrap();
let files = db.list_indexed_files(true).unwrap();
assert_eq!(files.len(), 1, "Should have 1 indexed file");
let file = &files[0];
assert!(
file.symbol_count.is_some(),
"Should have symbol count when flag is true"
);
assert!(
file.symbol_count.unwrap() > 0,
"Should have at least some symbols"
);
}
#[test]
fn test_list_indexed_files_empty_database() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let mut db = MagellanIntegration::open(&db_path).unwrap();
let files = db.list_indexed_files(false).unwrap();
assert!(
files.is_empty(),
"Empty database should have no indexed files"
);
}
#[test]
fn test_list_indexed_files_multilang() {
let temp_dir = create_temp_magellan_db();
let db_path = temp_dir.path().join("test.db");
let files = create_multilang_workspace(temp_dir.path());
let mut db = MagellanIntegration::open(&db_path).unwrap();
for file in &files {
db.index_file(file).unwrap();
}
let indexed = db.list_indexed_files(false).unwrap();
assert_eq!(indexed.len(), 7, "Should have 7 indexed files");
}