library(testthat) library(rIACI) library(reticulate) # Python virtual environment test_that("Set up Python virtual environment", { skip_on_cran() skip_if_not_installed("reticulate") if (!py_available(initialize = FALSE)) { skip("No Python available in this environment, skipping Python tests.") } env_dir <- file.path(tempdir(), "test_py_env") if (!dir.exists(env_dir)) { message("Creating Python virtual environment at: ", env_dir) virtualenv_create(env_dir) message("Installing Python packages...") py_install( packages = c("xarray", "pandas", "numpy", "netCDF4", "dask"), envname = env_dir ) } use_virtualenv(env_dir, required = TRUE) xarray <- import("xarray", convert = FALSE) expect_true(!is.null(xarray), "xarray should be available after installation.") }) ### 1: download_data test_that("Integrated Test: download_data", { skip_on_cran() if (tolower(Sys.info()[["sysname"]]) == "linux" && Sys.getenv("GITHUB_ACTIONS") == "true") { skip("Skipping download test on Linux GitHub Actions due to keyring creation issues.") } # Define parameters for the download request start_year <- 2020 end_year <- 2020 start_month <- 1 end_month <- 1 variables <- c("2m_temperature", "total_precipitation") dataset <- "reanalysis-era5-land" area <- c(44, -10, 36, 4) # Create a temporary directory for downloaded data output_dir <- tempfile("cds_data_") dir.create(output_dir) # Retrieve ECMWF credentials from environment variables user_id <- Sys.getenv("ECMWF_USER_ID") user_key <- Sys.getenv("ECMWF_USER_KEY") # Skip the test if credentials are not set if (user_id == "" || user_key == "") { skip("ECMWF_USER_ID or ECMWF_USER_KEY not set, skipping download test") } # Call the download_data function to request data download download_data( start_year = start_year, end_year = end_year, start_month = start_month, end_month = end_month, variables = variables, dataset = dataset, area = area, output_dir = output_dir, user_id = user_id, user_key = user_key, max_retries = 1, retry_delay = 0, timeout = 7200 ) # Check that the downloaded file exists (either a .zip or .nc file) expected_nc <- file.path(output_dir, "2020_01.nc") expect_true(file.exists(expected_nc)) }) ### 2: process_data test_that("Integrated Test: process_data", { skip_on_cran() skip_if_not_installed("reticulate") skip_if(!py_available(initialize = FALSE), "No Python available, skipping...") input_dir <- system.file("extdata", "testdata", package = "rIACI") expect_true(nchar(input_dir) > 0, info = "Cannot locate the 'testdata' directory in extdata") # Create a temporary directory for processed data output output_dir <- tempfile("processed_data_") dir.create(output_dir) # Call the process_data function to process the test data process_data(input_dir = input_dir, output_dir = output_dir, save_merged = FALSE) # Check that the processed data output directory contains files output_files <- list.files(output_dir) expect_gt(length(output_files), 0) }) #3. export_data_to_csv test_that("export_data_to_csv() with Python (skip on CRAN)", { skip_on_cran() skip_if_not_installed("reticulate") skip_if(!py_available(initialize = FALSE), "No Python available, skipping...") netcdf_file <- system.file("extdata", "testdata.nc", package = "rIACI") expect_true(file.exists(netcdf_file), info = "NetCDF file does not exist. Check path.") csv_output_dir <- tempfile("csv_output") dir.create(csv_output_dir) expect_error( export_data_to_csv(nc_file = netcdf_file, output_dir = csv_output_dir), NA ) csv_files <- list.files(csv_output_dir, pattern = "\\.csv$", full.names = TRUE) expect_true(length(csv_files) > 0, info = "No CSV files were generated by export_data_to_csv.") required_cols <- c("TMAX", "TMIN", "PRCP", "WP", "time") for (file in csv_files) { df <- read.csv(file) missing_cols <- setdiff(required_cols, names(df)) expect_true(length(missing_cols) == 0, info = paste("File", basename(file), "is missing columns:", paste(missing_cols, collapse = ", "))) } }) #4. Output all test_that("Integrated test: output_all (monthly & seasonal)", { csv_dir <- system.file("extdata", "test_output", package = "rIACI") expect_true(dir.exists(csv_dir), info = "Directory 'test_output' not found in inst/extdata") original_csv_files <- list.files(csv_dir, pattern = "\\.csv$", full.names = TRUE) expect_true(length(original_csv_files) > 0, info = "No CSV files found in 'test_output' directory") csv_output_dir <- tempfile("csv_output") dir.create(csv_output_dir) file.copy(original_csv_files, csv_output_dir) copied_csv_files <- list.files(csv_output_dir, pattern = "\\.csv$", full.names = TRUE) expect_true(length(copied_csv_files) > 0, info = "No CSV files were copied to the temporary directory.") required_cols <- c("TMAX", "TMIN", "PRCP", "WP", "time") for (csvfile in copied_csv_files) { df <- read.csv(csvfile) missing_cols <- setdiff(required_cols, names(df)) expect_true(length(missing_cols) == 0, info = paste("File", basename(csvfile), "is missing columns:", paste(missing_cols, collapse = ", "))) } sea_dates <- seq(as.Date("1960-01-01"), as.Date("2023-12-01"), by = "month") sea_dates <- format(sea_dates, "%Y-%m") sea_values <- rep(NA, length(sea_dates)) si <- sea_input(Date = sea_dates, Value = sea_values) # ----------------------- # a) Monthly # ----------------------- monthly_output_dir_parent <- tempfile("iaci_monthly_results") expect_error( output_all( si = si, input_dir = csv_output_dir, output_dir = monthly_output_dir_parent, freq = "monthly", base.range = c(1961, 1990), time.span = c(1961, 2023) ), NA ) monthly_output_dir <- file.path(monthly_output_dir_parent, "monthly") expect_true(dir.exists(monthly_output_dir), info = "output_all did not create a 'monthly' directory.") monthly_files <- list.files(monthly_output_dir, pattern = "\\.csv$") expect_true(length(monthly_files) > 0, info = "No CSV files generated in the monthly output directory.") sample_monthly <- read.csv(file.path(monthly_output_dir, monthly_files[1])) expect_true("IACI" %in% names(sample_monthly), info = "Monthly output CSV does not contain 'IACI' column.") # ----------------------- # b) Seasonal # ----------------------- seasonal_output_dir_parent <- tempfile("iaci_seasonal_results") expect_error( output_all( si = si, input_dir = csv_output_dir, # ????????? CSV ??? output_dir = seasonal_output_dir_parent, freq = "seasonal", base.range = c(1961, 1990), time.span = c(1961, 2023) ), NA ) seasonal_output_dir <- file.path(seasonal_output_dir_parent, "seasonal") expect_true(dir.exists(seasonal_output_dir), info = "output_all did not create a 'seasonal' directory.") seasonal_files <- list.files(seasonal_output_dir, pattern = "\\.csv$") expect_true(length(seasonal_files) > 0, info = "No CSV files generated in the seasonal output directory.") sample_seasonal <- read.csv(file.path(seasonal_output_dir, seasonal_files[1])) expect_true("IACI" %in% names(sample_seasonal), info = "Seasonal output CSV does not contain 'IACI' column.") }) #5. csv_to_nc test_that("csv_to_netcdf() [Python call]", { skip_on_cran() skip_if_not_installed("reticulate") skip_if(!py_available(initialize = FALSE), "No Python available, skipping...") csv_dir <- system.file("extdata", "testcsv", package = "rIACI") expect_true(dir.exists(csv_dir), info = "Directory inst/extdata/testcsv not found or not installed with the package.") merged_netcdf <- tempfile(fileext = ".nc") expect_error(csv_to_netcdf(csv_dir = csv_dir, output_file = merged_netcdf, freq = "monthly"),NA) expect_true(file.exists(merged_netcdf), info = "csv_to_netcdf did not generate the merged NetCDF file.") })