#![cfg(feature = "geometric")]
use splice::graph::CodeGraph;
use std::path::PathBuf;
fn geo_test_db() -> Option<PathBuf> {
let path = match std::env::var_os("SPLICE_GEO_TEST_DB") {
Some(path) => PathBuf::from(path),
None => {
eprintln!(
"SKIP: SPLICE_GEO_TEST_DB is not set. Build a .geo database and set this env var to run real geometric workflow tests."
);
return None;
}
};
if !path.exists() {
eprintln!(
"SKIP: SPLICE_GEO_TEST_DB does not exist: {}",
path.display()
);
return None;
}
Some(path)
}
#[test]
fn splice_can_open_geo_backend() {
let Some(geo_path) = geo_test_db() else {
return;
};
let result = CodeGraph::open(&geo_path);
assert!(
result.is_ok(),
"CodeGraph::open() should succeed on .geo file, got: {:?}",
result.err()
);
let graph = result.unwrap();
assert!(
graph.geometric().is_ok(),
"geometric() should return Ok when using .geo backend"
);
assert!(
graph.inner().is_err(),
"inner() should return Err when using .geo backend"
);
}
#[test]
fn splice_can_resolve_real_symbol_from_geo() {
let Some(geo_path) = geo_test_db() else {
return;
};
let graph = CodeGraph::open(&geo_path).expect("Should open .geo file");
let file_path = "/home/feanor/Projects/splice/src/graph/mod.rs";
let symbol_name = "get_span";
let node_id = graph.find_symbol_in_file(file_path, symbol_name);
assert!(
node_id.is_some(),
"Should find symbol '{}' in file '{}'",
symbol_name,
file_path
);
let id = node_id.unwrap();
assert!(id.0 > 0, "NodeId should be positive, got {}", id.0);
}
#[test]
fn splice_can_get_real_span_from_geo() {
let Some(geo_path) = geo_test_db() else {
return;
};
let graph = CodeGraph::open(&geo_path).expect("Should open .geo file");
let file_path = "/home/feanor/Projects/splice/src/graph/mod.rs";
let symbol_name = "get_span";
let node_id = graph
.find_symbol_in_file(file_path, symbol_name)
.expect("Should find symbol");
let span_result = graph.get_span(node_id);
assert!(
span_result.is_ok(),
"get_span() should work on geometric backend, got: {:?}",
span_result.err()
);
let (byte_start, byte_end) = span_result.unwrap();
assert!(
byte_start > 0,
"byte_start should be positive, got {}",
byte_start
);
assert!(
byte_end > byte_start,
"byte_end ({}) should be > byte_start ({})",
byte_end,
byte_start
);
eprintln!(
"SUCCESS: Symbol '{}' in '{}' has span {}..{}",
symbol_name, file_path, byte_start, byte_end
);
}
#[test]
fn splice_geo_ambiguity_handling_is_explicit() {
let Some(geo_path) = geo_test_db() else {
return;
};
let graph = CodeGraph::open(&geo_path).expect("Should open .geo file");
let file_path = "/home/feanor/Projects/splice/src/graph/mod.rs";
let ambiguous_name = "open";
let node_id = graph.find_symbol_in_file(file_path, ambiguous_name);
assert!(
node_id.is_some(),
"Should find symbol '{}' even if ambiguous across files",
ambiguous_name
);
let span = graph.get_span(node_id.unwrap());
assert!(span.is_ok(), "Should get span for ambiguous-named symbol");
}
#[test]
fn splice_span_safe_edit_workflow_works_on_geo() {
let Some(geo_path) = geo_test_db() else {
return;
};
let graph = CodeGraph::open(&geo_path).expect("Should open .geo file");
let file_path = "/home/feanor/Projects/splice/src/graph/mod.rs";
let symbol_name = "get_span";
let node_id = graph
.find_symbol_in_file(file_path, symbol_name)
.expect("Should find symbol");
let (byte_start, byte_end) = graph.get_span(node_id).expect("Should get span");
let magellan = graph.geometric().expect("Should have geometric backend");
let chunk_result = magellan.get_code_chunk_by_span(file_path, byte_start, byte_end);
assert!(
chunk_result.is_ok(),
"get_code_chunk should succeed, got: {:?}",
chunk_result.err()
);
let chunk = chunk_result.unwrap();
assert!(chunk.is_some(), "Should retrieve code chunk for symbol");
let code = chunk.unwrap();
assert!(!code.content.is_empty(), "Code chunk should not be empty");
assert!(
code.content.contains("pub fn get_span") || code.content.contains("fn get_span"),
"Code chunk should contain function definition, got: {}",
code.content
);
eprintln!(
"SUCCESS: Retrieved {} bytes of source code for '{}'",
code.content.len(),
symbol_name
);
}
#[test]
fn sqlite_backend_still_works() {
use tempfile::NamedTempFile;
let temp_file = NamedTempFile::new().expect("Should create temp file");
let db_path = temp_file.path().to_path_buf();
drop(temp_file);
let result = CodeGraph::open(&db_path);
assert!(
result.is_ok(),
"CodeGraph::open() should still work on .db files, got: {:?}",
result.err()
);
let graph = result.unwrap();
assert!(graph.inner().is_ok(), "inner() should work on .db files");
#[cfg(feature = "geometric")]
assert!(
graph.geometric().is_err(),
"geometric() should return Err for .db files"
);
let _ = std::fs::remove_file(&db_path);
}