From 4fdc96a5dd48711a7f5168ad2387fc69dbb93a8c Mon Sep 17 00:00:00 2001 From: Anthony Sena Date: Mon, 21 Aug 2023 15:45:42 -0400 Subject: [PATCH] Create .zip with test module for testing --- .github/workflows/R_CMD_check_Hades.yaml | 4 +- R/ModuleInstantiation.R | 53 +++++++----------- extras/PackageMaintenance.R | 30 +++++++++- .../TestModule1-0.0.1}/.Rprofile | 0 .../TestModule1-0.0.1}/.renvignore | 0 .../TestModule1-0.0.1}/Main.R | 0 .../TestModule1-0.0.1}/MetaData.json | 0 .../TestModule1-0.0.1}/SettingsFunctions.R | 0 .../TestModule1-0.0.1}/TestModule1.Rproj | 0 .../extras/CreateJobContextForTesting.R | 0 .../TestModule1-0.0.1}/renv.lock | 0 .../TestModule1-0.0.1}/renv/.gitignore | 0 .../TestModule1-0.0.1}/renv/activate.R | 0 .../TestModule1-0.0.1}/renv/settings.dcf | 0 .../TestModule1-0.0.1}/renv/settings.json | 0 .../TestModule1-0.0.1}/tests/test-eunomia.R | 0 .../tests/testJobContext.rds | Bin .../TestModule1-0.0.1}/tests/testScript.R | 0 inst/testdata/TestModule1_0.0.1.zip | Bin 0 -> 32257 bytes ...son => unitTestAnalysisSpecification.json} | 0 tests/testthat/test-Strategus.R | 2 +- 21 files changed, 52 insertions(+), 37 deletions(-) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/.Rprofile (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/.renvignore (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/Main.R (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/MetaData.json (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/SettingsFunctions.R (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/TestModule1.Rproj (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/extras/CreateJobContextForTesting.R (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/renv.lock (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/renv/.gitignore (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/renv/activate.R (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/renv/settings.dcf (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/renv/settings.json (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/tests/test-eunomia.R (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/tests/testJobContext.rds (100%) rename {inst/testdata/TestModules/TestModule1 => extras/TestModule1-0.0.1}/tests/testScript.R (100%) create mode 100644 inst/testdata/TestModule1_0.0.1.zip rename inst/testdata/{testModuleAnalysisSpecification.json => unitTestAnalysisSpecification.json} (100%) diff --git a/.github/workflows/R_CMD_check_Hades.yaml b/.github/workflows/R_CMD_check_Hades.yaml index ab339fc3..a6ce7e71 100644 --- a/.github/workflows/R_CMD_check_Hades.yaml +++ b/.github/workflows/R_CMD_check_Hades.yaml @@ -20,8 +20,8 @@ jobs: fail-fast: false matrix: config: - - {os: windows-latest, r: '4.2.3', rtools: '42', rspm: "https://cloud.r-project.org"} - - {os: macOS-latest, r: '4.2.3', rtools: '42', rspm: "https://cloud.r-project.org"} + #- {os: windows-latest, r: '4.2.3', rtools: '42', rspm: "https://cloud.r-project.org"} + #- {os: macOS-latest, r: '4.2.3', rtools: '42', rspm: "https://cloud.r-project.org"} - {os: ubuntu-20.04, r: '4.2.3', rtools: '42', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} #- {os: windows-latest, r: 'release', rtools: '', rspm: "https://cloud.r-project.org"} #- {os: macOS-latest, r: 'release', rtools: '', rspm: "https://cloud.r-project.org"} diff --git a/R/ModuleInstantiation.R b/R/ModuleInstantiation.R index ac622378..753d8560 100644 --- a/R/ModuleInstantiation.R +++ b/R/ModuleInstantiation.R @@ -144,44 +144,33 @@ instantiateModule <- function(module, version, remoteRepo, remoteUsername, modul dir.create(moduleFolder) success <- FALSE on.exit(if (!success) unlink(moduleFolder, recursive = TRUE)) + moduleFile <- file.path(moduleFolder, sprintf("%s_%s.zip", module, version)) if (module == "TestModule1") { - # For test purposes only: get module from extras folder - files <- list.files( - system.file( - "testdata/TestModules/TestModule1", - package = "Strategus" + # For unit testing purposes only: get module from inst/testdata folder + file.copy( + from = system.file( + file.path("testdata", basename(moduleFile)), + package = utils::packageName() ), - full.names = TRUE, - include.dirs = TRUE, - all.files = TRUE + to = moduleFolder ) - files <- c(files, list.files("extras/TestModules/TestModule1/renv", full.names = TRUE, include.dirs = FALSE, all.files = TRUE)) - print(paste0("DEBUG 1: ", files)) - #files <- files[!grepl("extras/TestModules/TestModule1/renv/library", files)] - files <- files[!grepl("\\.$", files)] - files <- files[!grepl(".Rhistory$", files)] - print(paste0("DEBUG 2: ", files)) - file.copy(files, moduleFolder, recursive = TRUE) - #dir.create(file.path(moduleFolder, "renv")) - #file.copy("extras/TestModules/TestModule1/renv/activate.R", file.path(moduleFolder, "renv"), recursive = TRUE) } else { - moduleFile <- file.path(moduleFolder, sprintf("%s_%s.zip", module, version)) moduleUrl <- sprintf("https://%s/%s/%s/archive/refs/tags/v%s.zip", remoteRepo, remoteUsername, module, version) utils::download.file(url = moduleUrl, destfile = moduleFile) - utils::unzip(zipfile = moduleFile, exdir = moduleFolder) - unlink(moduleFile) - # At this point, the unzipped folders will likely exist in a sub folder. - # Move all files from that sub folder to the main module folder - subFolders <- list.dirs(path = moduleFolder, recursive = FALSE) - if (length(subFolders) > 0) { - for (i in 1:length(subFolders)) { - R.utils::copyDirectory( - from = subFolders[i], - to = moduleFolder, - recursive = TRUE - ) - unlink(subFolders[i], recursive = TRUE) - } + } + utils::unzip(zipfile = moduleFile, exdir = moduleFolder) + unlink(moduleFile) + # At this point, the unzipped folders will likely exist in a sub folder. + # Move all files from that sub folder to the main module folder + subFolders <- list.dirs(path = moduleFolder, recursive = FALSE) + if (length(subFolders) > 0) { + for (i in 1:length(subFolders)) { + R.utils::copyDirectory( + from = subFolders[i], + to = moduleFolder, + recursive = TRUE + ) + unlink(subFolders[i], recursive = TRUE) } } diff --git a/extras/PackageMaintenance.R b/extras/PackageMaintenance.R index c8dfdb98..f465aaac 100644 --- a/extras/PackageMaintenance.R +++ b/extras/PackageMaintenance.R @@ -115,6 +115,32 @@ unlink("inst/doc/IntroductionToStrategus.tex") pkgdown::build_site() OhdsiRTools::fixHadesLogo() +# Repackage the test module for unit testing +# NOTE: This is only necessary when the TestModule +# has been updated +testModuleRootFolder <- "extras/TestModule1-0.0.1" +targetModuleZipFile <- "TestModule1_0.0.1.zip" +testModuleFilesToRemove <- c( + file.path(testModuleRootFolder, ".RData"), + file.path(testModuleRootFolder, ".Rhistory") +) +testModuleDirToRemove <- c( + file.path(testModuleRootFolder, ".Rproj.user"), + file.path(testModuleRootFolder, "renv/library") +) +unlink(testModuleFilesToRemove) +unlink(testModuleDirToRemove, recursive = TRUE) - - +oldwd <- getwd() +setwd("extras") +zip::zip( + zipfile = targetModuleZipFile, + files = list.files("TestModule1-0.0.1", all.files = TRUE, recursive = TRUE, include.dirs = TRUE, full.names = TRUE) +) +file.copy( + from = targetModuleZipFile, + to = file.path("../inst/testdata", targetModuleZipFile), + overwrite = TRUE +) +file.remove(targetModuleZipFile) +setwd(oldwd) diff --git a/inst/testdata/TestModules/TestModule1/.Rprofile b/extras/TestModule1-0.0.1/.Rprofile similarity index 100% rename from inst/testdata/TestModules/TestModule1/.Rprofile rename to extras/TestModule1-0.0.1/.Rprofile diff --git a/inst/testdata/TestModules/TestModule1/.renvignore b/extras/TestModule1-0.0.1/.renvignore similarity index 100% rename from inst/testdata/TestModules/TestModule1/.renvignore rename to extras/TestModule1-0.0.1/.renvignore diff --git a/inst/testdata/TestModules/TestModule1/Main.R b/extras/TestModule1-0.0.1/Main.R similarity index 100% rename from inst/testdata/TestModules/TestModule1/Main.R rename to extras/TestModule1-0.0.1/Main.R diff --git a/inst/testdata/TestModules/TestModule1/MetaData.json b/extras/TestModule1-0.0.1/MetaData.json similarity index 100% rename from inst/testdata/TestModules/TestModule1/MetaData.json rename to extras/TestModule1-0.0.1/MetaData.json diff --git a/inst/testdata/TestModules/TestModule1/SettingsFunctions.R b/extras/TestModule1-0.0.1/SettingsFunctions.R similarity index 100% rename from inst/testdata/TestModules/TestModule1/SettingsFunctions.R rename to extras/TestModule1-0.0.1/SettingsFunctions.R diff --git a/inst/testdata/TestModules/TestModule1/TestModule1.Rproj b/extras/TestModule1-0.0.1/TestModule1.Rproj similarity index 100% rename from inst/testdata/TestModules/TestModule1/TestModule1.Rproj rename to extras/TestModule1-0.0.1/TestModule1.Rproj diff --git a/inst/testdata/TestModules/TestModule1/extras/CreateJobContextForTesting.R b/extras/TestModule1-0.0.1/extras/CreateJobContextForTesting.R similarity index 100% rename from inst/testdata/TestModules/TestModule1/extras/CreateJobContextForTesting.R rename to extras/TestModule1-0.0.1/extras/CreateJobContextForTesting.R diff --git a/inst/testdata/TestModules/TestModule1/renv.lock b/extras/TestModule1-0.0.1/renv.lock similarity index 100% rename from inst/testdata/TestModules/TestModule1/renv.lock rename to extras/TestModule1-0.0.1/renv.lock diff --git a/inst/testdata/TestModules/TestModule1/renv/.gitignore b/extras/TestModule1-0.0.1/renv/.gitignore similarity index 100% rename from inst/testdata/TestModules/TestModule1/renv/.gitignore rename to extras/TestModule1-0.0.1/renv/.gitignore diff --git a/inst/testdata/TestModules/TestModule1/renv/activate.R b/extras/TestModule1-0.0.1/renv/activate.R similarity index 100% rename from inst/testdata/TestModules/TestModule1/renv/activate.R rename to extras/TestModule1-0.0.1/renv/activate.R diff --git a/inst/testdata/TestModules/TestModule1/renv/settings.dcf b/extras/TestModule1-0.0.1/renv/settings.dcf similarity index 100% rename from inst/testdata/TestModules/TestModule1/renv/settings.dcf rename to extras/TestModule1-0.0.1/renv/settings.dcf diff --git a/inst/testdata/TestModules/TestModule1/renv/settings.json b/extras/TestModule1-0.0.1/renv/settings.json similarity index 100% rename from inst/testdata/TestModules/TestModule1/renv/settings.json rename to extras/TestModule1-0.0.1/renv/settings.json diff --git a/inst/testdata/TestModules/TestModule1/tests/test-eunomia.R b/extras/TestModule1-0.0.1/tests/test-eunomia.R similarity index 100% rename from inst/testdata/TestModules/TestModule1/tests/test-eunomia.R rename to extras/TestModule1-0.0.1/tests/test-eunomia.R diff --git a/inst/testdata/TestModules/TestModule1/tests/testJobContext.rds b/extras/TestModule1-0.0.1/tests/testJobContext.rds similarity index 100% rename from inst/testdata/TestModules/TestModule1/tests/testJobContext.rds rename to extras/TestModule1-0.0.1/tests/testJobContext.rds diff --git a/inst/testdata/TestModules/TestModule1/tests/testScript.R b/extras/TestModule1-0.0.1/tests/testScript.R similarity index 100% rename from inst/testdata/TestModules/TestModule1/tests/testScript.R rename to extras/TestModule1-0.0.1/tests/testScript.R diff --git a/inst/testdata/TestModule1_0.0.1.zip b/inst/testdata/TestModule1_0.0.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..843827f194a1997c72fa1151ada68aa3a24f6888 GIT binary patch literal 32257 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