From ed4b432ee2f62cfb0d0bfc8f45ec6b37cf77ddc7 Mon Sep 17 00:00:00 2001 From: Ernest Guevarra Date: Tue, 23 Apr 2024 20:12:21 +0100 Subject: [PATCH 1/3] re-factor check functions --- R/icd_check.R | 38 +++++++++++++++++++++++--------- man/icd_check.Rd | 12 ++++++++-- tests/testthat/test-icd_10_get.R | 25 +++++++++++++++++++++ 3 files changed, 62 insertions(+), 13 deletions(-) create mode 100644 tests/testthat/test-icd_10_get.R diff --git a/R/icd_check.R b/R/icd_check.R index 728c49c..38851cc 100644 --- a/R/icd_check.R +++ b/R/icd_check.R @@ -3,6 +3,8 @@ #' functions #' #' @param release A string specifying the release version of the ICD-11. +#' @param icd A character string of available ICD classifications. Currently, +#' this can be either "icd10" or "icd11". Default is "icd11". #' @param language language codes such as en, es, zh, etc. #' @param verbose Logical. Should non-warning and non-error messages be #' printed? Default is TRUE. @@ -22,20 +24,27 @@ #' @rdname icd_check #' @export #' -icd_check_release <- function(release, verbose = TRUE) { - release_check <- release %in% codigo::icd_versions$`Release ID` +icd_check_release <- function(release, + icd = c("icd11", "icd10"), + verbose = TRUE) { + icd <- match.arg(icd) + + icd <- ifelse(icd == "icd11", "ICD-11", "ICD-10") + + release_check <- release %in% + codigo::icd_versions$`Release ID`[codigo::icd_versions$Classification == icd] if (release_check) { - icd_set <- with( - codigo::icd_versions, - Classification[`Release ID` == release] - ) + # icd_set <- with( + # codigo::icd_versions, + # Classification[`Release ID` == release] + # ) if (verbose) message( paste0( "Release `", release, "` matches a known release for ", - icd_set, "." + icd, "." ) |> strwrap(width = 80) ) @@ -43,8 +52,8 @@ icd_check_release <- function(release, verbose = TRUE) { stop( paste0( "Release `", release, - "` does not match any known release for ICD-11 or ICD-10.", - " Please verify and check with `icd_versions` and try again." + "` does not match any known release for ", icd, + ". Please check `icd_versions`." ) |> strwrap(width = 80) ) @@ -56,9 +65,16 @@ icd_check_release <- function(release, verbose = TRUE) { #' @rdname icd_check #' @export #' -icd_check_language <- function(release = NULL, language, verbose = TRUE) { +icd_check_language <- function(release = NULL, language, + icd = c("icd11", "icd10"), verbose = TRUE) { + icd <- match.arg(icd) + + icd <- ifelse(icd == "icd11", "ICD-11", "ICD-10") + ## Check if release is NULL ---- - if (is.null(release)) release <- codigo::icd_versions$`Release ID`[1] + if (is.null(release)) release <- codigo::icd_versions |> + dplyr::filter(Classification == icd) |> + dplyr::pull(`Release ID`) ## Check whether release is specified correctly ---- icd_check_release(release, verbose = verbose) diff --git a/man/icd_check.Rd b/man/icd_check.Rd index 1f56933..c5b62d3 100644 --- a/man/icd_check.Rd +++ b/man/icd_check.Rd @@ -6,13 +6,21 @@ \title{Checks for specified parameters supplied to search, autocode, and get functions} \usage{ -icd_check_release(release, verbose = TRUE) +icd_check_release(release, icd = c("icd11", "icd10"), verbose = TRUE) -icd_check_language(release = NULL, language, verbose = TRUE) +icd_check_language( + release = NULL, + language, + icd = c("icd11", "icd10"), + verbose = TRUE +) } \arguments{ \item{release}{A string specifying the release version of the ICD-11.} +\item{icd}{A character string of available ICD classifications. Currently, +this can be either "icd10" or "icd11". Default is "icd11".} + \item{verbose}{Logical. Should non-warning and non-error messages be printed? Default is TRUE.} diff --git a/tests/testthat/test-icd_10_get.R b/tests/testthat/test-icd_10_get.R new file mode 100644 index 0000000..1300118 --- /dev/null +++ b/tests/testthat/test-icd_10_get.R @@ -0,0 +1,25 @@ +# Tests for ICD-10 endpoints --------------------------------------------------- + +release_result <- icd_10_get_releases() + +testthat::test_that( + "release_result is of the right type", { + expect_type(release_result, "list") + } +) + + +release_chapters <- icd_10_get_chapters() + +testthat::test_that( + "release_chapters is of the right type", { + expect_type(release_chapters, "list") + } +) + +testthat::test_that( + "expect warning or error", { + expect_error(icd_10_get_chapters(release = 2020)) + expect_warning(icd_10_get_chapters(language = "fr")) + } +) From cbcdd37b9eaedf1c3944eda658b0ad841ec58191 Mon Sep 17 00:00:00 2001 From: Ernest Guevarra Date: Tue, 23 Apr 2024 21:46:50 +0100 Subject: [PATCH 2/3] refactor check functions --- DESCRIPTION | 1 + NAMESPACE | 3 ++ R/codigo.R | 4 +- R/icd_10_get.R | 16 +++++-- R/icd_autocode.R | 13 ++++-- R/icd_check.R | 14 +++--- R/icd_get.R | 29 ++++++++---- R/icd_search.R | 13 ++++-- man/icd_10_get.Rd | 5 +++ man/icd_get.Rd | 3 ++ tests/testthat/test-get.R | 92 +++++++++++++++++++++++++++++++++------ 11 files changed, 154 insertions(+), 39 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a40f59c..4bb60d8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,6 +22,7 @@ Depends: Imports: dplyr, httr2, + rlang, tibble, tidyr Suggests: diff --git a/NAMESPACE b/NAMESPACE index 987238a..bf3a239 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,6 +25,7 @@ export(icd_structure_foundation) export(icd_structure_search) importFrom(dplyr,bind_cols) importFrom(dplyr,bind_rows) +importFrom(dplyr,filter) importFrom(dplyr,pull) importFrom(httr2,oauth_client) importFrom(httr2,req_headers) @@ -34,5 +35,7 @@ importFrom(httr2,req_url_path) importFrom(httr2,req_url_query) importFrom(httr2,request) importFrom(httr2,resp_body_json) +importFrom(rlang,.data) importFrom(tibble,tibble) importFrom(tidyr,unnest) +importFrom(utils,head) diff --git a/R/codigo.R b/R/codigo.R index 8793e76..106d70c 100644 --- a/R/codigo.R +++ b/R/codigo.R @@ -14,7 +14,9 @@ #' @importFrom httr2 oauth_client request req_url_query req_headers #' req_oauth_client_credentials req_perform resp_body_json req_url_path #' @importFrom tibble tibble -#' @importFrom dplyr bind_cols bind_rows pull +#' @importFrom dplyr bind_cols bind_rows pull filter #' @importFrom tidyr unnest +#' @importFrom rlang .data +#' @importFrom utils head #' "_PACKAGE" diff --git a/R/icd_10_get.R b/R/icd_10_get.R index f8e6465..49a3e69 100644 --- a/R/icd_10_get.R +++ b/R/icd_10_get.R @@ -14,6 +14,8 @@ #' languages will vary. Default is English ("en"). Note that language support #' for ICD-10 is limited to English (`en`). #' @param category ICD-10 category code or for blocks, the code range. +#' @param verbose Logical. Should non-warning and non-error messages be +#' printed? Default is TRUE. #' @param base_url The base URL of the API. Default uses the WHO API server at #' https://id.who.int. If you are using a locally deployed server or hosting #' your own ICD API server, you should specify the URL of your instance here. @@ -72,6 +74,7 @@ icd_10_get_releases <- function(api_version = c("v2", "v1"), icd_10_get_chapters <- function(release = NULL, api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access") { @@ -80,13 +83,15 @@ icd_10_get_chapters <- function(release = NULL, ## Check release identifier ---- if (!is.null(release)) - icd_check_release(release) + icd_check_release(release = release, icd = "icd10", verbose = verbose) else release <- icd_get_releases(icd = "icd10", latest = TRUE) |> dplyr::pull() ## Check language ---- if (!is.null(language)) - icd_check_language(release = release, language = language) + language <- icd_check_language( + release = release, language = language, icd = "icd10", verbose = verbose + ) ## Make base request ---- req <- httr2::request(base_url) |> @@ -150,6 +155,7 @@ icd_10_get_info <- function(release = NULL, category, api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access") { @@ -158,13 +164,15 @@ icd_10_get_info <- function(release = NULL, ## Check release identifier ---- if (!is.null(release)) - icd_check_release(release) + icd_check_release(release = release, icd = "icd10", verbose = verbose) else release <- icd_get_releases(icd = "icd10", latest = TRUE) |> dplyr::pull() ## Check language ---- if (!is.null(language)) - icd_check_language(release = release, language = language) + language <- icd_check_language( + release = release, language = language, icd = "icd10", verbose = verbose + ) ## Make base request ---- req <- httr2::request(base_url) |> diff --git a/R/icd_autocode.R b/R/icd_autocode.R index dca2427..a965aa2 100644 --- a/R/icd_autocode.R +++ b/R/icd_autocode.R @@ -61,11 +61,14 @@ icd_autocode_foundation <- function(q, api_version <- match.arg(api_version) ## Check release identifier ---- - if (!is.null(release)) icd_check_release(release, verbose = verbose) + if (!is.null(release)) + icd_check_release(release, verbose = verbose) ## Check language ---- if (!is.null(language)) - language <- icd_check_language(release, language, verbose = verbose) + language <- icd_check_language( + release = release, language = language, verbose = verbose + ) ## Make base request ---- req <- httr2::request(file.path(base_url, "icd/entity/autocode")) |> @@ -131,13 +134,15 @@ icd_autocode <- function(q, ## Check release identifier ---- if (!is.null(release)) - icd_check_release(release, verbose = verbose) + icd_check_release(release = release, verbose = verbose) else release <- icd_get_releases(latest = TRUE) |> dplyr::pull() ## Check language ---- if (!is.null(language)) - language <- icd_check_language(release, language, verbose = verbose) + language <- icd_check_language( + release = release, language = language, verbose = verbose + ) ## Make base request ---- req <- httr2::request(base_url) |> diff --git a/R/icd_check.R b/R/icd_check.R index 38851cc..7d9f706 100644 --- a/R/icd_check.R +++ b/R/icd_check.R @@ -66,18 +66,22 @@ icd_check_release <- function(release, #' @export #' icd_check_language <- function(release = NULL, language, - icd = c("icd11", "icd10"), verbose = TRUE) { + icd = c("icd11", "icd10"), + verbose = TRUE) { icd <- match.arg(icd) - icd <- ifelse(icd == "icd11", "ICD-11", "ICD-10") + #icd <- ifelse(icd == "icd11", "ICD-11", "ICD-10") ## Check if release is NULL ---- if (is.null(release)) release <- codigo::icd_versions |> - dplyr::filter(Classification == icd) |> - dplyr::pull(`Release ID`) + dplyr::filter( + .data$Classification == ifelse(icd == "icd11", "ICD-11", "ICD-10") + ) |> + dplyr::pull(.data$`Release ID`) |> + head(1) ## Check whether release is specified correctly ---- - icd_check_release(release, verbose = verbose) + icd_check_release(release = release, icd = icd, verbose = verbose) ## Get languages available for release provided ---- languages_available <- with( diff --git a/R/icd_get.R b/R/icd_get.R index 6a9baa1..c84a8c4 100644 --- a/R/icd_get.R +++ b/R/icd_get.R @@ -60,10 +60,13 @@ icd_get_foundation <- function(release = NULL, api_version <- match.arg(api_version) ## Check release identifier ---- - if (!is.null(release)) icd_check_release(release, verbose = verbose) + if (!is.null(release)) icd_check_release(release = release, verbose = verbose) ## Check language ---- - if (!is.null(language)) icd_check_language(release, language, verbose = verbose) + if (!is.null(language)) + language <- icd_check_language( + release = release, language = language, verbose = verbose + ) ## Make base request ---- req <- httr2::request(file.path(base_url, "icd/entity")) @@ -105,6 +108,7 @@ icd_get_entity <- function(id, include = NULL, api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access") { @@ -112,10 +116,14 @@ icd_get_entity <- function(id, api_version <- match.arg(api_version) ## Check release identifier ---- - if (!is.null(release)) icd_check_release(release) + if (!is.null(release)) + icd_check_release(release = release, verbose = verbose) ## Check language ---- - if (!is.null(language)) icd_check_language(release, language) + if (!is.null(language)) + language <- icd_check_language( + release = release, language = language, verbose = verbose + ) ## Make base request ---- req <- httr2::request(file.path(base_url, "icd/entity", id)) |> @@ -159,6 +167,7 @@ icd_get_entity <- function(id, icd_get_info <- function(linearization = c("mms", "icf"), api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access") { @@ -170,9 +179,10 @@ icd_get_info <- function(linearization = c("mms", "icf"), ## Check language ---- if (!is.null(language)) - icd_check_language( + language <- icd_check_language( release = icd_get_releases(latest = TRUE) |> dplyr::pull(), - language + language = language, + verbose = verbose ) ## Make base request ---- @@ -203,6 +213,7 @@ icd_get_chapter <- function(linearization = c("mms", "icf"), release = NULL, api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access") { @@ -214,13 +225,15 @@ icd_get_chapter <- function(linearization = c("mms", "icf"), ## Check release identifier ---- if (!is.null(release)) - icd_check_release(release) + icd_check_release(release = release, verbose = verbose) else release <- icd_get_releases(latest = TRUE) |> dplyr::pull() ## Check language ---- if (!is.null(language)) - icd_check_language(release = release, language = language) + language <- icd_check_language( + release = release, language = language, verbose = verbose + ) ## Make base request ---- req <- httr2::request(base_url) |> diff --git a/R/icd_search.R b/R/icd_search.R index 38e4a34..bef7143 100644 --- a/R/icd_search.R +++ b/R/icd_search.R @@ -126,11 +126,14 @@ icd_search_foundation <- function(q, api_version <- match.arg(api_version) ## Check release identifier ---- - if (!is.null(release)) icd_check_release(release, verbose = verbose) + if (!is.null(release)) + icd_check_release(release = release, icd = "icd11", verbose = verbose) ## Check language ---- if (!is.null(language)) - language <- icd_check_language(release, language, verbose = verbose) + language <- icd_check_language( + release = release, language = language, icd = "icd11", verbose = verbose + ) ## Make base request ---- req <- httr2::request(base_url) |> @@ -229,13 +232,15 @@ icd_search <- function(q, ## Check release identifier ---- if (!is.null(release)) - icd_check_release(release, verbose = verbose) + icd_check_release(release = release, icd = "icd11", verbose = verbose) else release <- icd_get_releases(latest = TRUE) |> dplyr::pull() ## Check language ---- if (!is.null(language)) - language <- icd_check_language(release, language, verbose = verbose) + language <- icd_check_language( + release = release, language = language, icd = "icd11", verbose = verbose + ) ## Make base request ---- req <- httr2::request(base_url) |> diff --git a/man/icd_10_get.Rd b/man/icd_10_get.Rd index bf0e697..a855692 100644 --- a/man/icd_10_get.Rd +++ b/man/icd_10_get.Rd @@ -18,6 +18,7 @@ icd_10_get_chapters( release = NULL, api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access" @@ -36,6 +37,7 @@ icd_10_get_info( category, api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access" @@ -67,6 +69,9 @@ en, es, zh, etc. Depending on the \code{release_id} specified, the available languages will vary. Default is English ("en"). Note that language support for ICD-10 is limited to English (\code{en}).} +\item{verbose}{Logical. Should non-warning and non-error messages be +printed? Default is TRUE.} + \item{category}{ICD-10 category code or for blocks, the code range.} } \value{ diff --git a/man/icd_get.Rd b/man/icd_get.Rd index cf7ef40..3d84d7a 100644 --- a/man/icd_get.Rd +++ b/man/icd_get.Rd @@ -24,6 +24,7 @@ icd_get_entity( include = NULL, api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access" @@ -33,6 +34,7 @@ icd_get_info( linearization = c("mms", "icf"), api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access" @@ -43,6 +45,7 @@ icd_get_chapter( release = NULL, api_version = c("v2", "v1"), language = "en", + verbose = TRUE, base_url = "https://id.who.int", client = icd_oauth_client(), scope = "icdapi_access" diff --git a/tests/testthat/test-get.R b/tests/testthat/test-get.R index 0933e42..468fde2 100644 --- a/tests/testthat/test-get.R +++ b/tests/testthat/test-get.R @@ -3,46 +3,112 @@ ## Test default call ---- test_get_foundation_default <- icd_get_foundation() -testthat::expect_s3_class(test_get_foundation_default, "tbl_df") -testthat::expect_type(test_get_foundation_default, "list") +testthat::test_that( + "output class/type is as expected", { + testthat::expect_s3_class(test_get_foundation_default, "tbl_df") + testthat::expect_type(test_get_foundation_default, "list") + } +) ## Test non-tabular call ---- test_get_foundation_list <- icd_get_foundation(tabular = FALSE) -testthat::expect_type(test_get_foundation_list, "list") +testthat::test_that( + "output class/type is as expected", { + testthat::expect_type(test_get_foundation_list, "list") + } +) +## Test warning for unavailable language ---- + +testthat::test_that( + "a warning is raised for language not found", { + testthat::expect_warning(icd_get_foundation(language = "zz")) + } +) ## Test release ---- test_get_foundation_release <- icd_get_foundation(release = "2024-01") -testthat::expect_s3_class(test_get_foundation_release, "tbl_df") -testthat::expect_type(test_get_foundation_release, "list") +testthat::test_that( + "output class/type is as expected", { + testthat::expect_s3_class(test_get_foundation_release, "tbl_df") + testthat::expect_type(test_get_foundation_release, "list") + } +) + +testthat::test_that( + "an error is raised for unavailable icd release", { + testthat::expect_error(icd_get_foundation(release = "2020")) + } +) + ## Test default entity call ---- test_get_entity_default <- icd_get_entity("1435254666") -testthat::expect_type(test_get_entity_default, "list") + +testthat::test_that( + "output class/type is as expected", { + testthat::expect_type(test_get_entity_default, "list") + } +) test_get_entity_release <- icd_get_entity("1435254666", release = "2024-01") -testthat::expect_type(test_get_entity_release, "list") + +testthat::test_that( + "output class/type is as expected", { + testthat::expect_type(test_get_entity_release, "list") + } +) test_get_entity_include <- icd_get_entity( id = "1435254666", include = c("ancestor", "descendant", "diagnosticCriteria") ) -testthat::expect_type(test_get_entity_include, "list") -testthat::expect_true( - all(c("ancestor", "descendant") %in% names(test_get_entity_include)) + +testthat::test_that( + "output class/type is as expected", { + testthat::expect_type(test_get_entity_include, "list") + testthat::expect_true( + all(c("ancestor", "descendant") %in% names(test_get_entity_include)) + ) + } +) + +testthat::test_that( + "warning is raised for unavailable language", { + testthat::expect_warning(icd_get_entity(id = "1435254666", language = "zz")) + } ) ## Test icd_get_info ---- -testthat::expect_type(icd_get_info(), "list") +testthat::test_that( + "output class/type is as expected", { + testthat::expect_type(icd_get_info(), "list") + } +) + +testthat::test_that( + "warning is raised for unavailable language", { + testthat::expect_warning(icd_get_info(language = "zz")) + } +) ## Test icd_get_chapter ---- -testthat::expect_type(icd_get_chapter(release = "2023-01"), "list") -testthat::expect_type(icd_get_chapter(), "list") +testthat::test_that( + "output class/type is as expected", { + testthat::expect_type(icd_get_chapter(release = "2023-01"), "list") + testthat::expect_type(icd_get_chapter(), "list") + } +) +testthat::test_that( + "warning is raised for unavailable language", { + testthat::expect_warning(icd_get_chapter(language = "zz")) + } +) From 2dc31d9b6ce9a84da1155ef29008da69b03122c3 Mon Sep 17 00:00:00 2001 From: Ernest Guevarra Date: Tue, 23 Apr 2024 22:19:11 +0100 Subject: [PATCH 3/3] add codecov token --- .github/workflows/test-coverage.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 960234c..55b92ef 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -13,6 +13,7 @@ jobs: runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} steps: - uses: actions/checkout@v4