use workspace_tools :: { Workspace, WorkspaceError, workspace };
use std :: { env, fs, thread, sync ::Arc };
use tempfile ::TempDir;
fn create_test_workspace_at( path: &std ::path ::Path ) -> Workspace
{
let path_buf = path.to_path_buf();
if !path_buf.exists()
{
std ::fs ::create_dir_all(&path_buf).expect("Failed to create test directory");
}
Workspace ::new( path )
}
#[ test ]
fn test_from_git_root_in_repository()
{
let temp_dir = TempDir ::new().unwrap();
let git_dir = temp_dir.path().join( ".git" );
fs ::create_dir_all( &git_dir ).unwrap();
fs ::write( git_dir.join( "HEAD" ), "ref: refs/heads/main" ).unwrap();
let subdir = temp_dir.path().join( "src" );
fs ::create_dir_all( &subdir ).unwrap();
let original_cwd = env ::current_dir().unwrap();
env ::set_current_dir( &subdir ).unwrap();
let result = Workspace ::from_git_root();
env ::set_current_dir( original_cwd ).unwrap();
assert!( result.is_ok(), "from_git_root() should succeed when in git repository" );
if let Ok( workspace ) = result
{
assert_eq!( workspace.root(), temp_dir.path() );
}
}
#[ test ]
fn test_from_git_root_not_in_repository()
{
let temp_dir = TempDir ::new().unwrap();
let original_cwd = env ::current_dir().unwrap();
env ::set_current_dir( temp_dir.path() ).unwrap();
let result = Workspace ::from_git_root();
env ::set_current_dir( original_cwd ).unwrap();
assert!( result.is_err(), "from_git_root() should fail when not in git repository" );
match result.unwrap_err()
{
WorkspaceError ::PathNotFound( _ ) => {}, other => panic!( "Expected PathNotFound, got {other:?}" ),
}
}
#[ test ]
fn test_from_git_root_nested_repositories()
{
let temp_dir = TempDir ::new().unwrap();
let outer_git = temp_dir.path().join( ".git" );
fs ::create_dir_all( &outer_git ).unwrap();
fs ::write( outer_git.join( "HEAD" ), "ref: refs/heads/main" ).unwrap();
let inner_dir = temp_dir.path().join( "projects/inner" );
fs ::create_dir_all( &inner_dir ).unwrap();
let inner_git = inner_dir.join( ".git" );
fs ::create_dir_all( &inner_git ).unwrap();
fs ::write( inner_git.join( "HEAD" ), "ref: refs/heads/develop" ).unwrap();
let original_cwd = env ::current_dir().unwrap();
env ::set_current_dir( &inner_dir ).unwrap();
let result = Workspace ::from_git_root();
env ::set_current_dir( original_cwd ).unwrap();
assert!( result.is_ok(), "from_git_root() should find nearest git root" );
if let Ok( workspace ) = result
{
assert_eq!( workspace.root(), inner_dir );
}
}
#[ test ]
fn test_from_cwd_infallible()
{
let workspace = Workspace ::from_cwd();
let current_dir = env ::current_dir().unwrap();
assert_eq!( workspace.root(), current_dir );
for _ in 0..5
{
let ws = Workspace ::from_cwd();
assert_eq!( ws.root(), current_dir );
}
}
#[ test ]
fn test_resolve_or_fallback_no_environment()
{
let original = env ::var( "WORKSPACE_PATH" ).ok();
env ::remove_var( "WORKSPACE_PATH" );
let workspace = Workspace ::resolve_with_extended_fallbacks();
match original
{
Some( value ) => env ::set_var( "WORKSPACE_PATH", value ),
None => env ::remove_var( "WORKSPACE_PATH" ),
}
assert!( workspace.root().exists() || workspace.root().is_absolute() );
let _validation = workspace.validate();
}
#[ test ]
fn test_workspace_helper_function_error()
{
let original = env ::var( "WORKSPACE_PATH" ).ok();
env ::set_var( "WORKSPACE_PATH", "/completely/nonexistent/path/12345" );
let result = workspace();
match original
{
Some( value ) => env ::set_var( "WORKSPACE_PATH", value ),
None => env ::remove_var( "WORKSPACE_PATH" ),
}
assert!( result.is_ok(), "workspace() should succeed via fallbacks even with invalid WORKSPACE_PATH" );
assert!( result.unwrap().root().exists(), "workspace root should be a valid path" );
}
#[ test ]
fn test_concurrent_workspace_access()
{
let temp_dir = TempDir ::new().unwrap();
let workspace = Arc ::new( create_test_workspace_at( temp_dir.path() ) );
let mut handles = vec![];
for i in 0..10
{
let ws = Arc ::clone( &workspace );
let handle = thread ::spawn( move || {
let _root = ws.root();
let _config = ws.config_dir();
let _joined = ws.join( format!( "file_{i}.txt" ) );
let _is_workspace = ws.is_workspace_file( ws.root() );
i
});
handles.push( handle );
}
let mut results = vec![];
for handle in handles
{
results.push( handle.join().unwrap() );
}
assert_eq!( results.len(), 10 );
assert_eq!( results.iter().sum :: < i32 >(), 45 ); }
#[ test ]
fn test_memory_efficiency_large_operations()
{
let temp_dir = TempDir ::new().unwrap();
let workspace = create_test_workspace_at( temp_dir.path() );
for i in 0..1000
{
let path = format!( "dir_{}/subdir_{}/file_{}.txt", i % 10, i % 100, i );
let _joined = workspace.join( &path );
let _is_workspace = workspace.is_workspace_file( temp_dir.path().join( &path ) );
if i % 100 == 0
{
let _normalized = workspace.normalize_path( &path );
}
}
}
#[ test ]
fn test_cross_platform_path_handling()
{
let temp_dir = TempDir ::new().unwrap();
let workspace = create_test_workspace_at( temp_dir.path() );
let test_paths = vec![
"config/app.toml", "config\\app.toml", "config/sub/app.toml", "config\\sub\\app.toml", "./config/app.toml", ".\\config\\app.toml", ];
for test_path in test_paths
{
let joined = workspace.join( test_path );
assert!( joined.is_absolute(), "Joined path should be absolute for: {test_path}" );
assert!( joined.starts_with( temp_dir.path() ),
"Joined path should start with workspace root for: {test_path}" );
assert!( joined.is_absolute(), "Path should be absolute for: {test_path}" );
}
}
#[ cfg( unix ) ]
#[ test ]
fn test_symlink_workspace_root()
{
let temp_dir = TempDir ::new().unwrap();
let actual_workspace = temp_dir.path().join( "actual" );
let symlink_workspace = temp_dir.path().join( "symlink" );
fs ::create_dir_all( &actual_workspace ).unwrap();
std ::os ::unix ::fs ::symlink( &actual_workspace, &symlink_workspace ).unwrap();
let workspace = create_test_workspace_at( &symlink_workspace );
let _validation = workspace.validate();
let config_dir = workspace.config_dir();
assert!( config_dir.starts_with( &symlink_workspace ) );
let joined = workspace.join( "test.txt" );
assert!( joined.starts_with( &symlink_workspace ) );
assert!( workspace.is_workspace_file( &joined ) );
}
#[ test ]
fn test_empty_directory_workspace()
{
let temp_dir = TempDir ::new().unwrap();
let workspace = create_test_workspace_at( temp_dir.path() );
assert!( workspace.validate().is_ok() );
assert_eq!( workspace.root(), temp_dir.path() );
let config_dir = workspace.config_dir();
assert_eq!( config_dir, temp_dir.path().join( "config" ) );
let joined = workspace.join( "new_file.txt" );
assert_eq!( joined, temp_dir.path().join( "new_file.txt" ) );
assert!( workspace.is_workspace_file( &joined ) );
}
#[ test ]
fn test_workspace_with_hidden_files()
{
let temp_dir = TempDir ::new().unwrap();
fs ::write( temp_dir.path().join( ".gitignore" ), "target/" ).unwrap();
fs ::write( temp_dir.path().join( ".env" ), "DEBUG=true" ).unwrap();
fs ::create_dir_all( temp_dir.path().join( ".git" ) ).unwrap();
fs ::write( temp_dir.path().join( ".git/config" ), "[core]\n" ).unwrap();
let workspace = Workspace ::new( temp_dir.path() );
assert!( workspace.validate().is_ok() );
assert!( workspace.is_workspace_file( temp_dir.path().join( ".gitignore" ) ) );
assert!( workspace.is_workspace_file( temp_dir.path().join( ".env" ) ) );
assert!( workspace.is_workspace_file( temp_dir.path().join( ".git" ) ) );
assert!( workspace.is_workspace_file( temp_dir.path().join( ".git/config" ) ) );
}
#[ test ]
fn test_very_long_filename_operations()
{
let temp_dir = TempDir ::new().unwrap();
let workspace = create_test_workspace_at( temp_dir.path() );
let long_name = "a".repeat( 200 );
let long_filename = format!( "{long_name}.txt" );
let joined = workspace.join( &long_filename );
assert!( joined.starts_with( temp_dir.path() ) );
assert!( joined.file_name().unwrap().to_string_lossy().len() > 200 );
assert!( workspace.is_workspace_file( &joined ) );
assert!( joined.is_absolute() );
assert!( joined.starts_with( temp_dir.path() ) );
}
#[ test ]
fn test_rapid_repeated_operations()
{
let temp_dir = TempDir ::new().unwrap();
let workspace = create_test_workspace_at( temp_dir.path() );
for i in 0..100
{
let filename = format!( "file_{i}.txt" );
let joined1 = workspace.join( &filename );
let joined2 = workspace.join( &filename );
assert_eq!( joined1, joined2 );
let config1 = workspace.config_dir();
let config2 = workspace.config_dir();
assert_eq!( config1, config2 );
let root1 = workspace.root();
let root2 = workspace.root();
assert_eq!( root1, root2 );
assert_eq!( workspace.is_workspace_file( &joined1 ), workspace.is_workspace_file( &joined2 ) );
}
}