#[cfg(test)]
mod tests {
use std::io::Write;
use std::path::PathBuf;
use std::process::{Command, Stdio};
use tempfile::NamedTempFile;
fn get_splice_binary() -> PathBuf {
if let Ok(path) = std::env::var("SPLICE_TEST_BIN") {
return PathBuf::from(path);
}
if let Ok(path) = std::env::var("CARGO_BIN_EXE_splice") {
return PathBuf::from(path);
}
let mut path = std::env::current_exe().unwrap();
path.pop(); path.pop(); path.push("splice");
path
}
fn create_test_rust_file(content: &str) -> NamedTempFile {
let mut file = NamedTempFile::with_suffix(".rs").unwrap();
file.write_all(content.as_bytes()).unwrap();
file
}
fn create_replacement_file(content: &str) -> NamedTempFile {
let mut file = NamedTempFile::with_suffix(".rs").unwrap();
file.write_all(content.as_bytes()).unwrap();
file
}
#[test]
fn test_patch_dry_run_no_changes() {
}
#[test]
fn test_patch_dry_run_with_changes() {
let temp_dir = tempfile::tempdir().unwrap();
let cargo_toml = temp_dir.path().join("Cargo.toml");
std::fs::write(
&cargo_toml,
r#"
[package]
name = "test-project"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "test"
path = "test.rs"
"#,
)
.unwrap();
let source_path = temp_dir.path().join("test.rs");
std::fs::write(
&source_path,
r#"
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
pub fn main() {
println!("{}", greet("world"));
}
"#,
)
.unwrap();
let replacement_file = create_replacement_file(
r#"
pub fn greet(name: &str) -> String {
format!("Hi, {}!", name)
}
"#,
);
let output = Command::new(get_splice_binary())
.arg("patch")
.arg("--file")
.arg(&source_path)
.arg("--symbol")
.arg("greet")
.arg("--with")
.arg(replacement_file.path())
.arg("--preview")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("Failed to execute splice command");
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.contains("Cannot find Cargo.toml") {
assert_eq!(
output.status.code(),
Some(1),
"Expected exit code 1 for pending changes, got {:?}. stdout: {}, stderr: {}",
output.status.code(),
String::from_utf8_lossy(&output.stdout),
stderr
);
}
}
#[test]
fn test_patch_normal_success() {
let temp_dir = tempfile::tempdir().unwrap();
let cargo_toml = temp_dir.path().join("Cargo.toml");
std::fs::write(
&cargo_toml,
r#"
[package]
name = "test-project"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "test"
path = "test.rs"
"#,
)
.unwrap();
let source_path = temp_dir.path().join("test.rs");
std::fs::write(
&source_path,
r#"
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
pub fn main() {
println!("{}", greet("world"));
}
"#,
)
.unwrap();
let replacement_file = create_replacement_file(
r#"
pub fn greet(name: &str) -> String {
format!("Hi, {}!", name)
}
"#,
);
let output = Command::new(get_splice_binary())
.arg("patch")
.arg("--file")
.arg(&source_path)
.arg("--symbol")
.arg("greet")
.arg("--with")
.arg(replacement_file.path())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("Failed to execute splice command");
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.contains("Cannot find Cargo.toml") {
assert_eq!(
output.status.code(),
Some(0),
"Expected exit code 0 for successful patch, got {:?}. stdout: {}, stderr: {}",
output.status.code(),
String::from_utf8_lossy(&output.stdout),
stderr
);
let content = std::fs::read_to_string(&source_path).unwrap();
assert!(content.contains("Hi,"));
assert!(!content.contains("Hello,"));
}
}
#[test]
fn test_delete_dry_run_symbol_found() {
let temp_dir = tempfile::tempdir().unwrap();
let cargo_toml = temp_dir.path().join("Cargo.toml");
std::fs::write(
&cargo_toml,
r#"
[package]
name = "test-project"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "test"
path = "test.rs"
"#,
)
.unwrap();
let source_path = temp_dir.path().join("test.rs");
std::fs::write(
&source_path,
r#"
pub fn helper() -> i32 {
42
}
pub fn main() {
println!("{}", helper());
}
"#,
)
.unwrap();
let output = Command::new(get_splice_binary())
.arg("delete")
.arg("--file")
.arg(&source_path)
.arg("--symbol")
.arg("helper")
.arg("--dry-run")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("Failed to execute splice command");
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.contains("Cannot find Cargo.toml") {
assert_eq!(
output.status.code(),
Some(1),
"Expected exit code 1 when symbol found, got {:?}. stdout: {}, stderr: {}",
output.status.code(),
String::from_utf8_lossy(&output.stdout),
stderr
);
let content = std::fs::read_to_string(&source_path).unwrap();
assert!(content.contains("helper"));
}
}
#[test]
fn test_delete_dry_run_symbol_not_found() {
let temp_dir = tempfile::tempdir().unwrap();
let cargo_toml = temp_dir.path().join("Cargo.toml");
std::fs::write(
&cargo_toml,
r#"
[package]
name = "test-project"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "test"
path = "test.rs"
"#,
)
.unwrap();
let source_path = temp_dir.path().join("test.rs");
std::fs::write(
&source_path,
r#"
pub fn main() {
println!("Hello, world!");
}
"#,
)
.unwrap();
let output = Command::new(get_splice_binary())
.arg("delete")
.arg("--file")
.arg(&source_path)
.arg("--symbol")
.arg("nonexistent")
.arg("--dry-run")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("Failed to execute splice command");
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.contains("Cannot find Cargo.toml") {
assert!(
output.status.code() == Some(1),
"Expected exit code 1 for symbol not found error, got {:?}",
output.status.code()
);
assert!(
stderr.contains("not found") || stderr.contains("error"),
"Expected error message in stderr, got: {}",
stderr
);
}
}
#[test]
fn test_patch_dry_run_adds_lines() {
let temp_dir = tempfile::tempdir().unwrap();
let cargo_toml = temp_dir.path().join("Cargo.toml");
std::fs::write(
&cargo_toml,
r#"
[package]
name = "test-project"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "test"
path = "test.rs"
"#,
)
.unwrap();
let source_path = temp_dir.path().join("test.rs");
std::fs::write(
&source_path,
r#"
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
"#,
)
.unwrap();
let replacement_file = create_replacement_file(
r#"
pub fn greet(name: &str) -> String {
let greeting = "Hello";
format!("{}, {}!", greeting, name)
}
"#,
);
let output = Command::new(get_splice_binary())
.arg("patch")
.arg("--file")
.arg(&source_path)
.arg("--symbol")
.arg("greet")
.arg("--with")
.arg(replacement_file.path())
.arg("--preview")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("Failed to execute splice command");
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.contains("Cannot find Cargo.toml") {
let exit_code = output.status.code();
assert!(
exit_code == Some(1) || exit_code == Some(5),
"Expected exit code 1 or 5 when lines would be added, got {:?}",
exit_code
);
}
}
#[test]
fn test_patch_dry_run_removes_lines() {
let temp_dir = tempfile::tempdir().unwrap();
let cargo_toml = temp_dir.path().join("Cargo.toml");
std::fs::write(
&cargo_toml,
r#"
[package]
name = "test-project"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "test"
path = "test.rs"
"#,
)
.unwrap();
let source_path = temp_dir.path().join("test.rs");
std::fs::write(
&source_path,
r#"
pub fn greet(name: &str) -> String {
let greeting = "Hello";
format!("{}, {}!", greeting, name)
}
"#,
)
.unwrap();
let replacement_file = create_replacement_file(
r#"
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
"#,
);
let output = Command::new(get_splice_binary())
.arg("patch")
.arg("--file")
.arg(&source_path)
.arg("--symbol")
.arg("greet")
.arg("--with")
.arg(replacement_file.path())
.arg("--preview")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("Failed to execute splice command");
let stderr = String::from_utf8_lossy(&output.stderr);
if !stderr.contains("Cannot find Cargo.toml") {
let exit_code = output.status.code();
assert!(
exit_code == Some(1) || exit_code == Some(5),
"Expected exit code 1 or 5 when lines would be removed, got {:?}",
exit_code
);
}
}
}