Skip to content

Commit

Permalink
Merge pull request #285 from InstituteforDiseaseModeling/charles/issu…
Browse files Browse the repository at this point in the history
…e201
  • Loading branch information
celiot-IDM authored Jul 19, 2023
2 parents ed06e6f + ee1295a commit e64ce85
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 29 deletions.
16 changes: 11 additions & 5 deletions pacehrh/R/pace_lint.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#' @param outputFile Results output file. If NULL, results are printed to the console.
#' @param scenarioSheet Name of the sheet with scenario details. Default = "Scenarios".
#' @param seasonalityOffsetsSheet Name of the sheet with per-task seasonality offset details. Default = "SeasonalityOffsets"
#' @param noDate Suppress date stamp from output. Default = FALSE.
#'
#' @return Error code.
#' 0 = Success
Expand All @@ -33,7 +34,8 @@
CheckInputExcelFileFormat <- function(inputFile = NULL,
outputFile = NULL,
scenarioSheet = "Scenarios",
seasonalityOffsetsSheet = "SeasonalityOffsets") {
seasonalityOffsetsSheet = "SeasonalityOffsets",
noDate = FALSE) {

# This is a wrapper function that controls whether report output is directed
# to the console or a file. The real action is in the called function:
Expand All @@ -46,19 +48,23 @@ CheckInputExcelFileFormat <- function(inputFile = NULL,
}

if (is.null(outputFile)){
errcode <- .checkInputExcelFileFormat(inputFile, scenarioSheet, seasonalityOffsetsSheet)
errcode <- .checkInputExcelFileFormat(inputFile, scenarioSheet, seasonalityOffsetsSheet, noDate)
} else {
withr::with_output_sink(outputFile, code = {
errcode <- .checkInputExcelFileFormat(inputFile, scenarioSheet, seasonalityOffsetsSheet)
errcode <- .checkInputExcelFileFormat(inputFile, scenarioSheet, seasonalityOffsetsSheet, noDate)
})
}

return(errcode)
}

.checkInputExcelFileFormat <- function(inputFile, scenarioSheet, seasonalityOffsetsSheet){
.checkInputExcelFileFormat <- function(inputFile, scenarioSheet, seasonalityOffsetsSheet, noDate){
.catLine()
.catLine(date())

if (!noDate){
.catLine(date())
}

.catLine("Input file = ", inputFile)

# Create a place for the criticalChecks() functions to write some return
Expand Down
5 changes: 4 additions & 1 deletion pacehrh/man/CheckInputExcelFileFormat.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

185 changes: 185 additions & 0 deletions pacehrh/tests/testthat/_snaps/pace_lint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# Lint: basic

Code
errCode <- pacehrh::CheckInputExcelFileFormat(noDate = TRUE)
Output
Input file = ../../config/model_inputs.xlsx
Sheet references from scenarios ... OK
No duplicate tasks in seasonality offsets table ... OK
The following tasks in the scenario offsets table are not used in task values sheets ...
- TV_Comprehensive : OK
* TV_Basic : FH.MN.D.3
* TV_Basic : FH.MN.D.5
* TV_Basic : FH.MN.D.4
* TV_Basic : FH.MN.PNC.8
* TV_Merged : FH.MN.ANC.2
* TV_Merged : FH.MN.D.3
* TV_Merged : FH.MN.D.5
* TV_Merged : FH.MN.D.4
* TV_Merged : FH.MN.PNC.8
* TV_Merged : FH.MN.21A
* TV_Merged : FH.Ntr.68
* TV_Merged : FH.MN.21
* TV_Merged : FH.MN.22
* TV_Merged : DPC.Mlr.103A
* TV_Merged : DPC.Mlr.103B
* TV_Merged : DPC.Mlr.103C
* TV_Merged : DPC.Mlr.104A
* TV_Merged : DPC.Mlr.104B
The following tasks are duplicated in task values sheets ...
- TV_Comprehensive : OK
- TV_Basic : OK
- TV_Merged : OK
The following numeric columns contain non-numeric values ...
- TV_Comprehensive : OK
- TV_Basic : OK
- TV_Merged : OK
The following seasonality curves aren't normalized to 1 ...
- TV_Comprehensive : OK
Test results: 0-0-1-0-0-0

---

Code
errCode <- pacehrh::CheckInputExcelFileFormat(noDate = TRUE)
Output
Input file = ./bad_config/model_inputs-malformed.xlsx
The following sheets referenced by scenarios do not exist ...
* NotASheet
* AlsoNotASheet
The following tasks are duplicated in the seasonality offsets table ...
* DPC.TB.1
* DPC.M.2ChTP
The following tasks in the scenario offsets table are not used in task values sheets ...
* TaskValues : DPC.M.2
* TaskValues : NotATaskID
* TEST_TaskValues_1 : FH.MC.1
* TEST_TaskValues_1 : FH.MC.2
* TEST_TaskValues_1 : FH.MC.3
* TEST_TaskValues_1 : FH.MC.4
* TEST_TaskValues_1 : FH.MC.5
* TEST_TaskValues_1 : FH.Im.1
* TEST_TaskValues_1 : FH.Im.2
* TEST_TaskValues_1 : FH.Im.3
* TEST_TaskValues_1 : FH.Im.4
* TEST_TaskValues_1 : FH.N.1
* TEST_TaskValues_1 : FH.N.2
* TEST_TaskValues_1 : FH.N.3
* TEST_TaskValues_1 : FH.N.4
* TEST_TaskValues_1 : DPC.M.1AdTP
* TEST_TaskValues_1 : DPC.M.1ChTP
* TEST_TaskValues_1 : DPC.M.1neg
* TEST_TaskValues_1 : DPC.M.2AdTP
* TEST_TaskValues_1 : DPC.M.2ChTP
* TEST_TaskValues_1 : DPC.M.2
* TEST_TaskValues_1 : DPC.TB.1
* TEST_TaskValues_1 : DPC.TB.2
* TEST_TaskValues_1 : DPC.TB.3
* TEST_TaskValues_1 : NotATaskID
The following tasks are duplicated in task values sheets ...
* TaskValues : FH.MC.1
* TaskValues : FH.MC.2
* TaskValues : FH.MC.3
* TaskValues : FH.MC.4
* TaskValues : FH.MC.5
* TaskValues : FH.MC.6
* TaskValues : FH.MC.7
* TaskValues : FH.MC.8
* TaskValues : FH.Im.1
* TaskValues : FH.Im.2
* TaskValues : FH.Im.3
* TaskValues : FH.Im.4
* TaskValues : FH.Im.5
* TaskValues : FH.N.1
* TaskValues : FH.N.2
* TaskValues : FH.N.3
* TaskValues : FH.N.4
* TaskValues : Travel
* TaskValues : Administration
* TaskValues : Record keeping
* TaskValues : MHH
* TaskValues : DPC.TB.1
* TaskValues : DPC.TB.2
* TaskValues : DPC.TB.3
* TaskValues : DPC.M.1AdTP
* TaskValues : DPC.M.2AdTP
* TaskValues : DPC.M.1ChTP
* TaskValues : DPC.M.2ChTP
* TaskValues : DPC.M.1neg
* TaskValues : DPC.M.3
* TaskValues : DPC.FA.1
* TaskValues : DPC.H.1
* TaskValues : DPC.H.2
* TaskValues : DPC.CVD.1
* TaskValues : DPC.D.1
* TaskValues : DPC.D.2
* TaskValues : DPC.MH.2
* TaskValues : DPC.MH.3
* TaskValues : DPC.NTD.3
* TaskValues : DPC.HIV.1
* TaskValues : DPC.HIV.3
* TaskValues : DPC.HIV.2
* TaskValues : FH.FP.1A
* TaskValues : FH.FP.1B
* TaskValues : FH.FP.1C
* TaskValues : FH.FP.1D
* TaskValues : FH.FP.2
* TaskValues : FH.FP.3
* TaskValues : FH.FP.4
* TaskValues : FH.FP.5
* TaskValues : FH.FP.6
- TEST_TaskValues_1 : OK
The following numeric columns contain non-numeric values ...
- TaskValues : OK
* TEST_TaskValues_1 : StartingRateInPop
* TEST_TaskValues_1 : RateMultiplier
The following seasonality curves aren't normalized to 1 ...
* TaskValues : Malnutrition (12)
* TaskValues : TB (11.948)
* TEST_TaskValues_1 : Malnutrition (12)
* TEST_TaskValues_1 : TB (11.948)
Test results: 1-1-1-1-1-1

# Lint: bad scenario sheet name

Code
errCode <- pacehrh::CheckInputExcelFileFormat(scenarioSheet = "notasheet",
noDate = TRUE)
Output
Input file = ../../config/model_inputs.xlsx
notasheet sheet could not be found

# Lint: bad seasonality offsets sheet name

Code
errCode <- pacehrh::CheckInputExcelFileFormat(seasonalityOffsetsSheet = "notasheet",
noDate = TRUE)
Output
Input file = ../../config/model_inputs.xlsx
notasheet sheet could not be found

# Lint: non-existent input file

Code
errCode <- pacehrh::CheckInputExcelFileFormat(inputFile = "notafile", noDate = TRUE)
Output
Input file = notafile
notafile not found

---

Code
errCode <- pacehrh::CheckInputExcelFileFormat(inputFile = "globalconfig.json",
noDate = TRUE)
Output
Input file = globalconfig.json
globalconfig.json could not be read
Error message: Error: Can't establish that the input is either xls or xlsx.

53 changes: 30 additions & 23 deletions pacehrh/tests/testthat/test-pace_lint.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,68 @@ withr::local_dir("..")
test_that("Lint: basic", {
e <- pacehrh:::GPE
local_vars("inputExcelFile", envir = e)
e$inputExcelFile <- "./config/model_inputs.xlsx"

e$inputExcelFile <- "../../config/model_inputs.xlsx"
outFile = "lintout_01_clean.txt"

# Check that linting produces an output file
errCode <- pacehrh::CheckInputExcelFileFormat(outputFile = outFile)
testthat::expect_true(file.exists(outFile))

if (file.exists(outFile)){
file.remove(outFile)
}

# Check that linting output is stable
testthat::expect_snapshot({
errCode <- pacehrh::CheckInputExcelFileFormat(noDate = TRUE)
})
})

# Basic operation: use default config file and scenario tab, redirect output to a file
test_that("Lint: basic", {
e <- pacehrh:::GPE
local_vars("inputExcelFile", envir = e)
e$inputExcelFile <- "./bad_config/model_inputs-malformed.xlsx"

outFile = "lintout_01_dirty.txt"
errCode <- pacehrh::CheckInputExcelFileFormat(outputFile = outFile)
testthat::expect_true(file.exists(outFile))
testthat::expect_snapshot({
errCode <- pacehrh::CheckInputExcelFileFormat(noDate = TRUE)
})
})

# Bad name for the scenarios sheet
test_that("Lint: bad scenario steet name", {
test_that("Lint: bad scenario sheet name", {
e <- pacehrh:::GPE
local_vars("inputExcelFile", envir = e)
e$inputExcelFile <- "./simple_config/model_inputs.xlsx"

outFile = "lintout_02.txt"
errCode <- pacehrh::CheckInputExcelFileFormat(outputFile = outFile, scenarioSheet = "notasheet")
testthat::expect_true(file.exists(outFile))
e$inputExcelFile <- "../../config/model_inputs.xlsx"
testthat::expect_snapshot({
errCode <- pacehrh::CheckInputExcelFileFormat(scenarioSheet = "notasheet", noDate = TRUE)
})
testthat::expect_equal(errCode, pacehrh:::.errScenarioSheetNotFound)
})

# Bad name for the seasonality offsets sheet
test_that("Lint: bad seasonality offsets sheet name", {
e <- pacehrh:::GPE
local_vars("inputExcelFile", envir = e)
e$inputExcelFile <- "./simple_config/model_inputs.xlsx"

outFile = "lintout_05.txt"
errCode <- pacehrh::CheckInputExcelFileFormat(outputFile = outFile, seasonalityOffsetsSheet = "notasheet")
testthat::expect_true(file.exists(outFile))
e$inputExcelFile <- "../../config/model_inputs.xlsx"
testthat::expect_snapshot({
errCode <- pacehrh::CheckInputExcelFileFormat(seasonalityOffsetsSheet = "notasheet", noDate = TRUE)
})
testthat::expect_equal(errCode, pacehrh:::.errSeasonalityOffsetSheetNotFound)
})

# Bad name for the input file
test_that("Lint: non-existent input file", {
outFile = "lintout_03.txt"
errCode <- pacehrh::CheckInputExcelFileFormat(inputFile = "notafile", outputFile = outFile)
testthat::expect_true(file.exists(outFile))
testthat::expect_snapshot({
errCode <- pacehrh::CheckInputExcelFileFormat(inputFile = "notafile", noDate = TRUE)
})
testthat::expect_equal(errCode, pacehrh:::.errInputFileNotFound)
})

# Valid input file name, but not an Excel file
test_that("Lint: non-existent input file", {
outFile = "lintout_04.txt"
errCode <- pacehrh::CheckInputExcelFileFormat(inputFile = "globalconfig.json", outputFile = outFile)
testthat::expect_true(file.exists(outFile))
testthat::expect_snapshot({
errCode <- pacehrh::CheckInputExcelFileFormat(inputFile = "globalconfig.json", noDate = TRUE)
})
testthat::expect_equal(errCode, pacehrh:::.errInputFileNotReadable)
})

Expand Down

0 comments on commit e64ce85

Please sign in to comment.