# Enhanced function for complete cleanup - more robust complete_cleanup <- function() { # Limpiar opciones de sesión options(copernicus.username = NULL) options(copernicus.password = NULL) # Limpiar variables de entorno Sys.unsetenv("COPERNICUS_USERNAME") Sys.unsetenv("COPERNICUS_PASSWORD") # Limpiar ambiente interno del paquete tryCatch({ copernicus_env <- copernicusR:::.copernicus_env() if (exists("cm", envir = copernicus_env)) { rm("cm", envir = copernicus_env) } if (exists("credentials", envir = copernicus_env)) { rm("credentials", envir = copernicus_env) } }, error = function(e) { # Silently ignore if environment doesn't exist }) invisible(NULL) } # Enhanced test wrapper that's more robust for R CMD check test_with_clean_state <- function(desc, code) { test_that(desc, { # Store original state original_username <- getOption("copernicus.username") original_password <- getOption("copernicus.password") original_env_user <- Sys.getenv("COPERNICUS_USERNAME", unset = NA) original_env_pass <- Sys.getenv("COPERNICUS_PASSWORD", unset = NA) # Multiple levels of cleanup complete_cleanup() # Use withr for maximum isolation - more conservative approach withr::with_options( list(copernicus.username = NULL, copernicus.password = NULL), withr::with_envvar( c( COPERNICUS_USERNAME = NA, COPERNICUS_PASSWORD = NA ), { # Verify it's actually clean expect_null(getOption("copernicus.username")) expect_null(getOption("copernicus.password")) expect_equal(Sys.getenv("COPERNICUS_USERNAME", unset = ""), "") expect_equal(Sys.getenv("COPERNICUS_PASSWORD", unset = ""), "") # Execute the test code tryCatch({ force(code) }, error = function(e) { # Always restore state on error if (!is.null(original_username)) options(copernicus.username = original_username) if (!is.null(original_password)) options(copernicus.password = original_password) if (!is.na(original_env_user)) Sys.setenv(COPERNICUS_USERNAME = original_env_user) if (!is.na(original_env_pass)) Sys.setenv(COPERNICUS_PASSWORD = original_env_pass) stop(e) }) } ) ) # Final cleanup complete_cleanup() # Restore original state if needed if (!is.null(original_username)) options(copernicus.username = original_username) if (!is.null(original_password)) options(copernicus.password = original_password) if (!is.na(original_env_user)) Sys.setenv(COPERNICUS_USERNAME = original_env_user) if (!is.na(original_env_pass)) Sys.setenv(COPERNICUS_PASSWORD = original_env_pass) }) } # Rest of helper functions remain the same... create_test_credentials <- function(username = "test_user", password = "test_pass") { options(copernicus.username = username) options(copernicus.password = password) invisible(list(username = username, password = password)) } cleanup_test_files <- function(pattern = "^test_.*\\.nc$") { test_files <- list.files(pattern = pattern) if (length(test_files) > 0) { file.remove(test_files) } invisible(NULL) } create_mock_module <- function(should_fail = TRUE) { if (should_fail) { list( subset = function(...) stop("Mock download - no real connection"), open_dataset = function(...) stop("Mock open_dataset - no real connection") ) } else { list( subset = function(...) list(status = "success", file = "mock_file.nc"), open_dataset = function(...) list(status = "success", dataset = "mock_dataset") ) } }