use splice::patch::apply_patch_with_validation;
use splice::symbol::Language as SymbolLanguage;
use splice::validate::AnalyzerMode;
use std::fs::{self, File};
use std::io::Write;
use tempfile::TempDir;
fn setup_test_workspace() -> TempDir {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.rs");
let mut file = File::create(&file_path).unwrap();
writeln!(file, "fn main() {{").unwrap();
writeln!(file, " let x = 1;").unwrap();
writeln!(file, "}}").unwrap();
let db_path = temp_dir.path().join(".splice_graph.db");
let mut db = File::create(&db_path).unwrap();
writeln!(db, "dummy db").unwrap();
let cargo_toml = temp_dir.path().join("Cargo.toml");
let mut cargo = File::create(&cargo_toml).unwrap();
writeln!(cargo, "[package]").unwrap();
writeln!(cargo, "name = \"test\"").unwrap();
writeln!(cargo, "version = \"0.1.0\"").unwrap();
writeln!(cargo, "edition = \"2021\"").unwrap();
let src_dir = temp_dir.path().join("src");
fs::create_dir_all(&src_dir).unwrap();
let main_rs = src_dir.join("main.rs");
fs::copy(&file_path, &main_rs).unwrap();
fs::remove_file(&file_path).unwrap();
temp_dir
}
#[test]
fn test_post_verification_catches_syntax_error() {
let workspace = setup_test_workspace();
let file_path = workspace.path().join("src/main.rs");
let content = fs::read_to_string(&file_path).unwrap();
let start = content.find("let x = 1;").unwrap();
let end = start + "let x = 1;".len();
let invalid_content = "let x = {;";
let result = apply_patch_with_validation(
&file_path,
start,
end,
invalid_content,
workspace.path(),
SymbolLanguage::Rust,
AnalyzerMode::Off,
false, false, );
assert!(result.is_err());
if let Err(e) = result {
let error_msg = format!("{:?}", e);
assert!(
error_msg.contains("Parse") || error_msg.contains("validation"),
"Expected validation error, got: {}",
error_msg
);
}
let content_after = fs::read_to_string(&file_path).unwrap();
assert!(content_after.contains("let x = 1;"));
assert!(!content_after.contains("let x = {;"));
}
#[test]
fn test_post_verification_allows_valid_patch() {
let workspace = setup_test_workspace();
let file_path = workspace.path().join("src/main.rs");
let content = fs::read_to_string(&file_path).unwrap();
let start = content.find("let x = 1;").unwrap();
let end = start + "let x = 1;".len();
let valid_content = "let y = 2;";
let result = apply_patch_with_validation(
&file_path,
start,
end,
valid_content,
workspace.path(),
SymbolLanguage::Rust,
AnalyzerMode::Off,
false, false, );
assert!(result.is_ok());
let (before_hash, after_hash) = result.unwrap();
assert!(!before_hash.is_empty());
assert!(!after_hash.is_empty());
assert_ne!(before_hash, after_hash);
let content_after = fs::read_to_string(&file_path).unwrap();
assert!(!content_after.contains("let x = 1;"));
assert!(content_after.contains("let y = 2;"));
}
#[test]
fn test_post_verification_warnings_non_blocking() {
let workspace = setup_test_workspace();
let file_path = workspace.path().join("src/main.rs");
let content = fs::read_to_string(&file_path).unwrap();
let start = content.find("let x = 1;").unwrap();
let end = start + "let x = 1;".len();
let valid_content = "let y = 2;";
let result = apply_patch_with_validation(
&file_path,
start,
end,
valid_content,
workspace.path(),
SymbolLanguage::Rust,
AnalyzerMode::Off,
false, false, );
assert!(result.is_ok());
}
#[test]
fn test_localized_change_verification() {
let workspace = setup_test_workspace();
let file_path = workspace.path().join("src/main.rs");
let replaced = fs::read(&file_path).unwrap();
let content = String::from_utf8_lossy(&replaced);
let start = content.find("let x = 1;").unwrap();
let end = start + "let x = 1;".len();
let valid_content = "let y = 2;";
let result = apply_patch_with_validation(
&file_path,
start,
end,
valid_content,
workspace.path(),
SymbolLanguage::Rust,
AnalyzerMode::Off,
false, false, );
assert!(result.is_ok());
let patched = fs::read(&file_path).unwrap();
if start > 0 {
assert_eq!(&replaced[..start], &patched[..start]);
}
assert!(patched.len() > start); }