From 47e7dc2e9924758ad94f92f250ad19db965dd675 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Wed, 24 Jan 2024 11:40:43 +0100 Subject: [PATCH 01/18] chore: NEWS and DESCRIPTION development version v0.11.0.9000 --- DESCRIPTION | 4 ++-- NEWS | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index b537d0e..9f5055b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: NVIdb Title: Tools to facilitate the use of NVI's databases -Version: 0.11.0 -Date: 2024-01-24 +Version: 0.11.0.9000 +Date: 2024-##-## Authors@R: c(person(given = "Petter", family = "Hopp", diff --git a/NEWS b/NEWS index 47f6041..cf678e5 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,26 @@ +NVIdb 0.11.0.9000 - (2024-##-##) +---------------------------------------- + +New features: + +- + + +Bug fixes: + +- + + +Other changes: + +- + + +BREAKING CHANGES: + +- + + NVIdb 0.11.0 - (2024-01-24) ---------------------------------------- From 67f29ef0dabf1bda01c904ffc71b86ef33c3d144 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Fri, 26 Jan 2024 05:57:15 +0100 Subject: [PATCH 02/18] #34 test: updated test_set_disease_parameters Captured warning when using deprecated argument file. --- tests/testthat/test_set_disease_parameters.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test_set_disease_parameters.R b/tests/testthat/test_set_disease_parameters.R index 8786656..f399218 100644 --- a/tests/testthat/test_set_disease_parameters.R +++ b/tests/testthat/test_set_disease_parameters.R @@ -123,7 +123,8 @@ test_that("set disease parameters using parameter file", { con = file.path(tempdir(), "PD.R") ) - parameters <- set_disease_parameters(file = file.path(tempdir(), "PD.R")) + parameters <- expect_warning(set_disease_parameters(file = file.path(tempdir(), "PD.R")), + regexp = "The argument 'file' is deprecated") expect_equal(parameters, list("hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), "hensikt2delete" = NULL, From 8aa3c64ae418fff56a44f2d35012c11b6db0ba04 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Fri, 26 Jan 2024 05:58:31 +0100 Subject: [PATCH 03/18] #35 test: updated test_add_produsent-deprecated Captured warning when using deprecated add_produsent. --- .../testthat/test_add_produsent-deprecated.R | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/testthat/test_add_produsent-deprecated.R b/tests/testthat/test_add_produsent-deprecated.R index 7a3c0e7..1ee3a58 100644 --- a/tests/testthat/test_add_produsent-deprecated.R +++ b/tests/testthat/test_add_produsent-deprecated.R @@ -20,12 +20,13 @@ test_that("Correct merging of produsent og produsent properties", { # Compare Add fylke, current fylkenr and current fylke with correct result - produsenter <- NVIdb::add_produsent(data = produsenter, - translation_table = prodnr_2_gjeldende_prodnr, - code_column = "prodnr8", - new_column = "gjeldende_prodnr8", - position = "left", - overwrite = FALSE) + produsenter <- expect_warning(add_produsent(data = produsenter, + translation_table = prodnr_2_gjeldende_prodnr, + code_column = "prodnr8", + new_column = "gjeldende_prodnr8", + position = "left", + overwrite = FALSE), + regexp = "'add_produsent' is replaced by 'add_produsent_properties'") expect_identical(produsenter, correct_result) # COORDINATES @@ -39,10 +40,11 @@ test_that("Correct merging of produsent og produsent properties", { ) colnames(correct_result) <- c("gjeldende_prodnr8", "prodnr8", "longitude", "latitude") - produsenter <- add_produsent(data = produsenter, - translation_table = prodnr_2_koordinater, - code_column = c("gjeldende_prodnr8" = "prodnr8"), - new_column = c("longitude" = "geo_eu89_o", "latitude" = "geo_eu89_n"), - position = "last") + produsenter <- expect_warning(add_produsent(data = produsenter, + translation_table = prodnr_2_koordinater, + code_column = c("gjeldende_prodnr8" = "prodnr8"), + new_column = c("longitude" = "geo_eu89_o", "latitude" = "geo_eu89_n"), + position = "last"), + regexp = "'add_produsent' is replaced by 'add_produsent_properties'") expect_identical(produsenter, correct_result) }) From f03a74b9ae1d508826ff76a00f4a5501362db4ec Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Fri, 26 Jan 2024 07:53:19 +0100 Subject: [PATCH 04/18] test: improved test_set_dir_NVI Created tests for argument slash = FALSE --- tests/testthat/test_set_dir_NVI.R | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/testthat/test_set_dir_NVI.R b/tests/testthat/test_set_dir_NVI.R index 4c9c824..78baf61 100644 --- a/tests/testthat/test_set_dir_NVI.R +++ b/tests/testthat/test_set_dir_NVI.R @@ -25,6 +25,19 @@ test_that("set_dir_NVI with input ignoring case", { }) +test_that("set_dir_NVI with slash = FALSE", { + # skip if no connection to 'FAG' have been established + skip_if_not(dir.exists(set_dir_NVI("FAG"))) + + expect_true(dir.exists(set_dir_NVI("LevReg", slash = FALSE))) + expect_true(dir.exists(set_dir_NVI("PRodtilskudd", slash = FALSE))) + expect_true(dir.exists(set_dir_NVI("prodregister", slash = FALSE))) + expect_true(dir.exists(set_dir_NVI("GrunnDataLand", slash = FALSE))) + expect_true(dir.exists(set_dir_NVI("Provedata_rapportering", slash = FALSE))) + expect_true(dir.exists(set_dir_NVI("OkProgrammer", slash = FALSE))) + +}) + test_that("set_dir_NVI using abbreviated input", { # skip if no connection to 'FAG' have been established skip_if_not(dir.exists(set_dir_NVI("FAG"))) @@ -47,5 +60,8 @@ test_that("set_dir_NVI error testing", { expect_error(set_dir_NVI("p"), regexp = "but is 'p'. Abbreviated arguments can only be matched to one single value among the possible arguments.$") + expect_error(set_dir_NVI("FAG", slash = "FALSE"), + regexp = "Variable 'slash': Must be of type 'logical flag'") + options(width = unlist(linewidth)) }) From 1efe5693d05260d0c1725b0b46225be963d559c4 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Fri, 2 Feb 2024 17:09:39 +0100 Subject: [PATCH 05/18] fix: set_disease_parameters now accepts metodekode with 2 digits --- R/set_disease_parameters.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/set_disease_parameters.R b/R/set_disease_parameters.R index 3d36c32..f6425ae 100644 --- a/R/set_disease_parameters.R +++ b/R/set_disease_parameters.R @@ -169,7 +169,7 @@ set_disease_parameters <- function(hensikt2select = NULL, checkmate::assert_character(hensikt2select, min.chars = 2, max.chars = 15, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(hensikt2delete, min.chars = 2, max.chars = 15, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(utbrudd2select, max.chars = 5, any.missing = FALSE, null.ok = TRUE, add = checks) - checkmate::assert_character(metode2select, n.chars = 6, any.missing = FALSE, null.ok = TRUE, add = checks) + checkmate::assert_character(metode2select, min.chars = 2, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(analytt2select, min.chars = 2, max.chars = 20, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(analytt2delete, min.chars = 2, max.chars = 20, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(art2select, min.chars = 2, max.chars = 20, all.missing = FALSE, null.ok = TRUE, add = checks) From 83553b9ca221ec095fdbd5716d68185f39a2f6a1 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Fri, 2 Feb 2024 17:40:24 +0100 Subject: [PATCH 06/18] style: corrected typo in NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index cf678e5..873e0b7 100644 --- a/NEWS +++ b/NEWS @@ -26,7 +26,7 @@ NVIdb 0.11.0 - (2024-01-24) New features: -- Created `retrieve_PJS_data` to retrieve and standardisation of PJSdata. +- Created `retrieve_PJS_data` to retrieve and standardise PJSdata. - Created `transform_code_values` to easy transform few code combinations into other values. From 3663c375868e6748c054278da4d2691cd1773308 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Fri, 2 Feb 2024 22:43:27 +0100 Subject: [PATCH 07/18] style: styled lines in build_query_one_disease --- R/build_query_one_disease.R | 50 ++++++++++++++++++++++------------ man/build_query_one_disease.Rd | 50 ++++++++++++++++++++++------------ 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/R/build_query_one_disease.R b/R/build_query_one_disease.R index abd67ee..29627b4 100644 --- a/R/build_query_one_disease.R +++ b/R/build_query_one_disease.R @@ -1,25 +1,41 @@ #' @title Builds query for selecting data for one disease from PJS -#' @description Builds the query for selecting all data for one infection/disease within one year from PJS. The input is the analytter -#' for the infectious agent and/or disease, the hensikter and metoder specific for the infection and/or disease. The the query is -#' written in T-SQL as used by MS-SQL. +#' @description Builds the query for selecting all data for one +#' infection/disease within one year from PJS. The input is the +#' analytter for the infectious agent and/or disease, the +#' hensikter and metoder specific for the infection and/or +#' disease. The the query is written in T-SQL as used by MS-SQL. #' -#' @details The function builds the SQL syntax to select all PJS-journals concerning one infection and/o disease from PJS. This is based -#' on selecting all journals with the disease and/or infectious agent analytt in resultat, konklusjon or sakskonklusjon. By this, all -#' journals were the examination have been performed and a result has been entered should be selected. +#' @details The function builds the SQL syntax to select all PJS-journals +#' concerning one infection and/o disease from PJS. This is based +#' on selecting all journals with the disease and/or infectious +#' agent analytt in resultat, konklusjon or sakskonklusjon. By this, +#' all journals were the examination have been performed and a +#' result has been entered should be selected. #' -#' One or more specific hensikter may be input to the selection statement. With specific hensikt is meant a hensikt that will imply -#' that the sample will be examined for the infectious agent or disease. Thereby, the selection will include samples that haven't -#' been set up for examination yet, samples that were unfit for examination and samples for which wrong conclusions have been entered. +#' One or more specific hensikter may be input to the selection +#' statement. With specific hensikt is meant a hensikt that will +#' imply that the sample will be examined for the infectious agent +#' or disease. Thereby, the selection will include samples that +#' haven't been set up for examination yet, samples that were +#' unfit for examination and samples for which wrong conclusions +#' have been entered. #' -#' One or more specific metoder may be input to the selection statement. With specific metode is meant a metode that implies an -#' examination that will give one of the input analytter as a result. Thereby, the query will include samples that have been set up -#' for examination, but haven't been examined yet, samples that were unfit for examination and samples for which wrong results have -#' been entered. +#' One or more specific metoder may be input to the selection +#' statement. With specific metode is meant a metode that implies +#' an examination that will give one of the input analytter as a +#' result. Thereby, the query will include samples that have been +#' set up for examination, but haven't been examined yet, samples +#' that were unfit for examination and samples for which wrong +#' results have been entered. #' -#' To select both the disease analytt and the infectious agent analytt ensures that all journals that have been examined with a result -#' is included in the output. The inclusion of specific hensikter and metoder, if exists, ensures that all journals received with the -#' purpose of examining for the infectious agent and/or disease will be included even if the examination has not been performed. This -#' is important for a full control of all relevant data for an infectious agent and/or disease. +#' To select both the disease analytt and the infectious agent +#' analytt ensures that all journals that have been examined with +#' a result is included in the output. The inclusion of specific +#' hensikter and metoder, if exists, ensures that all journals +#' received with the purpose of examining for the infectious agent +#' and/or disease will be included even if the examination has +#' not been performed. This is important for a full control of +#' all relevant data for an infectious agent and/or disease. #' #' @template build_query_year #' @param analytt [\code{character}]\cr diff --git a/man/build_query_one_disease.Rd b/man/build_query_one_disease.Rd index 3107ac0..56d822f 100644 --- a/man/build_query_one_disease.Rd +++ b/man/build_query_one_disease.Rd @@ -36,28 +36,44 @@ is the only valid value.} A list with select-statement fom v2_sak_m_res and v_sakskonklusjon to be included in a \code{RODBC::sqlQuery}. } \description{ -Builds the query for selecting all data for one infection/disease within one year from PJS. The input is the analytter - for the infectious agent and/or disease, the hensikter and metoder specific for the infection and/or disease. The the query is - written in T-SQL as used by MS-SQL. +Builds the query for selecting all data for one + infection/disease within one year from PJS. The input is the + analytter for the infectious agent and/or disease, the + hensikter and metoder specific for the infection and/or + disease. The the query is written in T-SQL as used by MS-SQL. } \details{ -The function builds the SQL syntax to select all PJS-journals concerning one infection and/o disease from PJS. This is based - on selecting all journals with the disease and/or infectious agent analytt in resultat, konklusjon or sakskonklusjon. By this, all - journals were the examination have been performed and a result has been entered should be selected. +The function builds the SQL syntax to select all PJS-journals + concerning one infection and/o disease from PJS. This is based + on selecting all journals with the disease and/or infectious + agent analytt in resultat, konklusjon or sakskonklusjon. By this, + all journals were the examination have been performed and a + result has been entered should be selected. - One or more specific hensikter may be input to the selection statement. With specific hensikt is meant a hensikt that will imply - that the sample will be examined for the infectious agent or disease. Thereby, the selection will include samples that haven't - been set up for examination yet, samples that were unfit for examination and samples for which wrong conclusions have been entered. + One or more specific hensikter may be input to the selection + statement. With specific hensikt is meant a hensikt that will + imply that the sample will be examined for the infectious agent + or disease. Thereby, the selection will include samples that + haven't been set up for examination yet, samples that were + unfit for examination and samples for which wrong conclusions + have been entered. - One or more specific metoder may be input to the selection statement. With specific metode is meant a metode that implies an - examination that will give one of the input analytter as a result. Thereby, the query will include samples that have been set up - for examination, but haven't been examined yet, samples that were unfit for examination and samples for which wrong results have - been entered. + One or more specific metoder may be input to the selection + statement. With specific metode is meant a metode that implies + an examination that will give one of the input analytter as a + result. Thereby, the query will include samples that have been + set up for examination, but haven't been examined yet, samples + that were unfit for examination and samples for which wrong + results have been entered. - To select both the disease analytt and the infectious agent analytt ensures that all journals that have been examined with a result - is included in the output. The inclusion of specific hensikter and metoder, if exists, ensures that all journals received with the - purpose of examining for the infectious agent and/or disease will be included even if the examination has not been performed. This - is important for a full control of all relevant data for an infectious agent and/or disease. + To select both the disease analytt and the infectious agent + analytt ensures that all journals that have been examined with + a result is included in the output. The inclusion of specific + hensikter and metoder, if exists, ensures that all journals + received with the purpose of examining for the infectious agent + and/or disease will be included even if the examination has + not been performed. This is important for a full control of + all relevant data for an infectious agent and/or disease. } \examples{ # SQL-select query for Pancreatic disease (PD) From d556db08124ae130f5e0606bb05c7ef56095a993 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Fri, 2 Feb 2024 22:45:24 +0100 Subject: [PATCH 08/18] feat: improved set_disease_parameters Included the arguments purpose, FUN and select_statement --- R/set_disease_parameters.R | 43 +++++++++++++++++++++++++++++------ man/set_disease_parameters.Rd | 24 ++++++++++++++++++- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/R/set_disease_parameters.R b/R/set_disease_parameters.R index f6425ae..5b28a5b 100644 --- a/R/set_disease_parameters.R +++ b/R/set_disease_parameters.R @@ -12,6 +12,12 @@ #' a relevant "utbrudds_ID" and/or specific "metoder." These can be used to select #' saker in PJS and/or to structure and simplify the output from PJS. #' +#' The purpose is a short description of purpose of the selection described by the +#' selection parameters for example "ok_svin_virus" that describes the selection +#' parameters for the OK programme for virus in swine. The purpose is also used as +#' part of the file name for selection_parameters, i.e. "purpose_selection_parameters" +#' and in the annual tables for ok_programmer: Kontrolltabeller for yyyy. +#' #' One or more specific "hensiktkoder" may be input to the selection statement. #' With specific "hensiktkode" is meant a "hensiktkode" that will imply that the sample #' will be examined for specific infectious agent(s) or disease. One or more @@ -39,9 +45,11 @@ #' warning is issued and the input is transferred to \code{include_missing_art} and #' \code{selection_parameters}, respectively. #' +#' @param purpose [\code{character}]\cr +#' A short description of the purpose of the selection, see details. Defaults to NULL. #' @param hensikt2select [\code{character}]\cr #' Specific "hensiktkoder" for the "analytt" in question. If sub-codes should -#' be included, end the code with \%.Defaults to \code{NULL}. +#' be included, end the code with \%. Defaults to \code{NULL}. #' @param hensikt2delete [\code{character}]\cr #' "hensiktkoder" for which saker should be excluded. #' If sub-codes should be included, end the code with \%. Defaults to \code{NULL}. @@ -66,6 +74,14 @@ #' Either the path and file name for an R script that can be sourced and that #' sets the selection parameters or a named list with the selection parameters #' (i.e. equal to the output of this function). Defaults to \code{NULL}. +#' @param FUN [\code{function}]\cr +#' Function to build the selection statement, see +#' \ifelse{html}{\code{\link{retrieve_PJSdata}}}{\code{retrieve_PJSdata}}). +#' Defaults to \code{NULL}. +#' @param select_statement [\code{character(1)}]\cr +#' A written select statement, see +#' \ifelse{html}{\code{\link{retrieve_PJSdata}}}{\code{retrieve_PJSdata}}). +#' Defaults to \code{NULL}. #' @param \dots Other arguments to be passed to `set_disease_parameters`. #' #' @return A named list with selection parameters that can be used to generate @@ -80,7 +96,8 @@ #' hensikt2select = c("0100108018", "0100109003", "0100111003", "0800109"), #' metode2select = c("070070", "070231", "010057", "060265") #' ) -set_disease_parameters <- function(hensikt2select = NULL, +set_disease_parameters <- function(purpose = NULL, + hensikt2select = NULL, hensikt2delete = NULL, utbrudd2select = NULL, metode2select = NULL, @@ -88,15 +105,19 @@ set_disease_parameters <- function(hensikt2select = NULL, analytt2delete = NULL, art2select = NULL, include_missing_art = NULL, + FUN = NULL, + select_statement = NULL, selection_parameters = NULL, ...) { # SET SELECTION PARAMETERS ---- # Vector with possible selection parameter names # missing_art is deprecated - var2select_template <- c("hensikt2select", "hensikt2delete", "utbrudd2select", + var2select_template <- c("purpose", + "hensikt2select", "hensikt2delete", "utbrudd2select", "metode2select", "analytt2select", "analytt2delete", "art2select", - "include_missing_art", "missing_art") + "include_missing_art", "missing_art", + "FUN", "select_statement") # PREPARE ARGUMENTS BEFORE CHECKING ---- if ("file" %in% ...names() & is.null(selection_parameters)) { @@ -169,7 +190,7 @@ set_disease_parameters <- function(hensikt2select = NULL, checkmate::assert_character(hensikt2select, min.chars = 2, max.chars = 15, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(hensikt2delete, min.chars = 2, max.chars = 15, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(utbrudd2select, max.chars = 5, any.missing = FALSE, null.ok = TRUE, add = checks) - checkmate::assert_character(metode2select, min.chars = 2, any.missing = FALSE, null.ok = TRUE, add = checks) + checkmate::assert_character(metode2select, min.chars = 2, max.chars = 6, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(analytt2select, min.chars = 2, max.chars = 20, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(analytt2delete, min.chars = 2, max.chars = 20, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(art2select, min.chars = 2, max.chars = 20, all.missing = FALSE, null.ok = TRUE, add = checks) @@ -178,17 +199,25 @@ set_disease_parameters <- function(hensikt2select = NULL, choices = c("never", "always", "for_selected_hensikt"), add = checks) # } + checkmate::assert_function(FUN, null.ok = TRUE, add = checks) + checkmate::assert(checkmate::check_list(x = select_statement, null.ok = TRUE), + checkmate::check_string(x = select_statement), + combine = "or", + add = checks) # Report check-results checkmate::reportAssertions(checks) # CREATE LIST WITH PARAMETER VALUES ---- - return(list("hensikt2select" = hensikt2select, + return(list("purpose" = purpose, + "hensikt2select" = hensikt2select, "hensikt2delete" = hensikt2delete, "utbrudd2select" = utbrudd2select, "metode2select" = metode2select, "analytt2select" = analytt2select, "analytt2delete" = analytt2delete, "art2select" = art2select, - "include_missing_art" = include_missing_art)) + "include_missing_art" = include_missing_art, + "FUN" = FUN, + "select_statement" = select_statement)) } diff --git a/man/set_disease_parameters.Rd b/man/set_disease_parameters.Rd index 30b2f49..ec2adb8 100644 --- a/man/set_disease_parameters.Rd +++ b/man/set_disease_parameters.Rd @@ -5,6 +5,7 @@ \title{Sets disease selection parameters} \usage{ set_disease_parameters( + purpose = NULL, hensikt2select = NULL, hensikt2delete = NULL, utbrudd2select = NULL, @@ -13,14 +14,19 @@ set_disease_parameters( analytt2delete = NULL, art2select = NULL, include_missing_art = NULL, + FUN = NULL, + select_statement = NULL, selection_parameters = NULL, ... ) } \arguments{ +\item{purpose}{[\code{character}]\cr +A short description of the purpose of the selection, see details. Defaults to NULL.} + \item{hensikt2select}{[\code{character}]\cr Specific "hensiktkoder" for the "analytt" in question. If sub-codes should - be included, end the code with \%.Defaults to \code{NULL}.} + be included, end the code with \%. Defaults to \code{NULL}.} \item{hensikt2delete}{[\code{character}]\cr "hensiktkoder" for which saker should be excluded. @@ -49,6 +55,16 @@ Should missing art be included. Must be one of c("never", "always", "for_selecte If NULL, it is set to "always" when \code{art2select} includes NA, else it is set to "never". Defaults to \code{NULL}.} +\item{FUN}{[\code{function}]\cr +Function to build the selection statement, see + \ifelse{html}{\code{\link{retrieve_PJSdata}}}{\code{retrieve_PJSdata}}). + Defaults to \code{NULL}.} + +\item{select_statement}{[\code{character(1)}]\cr +A written select statement, see + \ifelse{html}{\code{\link{retrieve_PJSdata}}}{\code{retrieve_PJSdata}}). + Defaults to \code{NULL}.} + \item{selection_parameters}{[\code{character(1)}]\cr Either the path and file name for an R script that can be sourced and that sets the selection parameters or a named list with the selection parameters @@ -75,6 +91,12 @@ Saker in PJS that concern one infection / disease can be characterised a relevant "utbrudds_ID" and/or specific "metoder." These can be used to select saker in PJS and/or to structure and simplify the output from PJS. + The purpose is a short description of purpose of the selection described by the + selection parameters for example "ok_svin_virus" that describes the selection + parameters for the OK programme for virus in swine. The purpose is also used as + part of the file name for selection_parameters, i.e. "purpose_selection_parameters" + and in the annual tables for ok_programmer: Kontrolltabeller for yyyy. + One or more specific "hensiktkoder" may be input to the selection statement. With specific "hensiktkode" is meant a "hensiktkode" that will imply that the sample will be examined for specific infectious agent(s) or disease. One or more From 38e97d5950cd365b130e6cfa8c59ad2056dc2921 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Fri, 2 Feb 2024 22:46:41 +0100 Subject: [PATCH 09/18] test: updated test_set_disease_parameters Handles new arguments purpose, FUN, and select_statement --- tests/testthat/test_set_disease_parameters.R | 70 ++++++++++++++------ 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/tests/testthat/test_set_disease_parameters.R b/tests/testthat/test_set_disease_parameters.R index f399218..d48011e 100644 --- a/tests/testthat/test_set_disease_parameters.R +++ b/tests/testthat/test_set_disease_parameters.R @@ -6,25 +6,31 @@ test_that("set disease parameters by direct input", { analytt2select = c("01220104%", "1502010235"), metode2select = c("070070", "070231", "010057", "060265")) expect_equal(parameters, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), "hensikt2delete" = NULL, "utbrudd2select" = NULL, "metode2select" = c("070070", "070231", "010057", "060265"), "analytt2select" = c("01220104%", "1502010235"), "analytt2delete" = NULL, "art2select" = NULL, - "include_missing_art" = "never")) + "include_missing_art" = "never", + "FUN" = NULL, + "select_statement" = NULL)) parameters2 <- set_disease_parameters(selection_parameters = parameters) expect_equal(parameters2, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), "hensikt2delete" = NULL, "utbrudd2select" = NULL, "metode2select" = c("070070", "070231", "010057", "060265"), "analytt2select" = c("01220104%", "1502010235"), "analytt2delete" = NULL, "art2select" = NULL, - "include_missing_art" = "never")) + "include_missing_art" = "never", + "FUN" = NULL, + "select_statement" = NULL)) parameters <- set_disease_parameters(hensikt2select = c("0100108018", "0100109003", "0100111003"), @@ -33,25 +39,31 @@ test_that("set disease parameters by direct input", { analytt2select = c("01220104%", "1502010235"), metode2select = c("070070", "070231", "010057", "060265")) expect_equal(parameters, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003"), "hensikt2delete" = c("0800109"), "utbrudd2select" = "22", "metode2select" = c("070070", "070231", "010057", "060265"), "analytt2select" = c("01220104%", "1502010235"), "analytt2delete" = NULL, "art2select" = NULL, - "include_missing_art" = "never")) + "include_missing_art" = "never", + "FUN" = NULL, + "select_statement" = NULL)) parameters2 <- set_disease_parameters(selection_parameters = parameters) expect_equal(parameters2, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003"), "hensikt2delete" = c("0800109"), "utbrudd2select" = "22", "metode2select" = c("070070", "070231", "010057", "060265"), "analytt2select" = c("01220104%", "1502010235"), "analytt2delete" = NULL, "art2select" = NULL, - "include_missing_art" = "never")) + "include_missing_art" = "never", + "FUN" = NULL, + "select_statement" = NULL)) parameters <- set_disease_parameters(hensikt2select = c("0100108018", "0100109003", "0100111003"), hensikt2delete = c("0800109"), @@ -60,14 +72,17 @@ test_that("set disease parameters by direct input", { art2select = c("01%"), include_missing_art = "never") expect_equal(parameters, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003"), "hensikt2delete" = c("0800109"), "utbrudd2select" = "22", "metode2select" = NULL, "analytt2select" = NULL, "analytt2delete" = NULL, "art2select" = c("01%"), - "include_missing_art" = "never")) + "include_missing_art" = "never", + "FUN" = NULL, + "select_statement" = NULL)) parameters <- set_disease_parameters(hensikt2select = c("0100108018", "0100109003", "0100111003"), hensikt2delete = c("0800109"), @@ -76,14 +91,17 @@ test_that("set disease parameters by direct input", { art2select = c("01%"), include_missing_art = NULL) expect_equal(parameters, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003"), "hensikt2delete" = c("0800109"), "utbrudd2select" = "22", "metode2select" = NULL, "analytt2select" = NULL, "analytt2delete" = NULL, "art2select" = c("01%"), - "include_missing_art" = "never")) + "include_missing_art" = "never", + "FUN" = NULL, + "select_statement" = NULL)) parameters <- set_disease_parameters(hensikt2select = c("0100108018", "0100109003", "0100111003"), hensikt2delete = c("0800109"), @@ -92,25 +110,31 @@ test_that("set disease parameters by direct input", { art2select = c("01%", NA), include_missing_art = NULL) expect_equal(parameters, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003"), "hensikt2delete" = c("0800109"), "utbrudd2select" = "22", "metode2select" = NULL, "analytt2select" = NULL, "analytt2delete" = NULL, "art2select" = c("01%", NA), - "include_missing_art" = "always")) + "include_missing_art" = "always", + "FUN" = NULL, + "select_statement" = NULL)) parameters2 <- set_disease_parameters(selection_parameters = parameters) expect_equal(parameters2, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003"), "hensikt2delete" = c("0800109"), "utbrudd2select" = "22", "metode2select" = NULL, "analytt2select" = NULL, "analytt2delete" = NULL, "art2select" = c("01%", NA), - "include_missing_art" = "always")) + "include_missing_art" = "always", + "FUN" = NULL, + "select_statement" = NULL)) }) @@ -126,25 +150,31 @@ test_that("set disease parameters using parameter file", { parameters <- expect_warning(set_disease_parameters(file = file.path(tempdir(), "PD.R")), regexp = "The argument 'file' is deprecated") expect_equal(parameters, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), "hensikt2delete" = NULL, "utbrudd2select" = NULL, "metode2select" = c("070070", "070231", "010057", "060265"), "analytt2select" = c("01220104%", "1502010235"), "analytt2delete" = NULL, "art2select" = NULL, - "include_missing_art" = "never")) + "include_missing_art" = "never", + "FUN" = NULL, + "select_statement" = NULL)) parameters <- set_disease_parameters(selection_parameters = file.path(tempdir(), "PD.R")) expect_equal(parameters, - list("hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003", "0800109"), "hensikt2delete" = NULL, "utbrudd2select" = NULL, "metode2select" = c("070070", "070231", "010057", "060265"), "analytt2select" = c("01220104%", "1502010235"), "analytt2delete" = NULL, "art2select" = NULL, - "include_missing_art" = "never")) + "include_missing_art" = "never", + "FUN" = NULL, + "select_statement" = NULL)) }) From 17124a6e3a13b02799418617f7d601a10b140a21 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Sun, 4 Feb 2024 00:25:20 +0100 Subject: [PATCH 10/18] test: updated test_PJS_code_description Included tests for errors in add_PJS_code_description --- tests/testthat/test_PJS_code_description.R | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/testthat/test_PJS_code_description.R b/tests/testthat/test_PJS_code_description.R index 08455b0..be6a0d7 100644 --- a/tests/testthat/test_PJS_code_description.R +++ b/tests/testthat/test_PJS_code_description.R @@ -245,4 +245,54 @@ test_that("Backward translation from description to code", { # # c("", "", "", "", "", "", "", "", "", "")) # }) +test_that("errors for add_PJS_code_description", { + + linewidth <- options("width") + options(width = 80) + + # skip if no connection to 'FAG' have been established + skip_if_not(dir.exists(set_dir_NVI("FAG"))) + + # Reads translation table for PJS-codes + PJS_codes_2_text <- read_PJS_codes_2_text() + + testdata <- as.data.frame(list("hensiktkode" = c("01001", "01002"), + "metodekode" = c("010001", "010002"), + "ansvarlig_seksjon" = c("01", "02"))) + + expect_error(add_PJS_code_description("testdata", + translation_table = PJS_codes_2_text, + code_colname = c("hensiktkode", "metodekode", "ansvarlig_seksjon"), + PJS_variable_type = c("hensikt", "metode", "seksjon"), + new_column = c("hensikt", "metode", "seksjon")), + regexp = "Variable 'data': Must be of type 'data.frame', not 'character'.", + fixed = TRUE) + + expect_error(add_PJS_code_description(testdata, + translation_table = PJS_codes_2_text, + code_colname = c("hensiktkoder"), + PJS_variable_type = c("hensikt"), + new_column = c("hensikt")), + regexp = "but 'hensiktkoder' is not a column in the data.", + fixed = TRUE) + + expect_error(add_PJS_code_description(testdata, + translation_table = PJS_codes_2_text, + code_colname = c("hensiktkode"), + PJS_variable_type = c("hensikter"), + new_column = c("hensikt")), + regexp = "Variable 'PJS_variable_type': Must be a subset of", + fixed = TRUE) + + expect_error(add_PJS_code_description(testdata, + translation_table = PJS_codes_2_text, + code_colname = c("hensiktkode"), + PJS_variable_type = c("hensikt"), + new_column = c("metodekode")), + regexp = "The column name(s): 'metodekode' already exist in 'testdata`.", + fixed = TRUE) + + options(width = unlist(linewidth)) +}) + RODBC::odbcCloseAll() From 2a843607e7a205dfea1a69d2fd39eee7e1eeb1fd Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Sun, 4 Feb 2024 00:26:46 +0100 Subject: [PATCH 11/18] test: updated test_Prodtilskudd Included tests for errors in copy_Prodtilskudd with extracted_date --- tests/testthat/test_Prodtilskudd.R | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/testthat/test_Prodtilskudd.R b/tests/testthat/test_Prodtilskudd.R index 53a23cf..89d4738 100644 --- a/tests/testthat/test_Prodtilskudd.R +++ b/tests/testthat/test_Prodtilskudd.R @@ -101,6 +101,24 @@ test_that("errors for copy_Prodtilskudd", { options(width = unlist(linewidth)) }) +test_that("errors for copy_Prodtilskudd with extracted_date", { + + linewidth <- options("width") + options(width = 80) + + expect_error(copy_Prodtilskudd(from_path = tempdir(), to_path = "./", Pkode_year = "last", + Pkode_month = "10", extracted_date = "2023-03-31"), + regexp = "Contains only missing values. The input 'last' is", + fixed = TRUE) + + expect_error(copy_Prodtilskudd(from_path = tempdir(), to_path = "./", Pkode_year = 2020, + Pkode_month = "both", extracted_date = "2023-03-31"), + regexp = "The inputs 'both' and 'last' are not accepted when", + fixed = TRUE) + + options(width = unlist(linewidth)) +}) + test_that("errors for read_Prodtilskudd", { From 881814bdee7238d0bd817526208354ce64722859 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Sun, 4 Feb 2024 00:27:32 +0100 Subject: [PATCH 12/18] test: updated test_login Included tests for errors in login_PJS and login_EOS --- tests/testthat/test_login.R | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/testthat/test_login.R b/tests/testthat/test_login.R index 57d21ca..78c036e 100644 --- a/tests/testthat/test_login.R +++ b/tests/testthat/test_login.R @@ -37,3 +37,23 @@ test_that("Errors or warnings for login", { options(width = unlist(linewidth)) }) + +test_that("Errors or warnings for login_EOS", { + linewidth <- options("width") + options(width = 80) + + expect_error(login_EOS(dbinterface = "noodbc"), + regexpr = "Variable 'dbinterface': Must be element of set") + + options(width = unlist(linewidth)) +}) + +test_that("Errors or warnings for login_PJS", { + linewidth <- options("width") + options(width = 80) + + expect_error(login_PJS(dbinterface = "noodbc"), + regexpr = "Variable 'dbinterface': Must be element of set") + + options(width = unlist(linewidth)) +}) From 12f9023a39e00872a13a0b18fd916f10592ec9bd Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Sun, 4 Feb 2024 00:28:48 +0100 Subject: [PATCH 13/18] refactor: updated set_disease_parameters with argument testing for purpose --- R/set_disease_parameters.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/set_disease_parameters.R b/R/set_disease_parameters.R index 5b28a5b..2a2a8b5 100644 --- a/R/set_disease_parameters.R +++ b/R/set_disease_parameters.R @@ -186,6 +186,7 @@ set_disease_parameters <- function(purpose = NULL, # checks <- checkmate::makeAssertCollection() # Perform checks + checkmate::assert_string(purpose, null.ok = TRUE, add = checks) NVIcheckmate::assert_non_null(list(analytt2select, hensikt2select, utbrudd2select, unlist(selection_parameters)), add = checks) checkmate::assert_character(hensikt2select, min.chars = 2, max.chars = 15, any.missing = FALSE, null.ok = TRUE, add = checks) checkmate::assert_character(hensikt2delete, min.chars = 2, max.chars = 15, any.missing = FALSE, null.ok = TRUE, add = checks) From 8edf1d9bc9d225128ee0ae22b9e3df8274494ce0 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Sun, 4 Feb 2024 00:30:42 +0100 Subject: [PATCH 14/18] test: updated test_set_disese_parameters Included tests for argument purpose, FUN, and select_statement. Included test for deprecated arguments file and missing_art. --- tests/testthat/test_set_disease_parameters.R | 75 ++++++++++++++++++-- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/tests/testthat/test_set_disease_parameters.R b/tests/testthat/test_set_disease_parameters.R index d48011e..b9d833c 100644 --- a/tests/testthat/test_set_disease_parameters.R +++ b/tests/testthat/test_set_disease_parameters.R @@ -37,7 +37,8 @@ test_that("set disease parameters by direct input", { hensikt2delete = c("0800109"), utbrudd2select = "22", analytt2select = c("01220104%", "1502010235"), - metode2select = c("070070", "070231", "010057", "060265")) + metode2select = c("070070", "070231", "010057", "060265"), + art2select = c("03%", NA)) expect_equal(parameters, list("purpose" = NULL, "hensikt2select" = c("0100108018", "0100109003", "0100111003"), @@ -46,8 +47,8 @@ test_that("set disease parameters by direct input", { "metode2select" = c("070070", "070231", "010057", "060265"), "analytt2select" = c("01220104%", "1502010235"), "analytt2delete" = NULL, - "art2select" = NULL, - "include_missing_art" = "never", + "art2select" = c("03%", NA), + "include_missing_art" = "always", "FUN" = NULL, "select_statement" = NULL)) @@ -60,8 +61,8 @@ test_that("set disease parameters by direct input", { "metode2select" = c("070070", "070231", "010057", "060265"), "analytt2select" = c("01220104%", "1502010235"), "analytt2delete" = NULL, - "art2select" = NULL, - "include_missing_art" = "never", + "art2select" = c("03%", NA), + "include_missing_art" = "always", "FUN" = NULL, "select_statement" = NULL)) @@ -84,6 +85,28 @@ test_that("set disease parameters by direct input", { "FUN" = NULL, "select_statement" = NULL)) + parameters <- expect_warning(set_disease_parameters(hensikt2select = c("0100108018", "0100109003", "0100111003"), + hensikt2delete = c("0800109"), + utbrudd2select = "22", + metode2select = NULL, + art2select = c("01%"), + missing_art = "non_selected_hensikt"), + regexp = "The argument 'missing_art' is deprecated.", + fixed = TRUE) + + expect_equal(parameters, + list("purpose" = NULL, + "hensikt2select" = c("0100108018", "0100109003", "0100111003"), + "hensikt2delete" = c("0800109"), + "utbrudd2select" = "22", + "metode2select" = NULL, + "analytt2select" = NULL, + "analytt2delete" = NULL, + "art2select" = c("01%"), + "include_missing_art" = "for_selected_hensikt", + "FUN" = NULL, + "select_statement" = NULL)) + parameters <- set_disease_parameters(hensikt2select = c("0100108018", "0100109003", "0100111003"), hensikt2delete = c("0800109"), utbrudd2select = "22", @@ -229,6 +252,46 @@ test_that("errors for set_disease_parameters", { art2select = c("05%", NA), include_missing_art = "yes"), regexp = "Variable 'include_missing_art': Must be element of set") - + + expect_error(set_disease_parameters(purpose = NA, + hensikt2delete = "0100108018", + analytt2select = "01220104%", + utbrudd2select = "2", + art2select = c("05%", NA), + include_missing_art = "always"), + regexp = "Variable 'purpose': May not be NA") + + expect_error(set_disease_parameters(purpose = 1, + hensikt2delete = "0100108018", + analytt2select = "01220104%", + utbrudd2select = "2", + art2select = c("05%", NA), + include_missing_art = "always"), + regexp = "Variable 'purpose': Must be of type 'string' (or 'NULL')", + fixed = TRUE) + + expect_error(set_disease_parameters(purpose = "ok_storfe_virus", + hensikt2delete = "0100108018", + analytt2select = "01220104%", + utbrudd2select = "2", + art2select = c("05%", NA), + include_missing_art = "always", + FUN = build_query_hensikt, + select_statement = 1), + regexp = "Must be of type 'string', * not 'double'", + fixed = TRUE) + + expect_error(set_disease_parameters(purpose = "ok_storfe_virus", + hensikt2delete = "0100108018", + analytt2select = "01220104%", + utbrudd2select = "2", + art2select = c("05%", NA), + include_missing_art = "always", + FUN = "build_query_hensikt", + select_statement = NULL), + regexp = "Must be a function (or 'NULL'), not 'character'", + fixed = TRUE) + options(width = unlist(linewidth)) }) + From b9251ae615f31ef5332c4ec8c27a8650792a00d5 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Mon, 5 Feb 2024 08:16:08 +0100 Subject: [PATCH 15/18] chore: NEWS updated with bug fixes and new features. --- NEWS | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 873e0b7..12e4ea7 100644 --- a/NEWS +++ b/NEWS @@ -3,22 +3,12 @@ NVIdb 0.11.0.9000 - (2024-##-##) New features: -- +- set_disease_parameters now accepts the arguments purpose, FUN and select_statement. Bug fixes: -- - - -Other changes: - -- - - -BREAKING CHANGES: - -- +- set_disease_parameters now accepts metodekode with 2 digits. NVIdb 0.11.0 - (2024-01-24) From 8587046dd465a1dc196ee8e379741205b8f76e03 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Mon, 5 Feb 2024 08:19:46 +0100 Subject: [PATCH 16/18] chore: NEWS and DESCRIPTION v0.11.1 --- DESCRIPTION | 4 ++-- NEWS | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9f5055b..7a4d355 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: NVIdb Title: Tools to facilitate the use of NVI's databases -Version: 0.11.0.9000 -Date: 2024-##-## +Version: 0.11.1 +Date: 2024-02-05 Authors@R: c(person(given = "Petter", family = "Hopp", diff --git a/NEWS b/NEWS index 12e4ea7..05ad423 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -NVIdb 0.11.0.9000 - (2024-##-##) +NVIdb 0.11.1 - (2024-02-05) ---------------------------------------- New features: From 0f82da3c5da535b53acf877e5ddb380e833ab298 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Mon, 5 Feb 2024 08:24:04 +0100 Subject: [PATCH 17/18] style: styled lines in several tests test_PJS_code_description test_Prodtilskudd test_login test_set_disease_parameters --- tests/testthat/test_PJS_code_description.R | 20 ++++++++++---------- tests/testthat/test_Prodtilskudd.R | 10 +++++----- tests/testthat/test_login.R | 8 ++++---- tests/testthat/test_set_disease_parameters.R | 13 ++++++------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/tests/testthat/test_PJS_code_description.R b/tests/testthat/test_PJS_code_description.R index be6a0d7..66d4b7f 100644 --- a/tests/testthat/test_PJS_code_description.R +++ b/tests/testthat/test_PJS_code_description.R @@ -246,20 +246,20 @@ test_that("Backward translation from description to code", { # }) test_that("errors for add_PJS_code_description", { - + linewidth <- options("width") options(width = 80) - + # skip if no connection to 'FAG' have been established skip_if_not(dir.exists(set_dir_NVI("FAG"))) - + # Reads translation table for PJS-codes PJS_codes_2_text <- read_PJS_codes_2_text() - - testdata <- as.data.frame(list("hensiktkode" = c("01001", "01002"), + + testdata <- as.data.frame(list("hensiktkode" = c("01001", "01002"), "metodekode" = c("010001", "010002"), "ansvarlig_seksjon" = c("01", "02"))) - + expect_error(add_PJS_code_description("testdata", translation_table = PJS_codes_2_text, code_colname = c("hensiktkode", "metodekode", "ansvarlig_seksjon"), @@ -267,7 +267,7 @@ test_that("errors for add_PJS_code_description", { new_column = c("hensikt", "metode", "seksjon")), regexp = "Variable 'data': Must be of type 'data.frame', not 'character'.", fixed = TRUE) - + expect_error(add_PJS_code_description(testdata, translation_table = PJS_codes_2_text, code_colname = c("hensiktkoder"), @@ -275,7 +275,7 @@ test_that("errors for add_PJS_code_description", { new_column = c("hensikt")), regexp = "but 'hensiktkoder' is not a column in the data.", fixed = TRUE) - + expect_error(add_PJS_code_description(testdata, translation_table = PJS_codes_2_text, code_colname = c("hensiktkode"), @@ -283,7 +283,7 @@ test_that("errors for add_PJS_code_description", { new_column = c("hensikt")), regexp = "Variable 'PJS_variable_type': Must be a subset of", fixed = TRUE) - + expect_error(add_PJS_code_description(testdata, translation_table = PJS_codes_2_text, code_colname = c("hensiktkode"), @@ -291,7 +291,7 @@ test_that("errors for add_PJS_code_description", { new_column = c("metodekode")), regexp = "The column name(s): 'metodekode' already exist in 'testdata`.", fixed = TRUE) - + options(width = unlist(linewidth)) }) diff --git a/tests/testthat/test_Prodtilskudd.R b/tests/testthat/test_Prodtilskudd.R index 89d4738..385c846 100644 --- a/tests/testthat/test_Prodtilskudd.R +++ b/tests/testthat/test_Prodtilskudd.R @@ -102,20 +102,20 @@ test_that("errors for copy_Prodtilskudd", { }) test_that("errors for copy_Prodtilskudd with extracted_date", { - + linewidth <- options("width") options(width = 80) - + expect_error(copy_Prodtilskudd(from_path = tempdir(), to_path = "./", Pkode_year = "last", Pkode_month = "10", extracted_date = "2023-03-31"), regexp = "Contains only missing values. The input 'last' is", fixed = TRUE) - - expect_error(copy_Prodtilskudd(from_path = tempdir(), to_path = "./", Pkode_year = 2020, + + expect_error(copy_Prodtilskudd(from_path = tempdir(), to_path = "./", Pkode_year = 2020, Pkode_month = "both", extracted_date = "2023-03-31"), regexp = "The inputs 'both' and 'last' are not accepted when", fixed = TRUE) - + options(width = unlist(linewidth)) }) diff --git a/tests/testthat/test_login.R b/tests/testthat/test_login.R index 78c036e..d07f88f 100644 --- a/tests/testthat/test_login.R +++ b/tests/testthat/test_login.R @@ -41,19 +41,19 @@ test_that("Errors or warnings for login", { test_that("Errors or warnings for login_EOS", { linewidth <- options("width") options(width = 80) - + expect_error(login_EOS(dbinterface = "noodbc"), regexpr = "Variable 'dbinterface': Must be element of set") - + options(width = unlist(linewidth)) }) test_that("Errors or warnings for login_PJS", { linewidth <- options("width") options(width = 80) - + expect_error(login_PJS(dbinterface = "noodbc"), regexpr = "Variable 'dbinterface': Must be element of set") - + options(width = unlist(linewidth)) }) diff --git a/tests/testthat/test_set_disease_parameters.R b/tests/testthat/test_set_disease_parameters.R index b9d833c..d3d47be 100644 --- a/tests/testthat/test_set_disease_parameters.R +++ b/tests/testthat/test_set_disease_parameters.R @@ -93,7 +93,7 @@ test_that("set disease parameters by direct input", { missing_art = "non_selected_hensikt"), regexp = "The argument 'missing_art' is deprecated.", fixed = TRUE) - + expect_equal(parameters, list("purpose" = NULL, "hensikt2select" = c("0100108018", "0100109003", "0100111003"), @@ -252,7 +252,7 @@ test_that("errors for set_disease_parameters", { art2select = c("05%", NA), include_missing_art = "yes"), regexp = "Variable 'include_missing_art': Must be element of set") - + expect_error(set_disease_parameters(purpose = NA, hensikt2delete = "0100108018", analytt2select = "01220104%", @@ -260,7 +260,7 @@ test_that("errors for set_disease_parameters", { art2select = c("05%", NA), include_missing_art = "always"), regexp = "Variable 'purpose': May not be NA") - + expect_error(set_disease_parameters(purpose = 1, hensikt2delete = "0100108018", analytt2select = "01220104%", @@ -269,7 +269,7 @@ test_that("errors for set_disease_parameters", { include_missing_art = "always"), regexp = "Variable 'purpose': Must be of type 'string' (or 'NULL')", fixed = TRUE) - + expect_error(set_disease_parameters(purpose = "ok_storfe_virus", hensikt2delete = "0100108018", analytt2select = "01220104%", @@ -280,7 +280,7 @@ test_that("errors for set_disease_parameters", { select_statement = 1), regexp = "Must be of type 'string', * not 'double'", fixed = TRUE) - + expect_error(set_disease_parameters(purpose = "ok_storfe_virus", hensikt2delete = "0100108018", analytt2select = "01220104%", @@ -291,7 +291,6 @@ test_that("errors for set_disease_parameters", { select_statement = NULL), regexp = "Must be a function (or 'NULL'), not 'character'", fixed = TRUE) - + options(width = unlist(linewidth)) }) - From 2bbda0297d144772a931940107cfdd2fe9689913 Mon Sep 17 00:00:00 2001 From: Petter Hopp Date: Mon, 5 Feb 2024 08:26:14 +0100 Subject: [PATCH 18/18] doc: pdf reference manual v0.11.1 --- vignettes/NVIdb.pdf | Bin 300362 -> 301068 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/vignettes/NVIdb.pdf b/vignettes/NVIdb.pdf index be18bed33ec7401a48a25b10635f58ac7bd489fb..dc7f02f279d99323e41eb59f21ced6d75a6682bf 100644 GIT binary patch delta 35587 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 a>pL=T^vH;T9+*l&+uEag^_CriJpK=B1E^>K delta 35738 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%0Du0GAq(J*vO<6 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