use workspace_tools :: { Workspace, WorkspaceError, workspace };
use tempfile ::TempDir;
use std :: { env, path ::PathBuf };
use std ::sync ::Mutex;
static ENV_TEST_MUTEX: Mutex< () > = Mutex ::new( () );
#[ test ]
fn test_workspace_resolution_with_env_var()
{
let _lock = ENV_TEST_MUTEX.lock().unwrap();
let temp_dir = TempDir ::new().unwrap();
let original = env ::var( "WORKSPACE_PATH" ).ok();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
assert_eq!( workspace.root(), temp_dir.path() );
match original
{
Some( value ) => env ::set_var( "WORKSPACE_PATH", value ),
None => env ::remove_var( "WORKSPACE_PATH" ),
}
}
#[ test ]
fn test_workspace_resolution_missing_env_var()
{
env ::remove_var( "WORKSPACE_PATH" );
let result = Workspace ::resolve();
assert!( result.is_err() );
match result.unwrap_err()
{
WorkspaceError ::EnvironmentVariableMissing( var ) =>
{
assert_eq!( var, "WORKSPACE_PATH" );
}
other => panic!( "expected EnvironmentVariableMissing, got {other:?}" ),
}
}
#[ test ]
fn test_workspace_validation_valid_path()
{
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
let result = workspace.validate();
assert!( result.is_ok() );
env ::remove_var( "WORKSPACE_PATH" );
}
#[ test ]
fn test_workspace_validation_invalid_path()
{
let original_workspace_path = env ::var( "WORKSPACE_PATH" ).ok();
#[ cfg( windows ) ]
let invalid_path = PathBuf ::from( "C:\\nonexistent\\workspace\\path\\12345" );
#[ cfg( not( windows ) ) ]
let invalid_path = PathBuf ::from( "/nonexistent/workspace/path/12345" );
env ::set_var( "WORKSPACE_PATH", &invalid_path );
let result = Workspace ::resolve();
match original_workspace_path
{
Some( path ) => env ::set_var( "WORKSPACE_PATH", path ),
None => env ::remove_var( "WORKSPACE_PATH" ),
}
assert!( result.is_err() );
match result.unwrap_err()
{
WorkspaceError ::PathNotFound( path ) =>
{
assert_eq!( path, invalid_path );
}
other => panic!( "expected PathNotFound, got {other:?}" ),
}
}
#[ test ]
fn test_standard_directories()
{
let temp_dir = TempDir ::new().unwrap();
let workspace = Workspace ::new( temp_dir.path() );
assert_eq!( workspace.config_dir(), temp_dir.path().join( "config" ) );
assert_eq!( workspace.data_dir(), temp_dir.path().join( "data" ) );
assert_eq!( workspace.logs_dir(), temp_dir.path().join( "logs" ) );
assert_eq!( workspace.docs_dir(), temp_dir.path().join( "docs" ) );
assert_eq!( workspace.tests_dir(), temp_dir.path().join( "tests" ) );
assert_eq!( workspace.workspace_dir(), temp_dir.path().join( ".workspace" ) );
}
#[ test ]
fn test_path_joining()
{
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
let joined = workspace.join( "config/app.toml" );
let expected = temp_dir.path().join( "config/app.toml" );
assert_eq!( joined, expected );
env ::remove_var( "WORKSPACE_PATH" );
}
#[ test ]
fn test_workspace_boundaries_internal()
{
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
let internal_path = workspace.join( "config/app.toml" );
assert!( workspace.is_workspace_file( &internal_path ) );
env ::remove_var( "WORKSPACE_PATH" );
}
#[ test ]
fn test_workspace_boundaries_external()
{
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
let external_path = PathBuf ::from( "/etc/passwd" );
assert!( !workspace.is_workspace_file( &external_path ) );
env ::remove_var( "WORKSPACE_PATH" );
}
#[ test ]
fn test_fallback_resolution_current_dir()
{
env ::remove_var( "WORKSPACE_PATH" );
let workspace = Workspace ::resolve_with_extended_fallbacks();
#[ cfg( feature = "serde" ) ]
{
assert!( workspace.is_cargo_workspace() );
assert!( workspace.root().exists() );
assert!( workspace.root().is_dir() );
assert!( workspace.cargo_toml().exists() );
}
#[ cfg( not( feature = "serde" ) ) ]
{
let current_dir = env ::current_dir().unwrap();
assert_eq!( workspace.root(), current_dir );
}
}
#[ test ]
fn test_from_current_dir()
{
let workspace = Workspace ::from_current_dir().unwrap();
let current_dir = env ::current_dir().unwrap();
assert_eq!( workspace.root(), current_dir );
}
#[ test ]
fn test_convenience_function()
{
let original_workspace_path = env ::var( "WORKSPACE_PATH" ).ok();
let original_cwd = env ::current_dir().ok();
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let test_cwd = TempDir ::new().unwrap();
env ::set_current_dir( test_cwd.path() ).ok();
let ws = workspace().unwrap();
assert_eq!( ws.root(), temp_dir.path() );
if let Some( cwd ) = original_cwd
{
env ::set_current_dir( cwd ).ok();
}
match original_workspace_path
{
Some( path ) => env ::set_var( "WORKSPACE_PATH", path ),
None => env ::remove_var( "WORKSPACE_PATH" ),
}
}
#[ test ]
fn test_error_display()
{
let error = WorkspaceError ::EnvironmentVariableMissing( "TEST_VAR".to_string() );
let display = format!( "{error}" );
assert!( display.contains( "TEST_VAR" ) );
assert!( display.contains( "WORKSPACE_PATH" ) );
}
#[ test ]
#[ cfg( feature = "testing" ) ]
fn test_testing_utilities()
{
use workspace_tools ::testing :: { create_test_workspace, create_test_workspace_with_structure };
let ( _temp_dir, workspace ) = create_test_workspace();
assert!( workspace.root().exists() );
let ( _temp_dir, workspace ) = create_test_workspace_with_structure();
assert!( workspace.config_dir().exists() );
assert!( workspace.data_dir().exists() );
assert!( workspace.logs_dir().exists() );
}
#[ cfg( feature = "secrets" ) ]
mod secret_management_tests
{
use super :: *;
use std ::fs;
#[ test ]
fn test_secret_directory()
{
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
assert_eq!( workspace.secret_dir(), temp_dir.path().join( "secret" ) );
env ::remove_var( "WORKSPACE_PATH" );
}
#[ test ]
fn test_secret_file_loading()
{
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
let secret_dir = workspace.secret_dir();
fs ::create_dir_all( &secret_dir ).unwrap();
let secret_file = secret_dir.join( "test.env" );
fs ::write( &secret_file, "API_KEY=secret123\nDB_URL=postgres: //localhost\n# comment\n" ).unwrap();
let secrets = workspace.load_secrets_from_file( "test.env" ).unwrap();
assert_eq!( secrets.get( "API_KEY" ), Some( &"secret123".to_string() ) );
assert_eq!( secrets.get( "DB_URL" ), Some( &"postgres: //localhost".to_string() ) );
assert!( !secrets.contains_key( "comment" ) );
env ::remove_var( "WORKSPACE_PATH" );
}
#[ test ]
fn test_secret_key_loading_with_fallback()
{
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "TEST_ENV_KEY", "env_value" );
let workspace = Workspace ::new( temp_dir.path() );
let value = workspace.load_secret_key( "TEST_ENV_KEY", "nonexistent.env" ).unwrap();
assert_eq!( value, "env_value" );
env ::remove_var( "TEST_ENV_KEY" );
}
}
#[ cfg( feature = "glob" ) ]
mod glob_tests
{
use super :: *;
use std ::fs;
#[ test ]
fn test_find_resources()
{
let temp_dir = TempDir ::new().unwrap();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
let src_dir = workspace.join( "src" );
fs ::create_dir_all( &src_dir ).unwrap();
let test_files = vec![ "lib.rs", "main.rs", "mod.rs" ];
for file in &test_files
{
fs ::write( src_dir.join( file ), "// test content" ).unwrap();
}
let found = workspace.find_resources( "src/*.rs" ).unwrap();
assert_eq!( found.len(), 3 );
for path in found
{
assert!( path.extension().unwrap() == "rs" );
assert!( workspace.is_workspace_file( &path ) );
}
env ::remove_var( "WORKSPACE_PATH" );
}
#[ test ]
fn test_find_config()
{
let temp_dir = TempDir ::new().unwrap();
let original = env ::var( "WORKSPACE_PATH" ).ok();
env ::set_var( "WORKSPACE_PATH", temp_dir.path() );
let workspace = Workspace ::resolve().unwrap();
let config_dir = workspace.config_dir();
fs ::create_dir_all( &config_dir ).unwrap();
let config_file = config_dir.join( "app.toml" );
fs ::write( &config_file, "[app]\nname = \"test\"\n" ).unwrap();
let found = workspace.find_config( "app" ).unwrap();
assert_eq!( found, config_file );
match original
{
Some( value ) => env ::set_var( "WORKSPACE_PATH", value ),
None => env ::remove_var( "WORKSPACE_PATH" ),
}
}
#[ test ]
fn test_find_config_multiple_extensions()
{
let temp_dir = TempDir ::new().unwrap();
let workspace = Workspace ::new( temp_dir.path() );
let config_dir = workspace.config_dir();
fs ::create_dir_all( &config_dir ).unwrap();
let yaml_config = config_dir.join( "database.yaml" );
fs ::write( &yaml_config, "host: localhost\n" ).unwrap();
let json_config = config_dir.join( "database.json" );
fs ::write( &json_config, "{\"host\" : \"localhost\"}\n" ).unwrap();
let found = workspace.find_config( "database" ).unwrap();
assert_eq!( found, yaml_config );
}
}