use mockforge_core::sync_watcher::SyncWatcher;
use mockforge_core::workspace::{SyncConfig, SyncDirection, SyncDirectoryStructure, Workspace};
use std::fs;
use std::path::{Path, PathBuf};
use tempfile::TempDir;
#[cfg(test)]
mod cross_platform_tests {
use super::*;
#[tokio::test]
async fn test_path_handling_cross_platform() {
let temp_dir = TempDir::new().unwrap();
let workspace_dir = temp_dir.path();
let unix_path = workspace_dir.join("test/nested/directory");
fs::create_dir_all(&unix_path).unwrap();
assert!(unix_path.exists());
#[cfg(target_os = "windows")]
{
let windows_path = workspace_dir.join("test\\windows\\directory");
fs::create_dir_all(&windows_path).unwrap();
assert!(windows_path.exists());
}
let mixed_path = workspace_dir.join("test").join("mixed").join("directory");
fs::create_dir_all(&mixed_path).unwrap();
assert!(mixed_path.exists());
}
#[tokio::test]
async fn test_paths_with_spaces_and_special_chars() {
let temp_dir = TempDir::new().unwrap();
let workspace_dir = temp_dir.path();
let path_with_spaces = workspace_dir.join("my test workspace");
fs::create_dir_all(&path_with_spaces).unwrap();
assert!(path_with_spaces.exists());
let test_file = path_with_spaces.join("config.yaml");
fs::write(&test_file, "test: data").unwrap();
assert!(test_file.exists());
let content = fs::read_to_string(&test_file).unwrap();
assert_eq!(content, "test: data");
}
#[tokio::test]
async fn test_relative_and_absolute_paths() {
let temp_dir = TempDir::new().unwrap();
let workspace_dir = temp_dir.path();
let abs_path = workspace_dir.join("absolute.yaml");
fs::write(&abs_path, "absolute: true").unwrap();
assert!(abs_path.exists());
let canonical = abs_path.canonicalize().unwrap();
assert!(canonical.is_absolute());
assert!(canonical.exists());
let rel_path = PathBuf::from("relative.yaml");
let full_path = workspace_dir.join(&rel_path);
fs::write(&full_path, "relative: true").unwrap();
assert!(full_path.exists());
}
#[tokio::test]
async fn test_path_comparison_normalization() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let test_dir = base_path.join("test_dir");
fs::create_dir_all(&test_dir).unwrap();
let path1 = base_path.join("test_dir");
let path2 = base_path.join("./test_dir");
assert!(path1.exists());
assert!(path2.exists());
let canon1 = path1.canonicalize().unwrap();
let canon2 = path2.canonicalize().unwrap();
assert_eq!(canon1, canon2);
}
#[tokio::test]
async fn test_sync_config_with_various_paths() {
let temp_dir = TempDir::new().unwrap();
let workspace_dir = temp_dir.path();
let abs_sync_dir = workspace_dir.join("sync_abs");
fs::create_dir_all(&abs_sync_dir).unwrap();
let mut workspace = Workspace::new("Test Workspace".to_string());
let sync_config = SyncConfig {
enabled: true,
target_directory: Some(abs_sync_dir.to_string_lossy().to_string()),
sync_direction: SyncDirection::Bidirectional,
realtime_monitoring: true,
directory_structure: SyncDirectoryStructure::Flat,
filename_pattern: "workspace.yaml".to_string(),
exclude_pattern: None,
include_metadata: true,
force_overwrite: false,
last_sync: None,
};
workspace.configure_sync(sync_config).unwrap();
assert!(workspace.is_sync_enabled());
let stored_path = workspace.get_sync_directory().unwrap();
assert!(PathBuf::from(&stored_path).is_absolute());
}
#[tokio::test]
async fn test_nested_directory_creation() {
let temp_dir = TempDir::new().unwrap();
let workspace_dir = temp_dir.path();
let nested_path = workspace_dir.join("level1").join("level2").join("level3").join("level4");
fs::create_dir_all(&nested_path).unwrap();
assert!(nested_path.exists());
let file_path = nested_path.join("test.yaml");
fs::write(&file_path, "nested: true").unwrap();
assert!(file_path.exists());
}
#[tokio::test]
async fn test_path_components_and_traversal() {
let temp_dir = TempDir::new().unwrap();
let workspace_dir = temp_dir.path();
let dir_structure = workspace_dir.join("parent").join("child");
fs::create_dir_all(&dir_structure).unwrap();
let parent = dir_structure.parent().unwrap();
assert_eq!(parent, workspace_dir.join("parent"));
let file_name = dir_structure.file_name().unwrap();
assert_eq!(file_name, "child");
let components: Vec<_> = dir_structure.components().collect();
assert!(components.len() >= 2); }
#[tokio::test]
async fn test_path_joining_and_string_conversion() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let joined = base_path.join("a").join("b").join("c");
fs::create_dir_all(&joined).unwrap();
assert!(joined.exists());
let path_str = joined.to_string_lossy();
assert!(!path_str.is_empty());
let reconstructed = PathBuf::from(path_str.as_ref());
assert_eq!(reconstructed, joined);
}
#[tokio::test]
async fn test_current_and_parent_directory_refs() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let test_dir = base_path.join("test");
fs::create_dir_all(&test_dir).unwrap();
let with_dot = base_path.join(".").join("test");
assert_eq!(with_dot.canonicalize().unwrap(), test_dir.canonicalize().unwrap());
let with_dotdot = test_dir.join("..").join("test");
assert_eq!(with_dotdot.canonicalize().unwrap(), test_dir.canonicalize().unwrap());
}
#[cfg(target_os = "windows")]
#[tokio::test]
async fn test_windows_drive_letters() {
use std::env;
let current_dir = env::current_dir().unwrap();
assert!(current_dir.is_absolute());
let components: Vec<_> = current_dir.components().collect();
assert!(components.len() > 0);
use std::path::Component;
if let Some(Component::Prefix(_)) = components.first() {
}
}
#[cfg(target_os = "windows")]
#[tokio::test]
async fn test_windows_long_paths() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let mut long_path = base_path.to_path_buf();
for i in 0..20 {
long_path = long_path.join(format!("level_{}", i));
}
let result = fs::create_dir_all(&long_path);
match result {
Ok(_) => {
assert!(long_path.exists());
}
Err(e) => {
eprintln!(
"Long path creation failed (this may be expected on Windows without long path support): {}",
e
);
}
}
}
#[tokio::test]
async fn test_strip_prefix_for_relative_paths() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let sub_dir = base_path.join("sub").join("directory");
fs::create_dir_all(&sub_dir).unwrap();
let file_path = sub_dir.join("file.yaml");
fs::write(&file_path, "content").unwrap();
let relative = file_path.strip_prefix(base_path).unwrap();
#[cfg(target_os = "windows")]
{
let relative_str = relative.to_string_lossy();
assert!(relative_str.contains("sub") && relative_str.contains("file.yaml"));
}
#[cfg(not(target_os = "windows"))]
{
assert_eq!(relative, Path::new("sub/directory/file.yaml"));
}
}
#[tokio::test]
async fn test_sync_watcher_with_various_paths() {
let temp_dir = TempDir::new().unwrap();
let workspace_dir = temp_dir.path();
let watcher = SyncWatcher::new(workspace_dir);
assert!(watcher.get_monitored_workspaces().is_empty());
let path_with_spaces = workspace_dir.join("my workspace");
fs::create_dir_all(&path_with_spaces).unwrap();
let watcher2 = SyncWatcher::new(&path_with_spaces);
assert!(watcher2.get_monitored_workspaces().is_empty());
}
#[tokio::test]
async fn test_file_extension_handling() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let yaml_file = base_path.join("config.yaml");
let yml_file = base_path.join("config.yml");
let json_file = base_path.join("config.json");
for file in &[&yaml_file, &yml_file, &json_file] {
fs::write(file, "test").unwrap();
assert!(file.exists());
let _extension = file.extension().unwrap();
match file.extension().and_then(|e| e.to_str()) {
Some("yaml") | Some("yml") => (),
Some("json") => (),
_ => panic!("Unexpected extension"),
}
}
}
}