use mecha10_cli::services::package_service::utils::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_is_executable_on_unix() {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let temp = TempDir::new().unwrap();
let file = temp.path().join("test_binary");
fs::write(&file, "binary content").unwrap();
assert!(!is_executable(&file).unwrap());
let mut perms = fs::metadata(&file).unwrap().permissions();
perms.set_mode(0o755);
fs::set_permissions(&file, perms).unwrap();
assert!(is_executable(&file).unwrap());
}
}
#[test]
fn test_is_executable_on_windows() {
#[cfg(not(unix))]
{
let temp = TempDir::new().unwrap();
let exe_file = temp.path().join("test.exe");
fs::write(&exe_file, "binary").unwrap();
assert!(is_executable(&exe_file).unwrap());
let no_ext = temp.path().join("binary");
fs::write(&no_ext, "binary").unwrap();
assert!(is_executable(&no_ext).unwrap());
let txt_file = temp.path().join("readme.txt");
fs::write(&txt_file, "text").unwrap();
assert!(!is_executable(&txt_file).unwrap());
}
}
#[test]
fn test_calculate_checksum_consistent() {
let temp = TempDir::new().unwrap();
let file = temp.path().join("test.txt");
fs::write(&file, "test content").unwrap();
let checksum1 = calculate_checksum(&file).unwrap();
let checksum2 = calculate_checksum(&file).unwrap();
assert_eq!(checksum1, checksum2);
assert_eq!(checksum1.len(), 64); }
#[test]
fn test_calculate_checksum_different_content() {
let temp = TempDir::new().unwrap();
let file1 = temp.path().join("file1.txt");
let file2 = temp.path().join("file2.txt");
fs::write(&file1, "content A").unwrap();
fs::write(&file2, "content B").unwrap();
let checksum1 = calculate_checksum(&file1).unwrap();
let checksum2 = calculate_checksum(&file2).unwrap();
assert_ne!(checksum1, checksum2);
}
#[test]
fn test_calculate_checksum_large_file() {
let temp = TempDir::new().unwrap();
let file = temp.path().join("large.dat");
let content = vec![0u8; 16384];
fs::write(&file, content).unwrap();
let result = calculate_checksum(&file);
assert!(result.is_ok());
assert_eq!(result.unwrap().len(), 64);
}
#[test]
fn test_calculate_checksum_missing_file() {
let temp = TempDir::new().unwrap();
let file = temp.path().join("nonexistent.txt");
let result = calculate_checksum(&file);
assert!(result.is_err());
}
#[test]
fn test_determine_config_type_infrastructure() {
let path = std::path::Path::new("/project/config/infrastructure.yaml");
assert_eq!(determine_config_type(path), "infrastructure");
}
#[test]
fn test_determine_config_type_node() {
let path = std::path::Path::new("/project/config/node_config.json");
assert_eq!(determine_config_type(path), "node");
}
#[test]
fn test_determine_config_type_behavior() {
let path = std::path::Path::new("/project/config/behavior_tree.yaml");
assert_eq!(determine_config_type(path), "behavior");
}
#[test]
fn test_determine_config_type_unknown() {
let path = std::path::Path::new("/project/config/database.toml");
assert_eq!(determine_config_type(path), "unknown");
}
#[test]
fn test_determine_config_type_case_insensitive() {
let path = std::path::Path::new("/project/config/INFRASTRUCTURE.yaml");
assert_eq!(determine_config_type(path), "infrastructure");
}
#[test]
fn test_determine_asset_type_model_by_path() {
let path = std::path::Path::new("/project/models/robot.urdf");
assert_eq!(determine_asset_type(path), "model");
}
#[test]
fn test_determine_asset_type_model_by_extension() {
let path = std::path::Path::new("/project/data/network.onnx");
assert_eq!(determine_asset_type(path), "model");
let path2 = std::path::Path::new("/project/data/weights.pt");
assert_eq!(determine_asset_type(path2), "model");
}
#[test]
fn test_determine_asset_type_calibration() {
let path = std::path::Path::new("/project/calibration/camera.yaml");
assert_eq!(determine_asset_type(path), "calibration");
}
#[test]
fn test_determine_asset_type_data() {
let path = std::path::Path::new("/project/data/training.csv");
assert_eq!(determine_asset_type(path), "data");
}
#[test]
fn test_determine_asset_type_case_insensitive() {
let path = std::path::Path::new("/project/MODELS/robot.urdf");
assert_eq!(determine_asset_type(path), "model");
}
#[test]
fn test_collect_dependencies_with_cargo_lock() {
let temp = TempDir::new().unwrap();
let project_root = temp.path();
let cargo_lock_content = r#"
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
"#;
fs::write(project_root.join("Cargo.lock"), cargo_lock_content).unwrap();
let result = collect_dependencies(project_root);
assert!(result.is_ok());
let deps = result.unwrap();
assert!(deps.contains_key("anyhow"));
assert!(deps.contains_key("serde"));
assert_eq!(deps.len(), 2);
}
#[test]
fn test_collect_dependencies_without_cargo_lock() {
let temp = TempDir::new().unwrap();
let project_root = temp.path();
let result = collect_dependencies(project_root);
assert!(result.is_ok());
let deps = result.unwrap();
assert_eq!(deps.len(), 0);
}
#[test]
fn test_collect_dependencies_empty_cargo_lock() {
let temp = TempDir::new().unwrap();
let project_root = temp.path();
fs::write(project_root.join("Cargo.lock"), "").unwrap();
let result = collect_dependencies(project_root);
assert!(result.is_ok());
let deps = result.unwrap();
assert_eq!(deps.len(), 0);
}
#[test]
fn test_get_git_commit_in_git_repo() {
let temp = TempDir::new().unwrap();
let project_root = temp.path();
std::process::Command::new("git")
.args(["init"])
.current_dir(project_root)
.output()
.ok();
fs::write(project_root.join("test.txt"), "test").ok();
std::process::Command::new("git")
.args(["add", "."])
.current_dir(project_root)
.output()
.ok();
std::process::Command::new("git")
.args(["commit", "-m", "Initial commit"])
.current_dir(project_root)
.output()
.ok();
let result = get_git_commit(project_root);
if let Some(commit) = result {
assert_eq!(commit.len(), 40); assert!(commit.chars().all(|c| c.is_ascii_hexdigit()));
}
}
#[test]
fn test_get_git_commit_not_git_repo() {
let temp = TempDir::new().unwrap();
let project_root = temp.path();
let result = get_git_commit(project_root);
assert!(result.is_none());
}
#[test]
fn test_copy_dir_recursive_simple() {
let temp = TempDir::new().unwrap();
let src = temp.path().join("source");
let dst = temp.path().join("dest");
fs::create_dir_all(&src).unwrap();
fs::write(src.join("file1.txt"), "content1").unwrap();
fs::write(src.join("file2.txt"), "content2").unwrap();
let result = copy_dir_recursive(&src, &dst);
assert!(result.is_ok());
assert!(dst.join("file1.txt").exists());
assert!(dst.join("file2.txt").exists());
assert_eq!(fs::read_to_string(dst.join("file1.txt")).unwrap(), "content1");
assert_eq!(fs::read_to_string(dst.join("file2.txt")).unwrap(), "content2");
}
#[test]
fn test_copy_dir_recursive_nested() {
let temp = TempDir::new().unwrap();
let src = temp.path().join("source");
let dst = temp.path().join("dest");
let nested = src.join("subdir/deeper");
fs::create_dir_all(&nested).unwrap();
fs::write(src.join("root.txt"), "root content").unwrap();
fs::write(src.join("subdir/sub.txt"), "sub content").unwrap();
fs::write(nested.join("deep.txt"), "deep content").unwrap();
let result = copy_dir_recursive(&src, &dst);
assert!(result.is_ok());
assert!(dst.join("root.txt").exists());
assert!(dst.join("subdir/sub.txt").exists());
assert!(dst.join("subdir/deeper/deep.txt").exists());
}
#[test]
fn test_copy_dir_recursive_creates_dest() {
let temp = TempDir::new().unwrap();
let src = temp.path().join("source");
let dst = temp.path().join("nonexistent/dest");
fs::create_dir_all(&src).unwrap();
fs::write(src.join("file.txt"), "content").unwrap();
assert!(!dst.exists());
let result = copy_dir_recursive(&src, &dst);
assert!(result.is_ok());
assert!(dst.exists());
assert!(dst.join("file.txt").exists());
}
#[test]
fn test_copy_dir_recursive_empty_dir() {
let temp = TempDir::new().unwrap();
let src = temp.path().join("source");
let dst = temp.path().join("dest");
fs::create_dir_all(&src).unwrap();
let result = copy_dir_recursive(&src, &dst);
assert!(result.is_ok());
assert!(dst.exists());
}
#[test]
fn test_copy_dir_recursive_missing_source() {
let temp = TempDir::new().unwrap();
let src = temp.path().join("nonexistent");
let dst = temp.path().join("dest");
let result = copy_dir_recursive(&src, &dst);
assert!(result.is_err());
}