#[cfg(test)]
mod tests {
use super::super::*;
use std::fs;
use std::path::PathBuf;
use tempfile::TempDir;
use toml_edit::DocumentMut;
fn create_test_workspace() -> (TempDir, PathBuf) {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path().to_path_buf();
let repos = vec![
"embeddenator-vsa",
"embeddenator-fs",
"embeddenator-io",
"embeddenator-retrieval",
];
for repo in repos {
let repo_path = root.join(repo);
fs::create_dir_all(&repo_path).unwrap();
let manifest_content = format!(
r#"[package]
name = "{}"
version = "0.1.0"
edition = "2021"
[dependencies]
"#,
repo
);
fs::write(repo_path.join("Cargo.toml"), manifest_content).unwrap();
}
let main_path = root.join("embeddenator");
fs::create_dir_all(&main_path).unwrap();
let main_manifest = r#"[package]
name = "embeddenator"
version = "0.20.0"
edition = "2021"
[dependencies]
embeddenator-vsa = { git = "https://github.com/tzervas/embeddenator-vsa", tag = "v0.1.0" }
embeddenator-fs = { git = "https://github.com/tzervas/embeddenator-fs", branch = "main" }
embeddenator-io = { git = "https://github.com/tzervas/embeddenator-io", tag = "v0.1.1" }
serde = "1.0"
[dev-dependencies]
embeddenator-retrieval = { git = "https://github.com/tzervas/embeddenator-retrieval", tag = "v0.1.3" }
"#;
fs::write(main_path.join("Cargo.toml"), main_manifest).unwrap();
(temp_dir, root)
}
#[test]
fn test_discover_patchable_dependencies() {
let (_temp, root) = create_test_workspace();
let manager = PatchManager::new(&root);
let deps = manager.discover_patchable_dependencies().unwrap();
assert_eq!(deps.len(), 4);
let names: Vec<&str> = deps.iter().map(|d| d.name.as_str()).collect();
assert_eq!(
names,
vec![
"embeddenator-fs",
"embeddenator-io",
"embeddenator-retrieval",
"embeddenator-vsa"
]
);
for dep in &deps {
assert!(dep.local_path.exists());
assert!(dep.local_path.join("Cargo.toml").exists());
}
let vsa = deps.iter().find(|d| d.name == "embeddenator-vsa").unwrap();
assert_eq!(vsa.git_url, "https://github.com/tzervas/embeddenator-vsa");
assert_eq!(vsa.branch_or_tag, Some("v0.1.0".to_string()));
}
#[test]
fn test_apply_patches() {
let (_temp, root) = create_test_workspace();
let manager = PatchManager::new(&root);
let deps = manager.discover_patchable_dependencies().unwrap();
let report = manager.apply_patches(&deps, false).unwrap();
assert_eq!(report.patched_count, 4);
assert!(!report.verified);
let config_path = root.join(".cargo/config.toml");
assert!(config_path.exists());
let content = fs::read_to_string(&config_path).unwrap();
let doc: DocumentMut = content.parse().unwrap();
let patch_key = "patch.\"https://github.com/tzervas/embeddenator-vsa\"";
assert!(doc.get(patch_key).is_some());
let vsa_path = doc
.get(patch_key)
.and_then(|p| p.get("embeddenator-vsa"))
.and_then(|e| e.get("path"))
.and_then(|p| p.as_str())
.unwrap();
assert!(vsa_path.contains("embeddenator-vsa"));
}
#[test]
fn test_remove_patches() {
let (_temp, root) = create_test_workspace();
let manager = PatchManager::new(&root);
let deps = manager.discover_patchable_dependencies().unwrap();
manager.apply_patches(&deps, false).unwrap();
let config_path = root.join(".cargo/config.toml");
assert!(config_path.exists());
let report = manager.remove_patches().unwrap();
assert_eq!(report.removed_count, 4);
assert!(report.config_deleted);
assert!(!config_path.exists());
}
#[test]
fn test_remove_patches_preserves_other_config() {
let (_temp, root) = create_test_workspace();
let manager = PatchManager::new(&root);
let cargo_dir = root.join(".cargo");
fs::create_dir_all(&cargo_dir).unwrap();
let config_content = r#"[build]
target-dir = "custom-target"
[patch."https://github.com/tzervas/embeddenator-vsa"]
embeddenator-vsa = { path = "embeddenator-vsa" }
"#;
let config_path = cargo_dir.join("config.toml");
fs::write(&config_path, config_content).unwrap();
let report = manager.remove_patches().unwrap();
assert_eq!(report.removed_count, 1);
assert!(!report.config_deleted);
let content = fs::read_to_string(&config_path).unwrap();
let doc: DocumentMut = content.parse().unwrap();
assert!(doc.get("build").is_some());
assert!(doc
.get("patch.\"https://github.com/tzervas/embeddenator-vsa\"")
.is_none());
}
#[test]
fn test_remove_patches_when_none_exist() {
let (_temp, root) = create_test_workspace();
let manager = PatchManager::new(&root);
let report = manager.remove_patches().unwrap();
assert_eq!(report.removed_count, 0);
}
#[test]
fn test_multiple_repos_same_git_url() {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path();
for repo in &["embeddenator-vsa", "embeddenator-fs"] {
let repo_path = root.join(repo);
fs::create_dir_all(&repo_path).unwrap();
let manifest = format!(
r#"[package]
name = "{}"
version = "0.1.0"
edition = "2021"
"#,
repo
);
fs::write(repo_path.join("Cargo.toml"), manifest).unwrap();
}
let main_path = root.join("embeddenator");
fs::create_dir_all(&main_path).unwrap();
let manifest = r#"[package]
name = "embeddenator"
version = "0.1.0"
edition = "2021"
[dependencies]
embeddenator-vsa = { git = "https://github.com/tzervas/embeddenator", branch = "main" }
embeddenator-fs = { git = "https://github.com/tzervas/embeddenator", branch = "main" }
"#;
fs::write(main_path.join("Cargo.toml"), manifest).unwrap();
let manager = PatchManager::new(root);
let deps = manager.discover_patchable_dependencies().unwrap();
assert_eq!(deps.len(), 2);
let report = manager.apply_patches(&deps, false).unwrap();
assert_eq!(report.patched_count, 2);
let config_path = root.join(".cargo/config.toml");
let content = fs::read_to_string(&config_path).unwrap();
let doc: DocumentMut = content.parse().unwrap();
let patch_section = doc
.get("patch.\"https://github.com/tzervas/embeddenator\"")
.unwrap();
assert!(patch_section.get("embeddenator-vsa").is_some());
assert!(patch_section.get("embeddenator-fs").is_some());
}
#[test]
fn test_parse_git_dependency() {
use toml_edit::value;
let mut table = toml_edit::Table::new();
table.insert("git", value("https://github.com/user/repo"));
table.insert("tag", value("v1.0.0"));
let item = Item::Table(table);
let result = PatchManager::parse_git_dependency("test-crate", &item);
assert!(result.is_some());
let (url, tag) = result.unwrap();
assert_eq!(url, "https://github.com/user/repo");
assert_eq!(tag, Some("v1.0.0".to_string()));
let mut table = toml_edit::Table::new();
table.insert("git", value("https://github.com/user/repo"));
table.insert("branch", value("main"));
let item = Item::Table(table);
let result = PatchManager::parse_git_dependency("test-crate", &item);
assert!(result.is_some());
let (url, branch) = result.unwrap();
assert_eq!(url, "https://github.com/user/repo");
assert_eq!(branch, Some("main".to_string()));
let item = value("1.0.0");
let result = PatchManager::parse_git_dependency("test-crate", &item);
assert!(result.is_none());
}
}