diff --git a/NAMESPACE b/NAMESPACE index 242b444a..9357ccdf 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,11 +25,13 @@ export(assert_vars) export(assert_varval_list) export(convert_blanks_to_na) export(dataset_vignette) +export(desc) export(expect_dfs_equal) export(extract_unit) export(filter_if) export(hello_admiral) export(negate_vars) +export(vars) export(vars2chr) importFrom(admiral,assert_character_scalar) importFrom(admiral,derive_vars_dy) diff --git a/R/assertions.R b/R/assertions.R index 32071f4c..7bded3aa 100644 --- a/R/assertions.R +++ b/R/assertions.R @@ -23,6 +23,7 @@ #' #' @examples #' library(admiral.test) +#' library(admiral) #' data(admiral_dm) #' #' example_fun <- function(dataset) { @@ -503,6 +504,7 @@ assert_vars <- function(arg, optional = FALSE) { #' @keywords assertion #' @family assertion #' @examples +#' #' example_fun <- function(by_vars) { #' assert_order_vars(by_vars) #' } @@ -947,14 +949,15 @@ assert_function_param <- function(arg, params) { #' #' @export #' -#' @keywords assertion -#' @family assertion #' @examples -#' data(admiral_advs) -#' assert_unit(admiral_advs, param = "WEIGHT", required_unit = "kg", get_unit_expr = VSSTRESU) -#' \dontrun{ -#' assert_unit(admiral_advs, param = "WEIGHT", required_unit = "g", get_unit_expr = VSSTRESU) -#' } +#' library(tibble) +#' advs <- tribble( +#' ~USUBJID, ~VSTESTCD, ~VSTRESN, ~VSSTRESU, ~PARAMCD, ~AVAL, +#' "P01", "WEIGHT", 80.1, "kg", "WEIGHT", 80.1, +#' "P02", "WEIGHT", 85.7, "kg", "WEIGHT", 85.7 +#' ) +#' +#' assert_unit(advs, param = "WEIGHT", required_unit = "kg", get_unit_expr = VSSTRESU) assert_unit <- function(dataset, param, required_unit, get_unit_expr) { assert_data_frame(dataset, required_vars = vars(PARAMCD)) assert_character_scalar(param) @@ -1015,9 +1018,15 @@ assert_unit <- function(dataset, param, required_unit, get_unit_expr) { #' @keywords assertion #' @family assertion #' @examples -#' data(admiral_advs) -#' assert_param_does_not_exist(admiral_advs, param = "HR") -#' try(assert_param_does_not_exist(admiral_advs, param = "WEIGHT")) +#' +#' library(tibble) +#' advs <- tribble( +#' ~USUBJID, ~VSTESTCD, ~VSTRESN, ~VSSTRESU, ~PARAMCD, ~AVAL, +#' "P01", "WEIGHT", 80.1, "kg", "WEIGHT", 80.1, +#' "P02", "WEIGHT", 85.7, "kg", "WEIGHT", 85.7 +#' ) +#' assert_param_does_not_exist(advs, param = "HR") +#' try(assert_param_does_not_exist(advs, param = "WEIGHT")) assert_param_does_not_exist <- function(dataset, param) { assert_data_frame(dataset, required_vars = vars(PARAMCD)) if (param %in% unique(dataset$PARAMCD)) { @@ -1209,6 +1218,8 @@ assert_varval_list <- function(arg, # nolint #' @export #' #' @examples +#' library(admiral) +#' #' death <- event_source( #' dataset_name = "adsl", #' filter = DTHFL == "Y", diff --git a/R/compat_friendly_type.R b/R/compat_friendly_type.R new file mode 100644 index 00000000..913039c0 --- /dev/null +++ b/R/compat_friendly_type.R @@ -0,0 +1,166 @@ +#' Return English-friendly Type +#' @param x Any R object. +#' @param value Whether to describe the value of `x`. +#' @param length Whether to mention the length of vectors and lists. +#' @return A string describing the type. Starts with an indefinite +#' article, e.g. "an integer vector". +#' @noRd +friendly_type_of <- function(x, value = TRUE, length = FALSE) { # nolint + if (rlang::is_missing(x)) { + return("absent") + } + + if (is.object(x)) { + if (inherits(x, "quosure")) { + type <- "quosure" + } else { + type <- paste(class(x), collapse = "/") + } + return(sprintf("a <%s> object", type)) + } + + if (!rlang::is_vector(x)) { + return(.rlang_as_friendly_type(typeof(x))) + } + + n_dim <- length(dim(x)) + + if (value && !n_dim) { + if (rlang::is_na(x)) { + return(switch(typeof(x), + logical = "`NA`", + integer = "an integer `NA`", + double = "a numeric `NA`", + complex = "a complex `NA`", + character = "a character `NA`", + .rlang_stop_unexpected_typeof(x) + )) + } + if (length(x) == 1 && !rlang::is_list(x)) { + return(switch(typeof(x), + logical = if (x) "`TRUE`" else "`FALSE`", + integer = "an integer", + double = "a number", + complex = "a complex number", + character = if (nzchar(x)) "a string" else "`\"\"`", + raw = "a raw value", + .rlang_stop_unexpected_typeof(x) + )) + } + if (length(x) == 0) { + return(switch(typeof(x), + logical = "an empty logical vector", + integer = "an empty integer vector", + double = "an empty numeric vector", + complex = "an empty complex vector", + character = "an empty character vector", + raw = "an empty raw vector", + list = "an empty list", + .rlang_stop_unexpected_typeof(x) + )) + } + } + + type <- .rlang_as_friendly_vector_type(typeof(x), n_dim) + + if (length && !n_dim) { + type <- paste0(type, sprintf(" of length %s", length(x))) + } + + type +} + +.rlang_as_friendly_vector_type <- function(type, n_dim) { + if (type == "list") { + if (n_dim < 2) { + return("a list") + } else if (n_dim == 2) { + return("a list matrix") + } else { + return("a list array") + } + } + + type <- switch(type, + logical = "a logical %s", + integer = "an integer %s", + numeric = , # nolint + double = "a double %s", + complex = "a complex %s", + character = "a character %s", + raw = "a raw %s", + type = paste0("a ", type, " %s") + ) + + if (n_dim < 2) { + kind <- "vector" + } else if (n_dim == 2) { + kind <- "matrix" + } else { + kind <- "array" + } + sprintf(type, kind) +} + +.rlang_as_friendly_type <- function(type) { + switch(type, + list = "a list", + NULL = "NULL", + environment = "an environment", + externalptr = "a pointer", + weakref = "a weak reference", + S4 = "an S4 object", + name = , # nolint + symbol = "a symbol", + language = "a call", + pairlist = "a pairlist node", + expression = "an expression vector", + char = "an internal string", + promise = "an internal promise", + ... = "an internal dots object", + any = "an internal `any` object", + bytecode = "an internal bytecode object", + primitive = , # nolint + builtin = , # nolint + special = "a primitive function", + closure = "a function", + type + ) +} + +.rlang_stop_unexpected_typeof <- function(x, call = rlang::caller_env()) { + rlang::abort( + sprintf("Unexpected type <%s>.", typeof(x)), + call = call + ) +} + +#' @param x The object type which does not conform to `what`. Its +#' `friendly_type_of()` is taken and mentioned in the error message. +#' @param what The friendly expected type. +#' @param ... Arguments passed to [abort()]. +#' @inheritParams args_error_context +#' @noRd +stop_input_type <- function(x, + what, + ..., + arg = rlang::caller_arg(x), + call = rlang::caller_env()) { + # From compat-cli.R + format_arg <- rlang::env_get( + nm = "format_arg", + last = topenv(), + default = NULL + ) + if (!is.function(format_arg)) { + format_arg <- function(x) sprintf("`%s`", x) + } + + message <- sprintf( + "%s must be %s, not %s.", + format_arg(arg), + what, + friendly_type_of(x) + ) + rlang::abort(message, ..., call = call) +} diff --git a/R/global.R b/R/global.R index cc4b915d..93837fb8 100644 --- a/R/global.R +++ b/R/global.R @@ -73,5 +73,7 @@ globalVariables(c( "CDISC_VALUE", "DOSE_WINDOW", "DOSE_COUNT", - "CONVERSION_FACTOR" + "CONVERSION_FACTOR", + "_unit", + "auto" )) diff --git a/R/reexports.R b/R/reexports.R new file mode 100644 index 00000000..9d41576a --- /dev/null +++ b/R/reexports.R @@ -0,0 +1,5 @@ +#' @export +dplyr::vars + +#' @export +dplyr::desc diff --git a/README.Rmd b/README.Rmd index 4c8a84fe..ea6078d8 100644 --- a/README.Rmd +++ b/README.Rmd @@ -72,3 +72,44 @@ remotes::install_github("pharmaverse/admiraldev", ref = "devel") | `get` | A function that ... +```{r, echo = FALSE, results = 'asis'} +nomnoml::nomnoml( + "[Release Schedule| +[Q3-2022] +[August 29th| +admiraldev +admiral.test +] + +[September 5th| +admiral +] + +[September 12th| +admiralonco +admiralroche +admiralext +] + +[Q4-2022] +[Logs| + R does not naturally create a log file + There are many possible ways to create a log file + Clinical Environment creates a unique siutation +] +[Q1-2023] +[R Logs| +Does a R Log need to be like a SAS Log? +Could a user decide on unique customization +A new way of thinking!!? +] +[Logging in R] -> [Logs] +[Audit-Ready] -> [Ready!] +[SAS Logs] -> [R Logs] +]", +width = 1000, +height = 500 +) +``` + + diff --git a/README.md b/README.md index 476678b1..35c31f69 100644 --- a/README.md +++ b/README.md @@ -68,3 +68,9 @@ GitHub use the following code: + +QStandardPaths: XDG\_RUNTIME\_DIR not set, defaulting to +‘/tmp/runtime-r590548’ TypeError: Attempting to change the setter of an +unconfigurable property. TypeError: Attempting to change the setter of +an unconfigurable property. +![](README_files/figure-markdown_strict/unnamed-chunk-2-1.png) diff --git a/README_files/figure-markdown_strict/unnamed-chunk-2-1.png b/README_files/figure-markdown_strict/unnamed-chunk-2-1.png new file mode 100644 index 00000000..2d25bb49 Binary files /dev/null and b/README_files/figure-markdown_strict/unnamed-chunk-2-1.png differ diff --git a/admiralext.Rproj b/admiralext.Rproj index c0504175..934df488 100644 --- a/admiralext.Rproj +++ b/admiralext.Rproj @@ -19,3 +19,4 @@ LineEndingConversion: Posix BuildType: Package PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace diff --git a/man/assert_character_scalar.Rd b/man/assert_character_scalar.Rd index 45cf5559..6167327a 100644 --- a/man/assert_character_scalar.Rd +++ b/man/assert_character_scalar.Rd @@ -74,7 +74,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_character_vector.Rd b/man/assert_character_vector.Rd index 8697c842..117bd274 100644 --- a/man/assert_character_vector.Rd +++ b/man/assert_character_vector.Rd @@ -48,7 +48,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_data_frame.Rd b/man/assert_data_frame.Rd index 61afbd0b..c8ba872f 100644 --- a/man/assert_data_frame.Rd +++ b/man/assert_data_frame.Rd @@ -32,6 +32,7 @@ a set of required variables } \examples{ library(admiral.test) +library(admiral) data(admiral_dm) example_fun <- function(dataset) { @@ -61,7 +62,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_filter_cond.Rd b/man/assert_filter_cond.Rd index 16d899c4..0bba6f23 100644 --- a/man/assert_filter_cond.Rd +++ b/man/assert_filter_cond.Rd @@ -53,7 +53,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_function.Rd b/man/assert_function.Rd index a739b5b0..91949bf3 100644 --- a/man/assert_function.Rd +++ b/man/assert_function.Rd @@ -55,7 +55,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_has_variables.Rd b/man/assert_has_variables.Rd index fc109870..a1b4c014 100644 --- a/man/assert_has_variables.Rd +++ b/man/assert_has_variables.Rd @@ -43,7 +43,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_integer_scalar.Rd b/man/assert_integer_scalar.Rd index 1ca65ef7..aa4bf030 100644 --- a/man/assert_integer_scalar.Rd +++ b/man/assert_integer_scalar.Rd @@ -53,7 +53,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_list_element.Rd b/man/assert_list_element.Rd index 09876d19..b7e37fc0 100644 --- a/man/assert_list_element.Rd +++ b/man/assert_list_element.Rd @@ -40,6 +40,8 @@ condition. If not, an error is issued and all elements of the list not fulfilling the condition are listed. } \examples{ +library(admiral) + death <- event_source( dataset_name = "adsl", filter = DTHFL == "Y", @@ -97,7 +99,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_list_of.Rd b/man/assert_list_of.Rd index 8ddffcf1..0033737a 100644 --- a/man/assert_list_of.Rd +++ b/man/assert_list_of.Rd @@ -50,7 +50,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_logical_scalar.Rd b/man/assert_logical_scalar.Rd index 9e3899bb..e5bb1409 100644 --- a/man/assert_logical_scalar.Rd +++ b/man/assert_logical_scalar.Rd @@ -51,7 +51,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_numeric_vector.Rd b/man/assert_numeric_vector.Rd index 8a4a23ea..3f17eb9e 100644 --- a/man/assert_numeric_vector.Rd +++ b/man/assert_numeric_vector.Rd @@ -45,7 +45,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_one_to_one.Rd b/man/assert_one_to_one.Rd index 06e20415..650205f7 100644 --- a/man/assert_one_to_one.Rd +++ b/man/assert_one_to_one.Rd @@ -44,7 +44,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_order_vars.Rd b/man/assert_order_vars.Rd index 923c2c37..a061bec8 100644 --- a/man/assert_order_vars.Rd +++ b/man/assert_order_vars.Rd @@ -20,6 +20,7 @@ calls created using \code{vars()} and returns the input invisibly otherwise. Checks if an argument is a valid list of order variables created using \code{vars()} } \examples{ + example_fun <- function(by_vars) { assert_order_vars(by_vars) } @@ -49,7 +50,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_param_does_not_exist.Rd b/man/assert_param_does_not_exist.Rd index 3e3811b1..8e11cf5f 100644 --- a/man/assert_param_does_not_exist.Rd +++ b/man/assert_param_does_not_exist.Rd @@ -19,9 +19,15 @@ dataset. Otherwise, the dataset is returned invisibly. Checks if a parameter (\code{PARAMCD}) does not exist in a dataset. } \examples{ -data(admiral_advs) -assert_param_does_not_exist(admiral_advs, param = "HR") -try(assert_param_does_not_exist(admiral_advs, param = "WEIGHT")) + +library(tibble) +advs <- tribble( + ~USUBJID, ~VSTESTCD, ~VSTRESN, ~VSSTRESU, ~PARAMCD, ~AVAL, + "P01", "WEIGHT", 80.1, "kg", "WEIGHT", 80.1, + "P02", "WEIGHT", 85.7, "kg", "WEIGHT", 85.7 +) +assert_param_does_not_exist(advs, param = "HR") +try(assert_param_does_not_exist(advs, param = "WEIGHT")) } \seealso{ Other assertion: @@ -40,7 +46,6 @@ Other assertion: \code{\link{assert_order_vars}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_s3_class.Rd b/man/assert_s3_class.Rd index 3b38b4e8..14dd7a2e 100644 --- a/man/assert_s3_class.Rd +++ b/man/assert_s3_class.Rd @@ -49,7 +49,6 @@ Other assertion: \code{\link{assert_order_vars}()}, \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_symbol.Rd b/man/assert_symbol.Rd index a8912065..5e4413e8 100644 --- a/man/assert_symbol.Rd +++ b/man/assert_symbol.Rd @@ -53,7 +53,6 @@ Other assertion: \code{\link{assert_order_vars}()}, \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()}, \code{\link{assert_varval_list}()} } diff --git a/man/assert_unit.Rd b/man/assert_unit.Rd index 6aeb6cc0..9404158b 100644 --- a/man/assert_unit.Rd +++ b/man/assert_unit.Rd @@ -25,35 +25,15 @@ Checks if a parameter (\code{PARAMCD}) in a dataset is provided in the expected unit. } \examples{ -data(admiral_advs) -assert_unit(admiral_advs, param = "WEIGHT", required_unit = "kg", get_unit_expr = VSSTRESU) -\dontrun{ -assert_unit(admiral_advs, param = "WEIGHT", required_unit = "g", get_unit_expr = VSSTRESU) -} -} -\seealso{ -Other assertion: -\code{\link{assert_character_scalar}()}, -\code{\link{assert_character_vector}()}, -\code{\link{assert_data_frame}()}, -\code{\link{assert_filter_cond}()}, -\code{\link{assert_function}()}, -\code{\link{assert_has_variables}()}, -\code{\link{assert_integer_scalar}()}, -\code{\link{assert_list_element}()}, -\code{\link{assert_list_of}()}, -\code{\link{assert_logical_scalar}()}, -\code{\link{assert_numeric_vector}()}, -\code{\link{assert_one_to_one}()}, -\code{\link{assert_order_vars}()}, -\code{\link{assert_param_does_not_exist}()}, -\code{\link{assert_s3_class}()}, -\code{\link{assert_symbol}()}, -\code{\link{assert_vars}()}, -\code{\link{assert_varval_list}()} +library(tibble) +advs <- tribble( + ~USUBJID, ~VSTESTCD, ~VSTRESN, ~VSSTRESU, ~PARAMCD, ~AVAL, + "P01", "WEIGHT", 80.1, "kg", "WEIGHT", 80.1, + "P02", "WEIGHT", 85.7, "kg", "WEIGHT", 85.7 +) + +assert_unit(advs, param = "WEIGHT", required_unit = "kg", get_unit_expr = VSSTRESU) } \author{ Stefan Bundfuss } -\concept{assertion} -\keyword{assertion} diff --git a/man/assert_vars.Rd b/man/assert_vars.Rd index de9ed285..c1246470 100644 --- a/man/assert_vars.Rd +++ b/man/assert_vars.Rd @@ -50,7 +50,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_varval_list}()} } \author{ diff --git a/man/assert_varval_list.Rd b/man/assert_varval_list.Rd index 2adb574f..33710e12 100644 --- a/man/assert_varval_list.Rd +++ b/man/assert_varval_list.Rd @@ -60,7 +60,6 @@ Other assertion: \code{\link{assert_param_does_not_exist}()}, \code{\link{assert_s3_class}()}, \code{\link{assert_symbol}()}, -\code{\link{assert_unit}()}, \code{\link{assert_vars}()} } \author{ diff --git a/man/reexports.Rd b/man/reexports.Rd new file mode 100644 index 00000000..af251f24 --- /dev/null +++ b/man/reexports.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reexports.R +\docType{import} +\name{reexports} +\alias{reexports} +\alias{vars} +\alias{desc} +\title{Objects exported from other packages} +\keyword{internal} +\description{ +These objects are imported from other packages. Follow the links +below to see their documentation. + +\describe{ + \item{dplyr}{\code{\link[dplyr]{desc}}, \code{\link[dplyr]{vars}}} +}} + diff --git a/tests/testthat/test-compat_friendly_type.R b/tests/testthat/test-compat_friendly_type.R new file mode 100644 index 00000000..5c775ce2 --- /dev/null +++ b/tests/testthat/test-compat_friendly_type.R @@ -0,0 +1,37 @@ +test_that("friendly_type_of() supports objects", { + expect_equal(friendly_type_of(mtcars), "a object") + expect_equal(friendly_type_of(quo(1)), "a object") +}) + +test_that("friendly_type_of() supports matrices and arrays (#141)", { + expect_equal(friendly_type_of(list()), "an empty list") + expect_equal(friendly_type_of(matrix(list(1, 2))), "a list matrix") + expect_equal(friendly_type_of(array(list(1, 2, 3), dim = 1:3)), "a list array") + + expect_equal(friendly_type_of(matrix(1:3)), "an integer matrix") + expect_equal(friendly_type_of(array(1:3, dim = 1:3)), "an integer array") + + expect_equal(friendly_type_of(matrix(letters)), "a character matrix") + expect_equal(friendly_type_of(array(letters[1:3], dim = 1:3)), "a character array") +}) + + +test_that("friendly_type_of() handles scalars", { + expect_equal(friendly_type_of(NA), "`NA`") + + expect_equal(friendly_type_of(TRUE), "`TRUE`") + expect_equal(friendly_type_of(FALSE), "`FALSE`") + + expect_equal(friendly_type_of(1L), "an integer") + expect_equal(friendly_type_of(1.0), "a number") + expect_equal(friendly_type_of(1i), "a complex number") + expect_equal(friendly_type_of(as.raw(1)), "a raw value") + + expect_equal(friendly_type_of("foo"), "a string") + expect_equal(friendly_type_of(""), "`\"\"`") + + expect_equal(friendly_type_of(list(1)), "a list") + + expect_equal(friendly_type_of(matrix(NA)), "a logical matrix") + expect_equal(friendly_type_of(matrix(1)), "a double matrix") +})