use splice::syntax_validator::validate_syntax;
use splice::verify::{verify_after_patch, PostVerificationResult};
use std::fs::{self, File};
use std::io::Write;
use tempfile::TempDir;
#[test]
fn test_syntax_gate_catches_missing_semicolon() {
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 broken() {{").unwrap();
writeln!(file, " let x = 5").unwrap(); writeln!(file, "}}").unwrap();
let source = fs::read(&file_path).unwrap();
let result = validate_syntax(&file_path, &source).unwrap();
assert!(!result, "Tree-sitter should catch missing semicolon");
}
#[test]
fn test_syntax_gate_allows_valid_code() {
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 valid() {{").unwrap();
writeln!(file, " let x = 5;").unwrap();
writeln!(file, "}}").unwrap();
let source = fs::read(&file_path).unwrap();
let result = validate_syntax(&file_path, &source).unwrap();
assert!(result, "Tree-sitter should allow valid code");
}
#[test]
fn test_compiler_gate_catches_type_errors() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test_type_error.rs");
let mut file = File::create(&file_path).unwrap();
writeln!(file, "fn type_error() {{").unwrap();
writeln!(file, " let x: i32 = \"string\";").unwrap(); writeln!(file, "}}").unwrap();
let output = std::process::Command::new("rustc")
.arg("--emit=metadata")
.arg("--crate-type=lib")
.arg(&file_path)
.output()
.unwrap();
assert!(!output.status.success(), "rustc should catch type error");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("expected `i32`, found `&str`"),
"Error should mention type mismatch"
);
}
#[test]
fn test_compiler_gate_catches_borrow_errors() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test_borrow_error.rs");
let mut file = File::create(&file_path).unwrap();
writeln!(file, "fn borrow_error() {{").unwrap();
writeln!(file, " let mut s = String::from(\"hello\");").unwrap();
writeln!(file, " let r = &s;").unwrap();
writeln!(file, " s.push_str(\" world\");").unwrap(); writeln!(file, " println!(\"{{}}\", r);").unwrap();
writeln!(file, "}}").unwrap();
let output = std::process::Command::new("rustc")
.arg("--emit=metadata")
.arg("--crate-type=lib")
.arg(&file_path)
.output()
.unwrap();
let stderr = String::from_utf8_lossy(&output.stderr);
if output.status.success() {
return;
}
assert!(
stderr.contains("borrow"),
"Error should mention borrow if caught"
);
}
#[test]
fn test_verify_after_patch_integration() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test_patch.rs");
let workspace_root = temp_dir.path();
let mut file = File::create(&file_path).unwrap();
writeln!(file, "pub fn original() {{").unwrap();
writeln!(file, " println!(\"original\");").unwrap();
writeln!(file, "}}").unwrap();
let initial_content = fs::read_to_string(&file_path).unwrap();
let result = verify_after_patch(
&file_path,
workspace_root,
&initial_content,
splice::validate::AnalyzerMode::Off,
)
.unwrap();
assert!(result.syntax_ok, "Valid code should pass syntax gate");
let mut file = File::create(&file_path).unwrap();
writeln!(file, "pub fn broken() {{").unwrap();
writeln!(file, " let x = 5").unwrap(); writeln!(file, "}}").unwrap();
let result = verify_after_patch(
&file_path,
workspace_root,
&initial_content,
splice::validate::AnalyzerMode::Off,
)
.unwrap();
assert!(!result.syntax_ok, "Syntax error should fail syntax gate");
assert!(!result.errors.is_empty(), "Should have error messages");
}
#[test]
fn test_unknown_language_skips_validation() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.xyz");
let mut file = File::create(&file_path).unwrap();
writeln!(file, "some random content").unwrap();
let source = fs::read(&file_path).unwrap();
let result = validate_syntax(&file_path, &source).unwrap();
assert!(result, "Unknown language should pass (skip validation)");
}
#[test]
fn test_multiple_languages_supported() {
let rust_code = b"fn main() { println!(\"hello\"); }";
let rust_path = std::path::Path::new("test.rs");
assert!(validate_syntax(rust_path, rust_code).unwrap());
let python_code = b"def main():\n print('hello')";
let python_path = std::path::Path::new("test.py");
assert!(validate_syntax(python_path, python_code).unwrap());
let js_code = b"function main() { console.log('hello'); }";
let js_path = std::path::Path::new("test.js");
assert!(validate_syntax(js_path, js_code).unwrap());
}