From eb646f72a80ac49f548ede792c9f5cb3694bc0bb Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 22 Jan 2026 11:41:23 +0100 Subject: [PATCH 1/6] refactor code to reuse functions in teal.slice --- R/teal_slices.R | 63 ++++++++++++++-------------------- man/dot-copy_from_namespace.Rd | 19 ++++++++++ 2 files changed, 45 insertions(+), 37 deletions(-) create mode 100644 man/dot-copy_from_namespace.Rd diff --git a/R/teal_slices.R b/R/teal_slices.R index d4547b4eff..a5b386ed67 100644 --- a/R/teal_slices.R +++ b/R/teal_slices.R @@ -123,43 +123,6 @@ teal_slices <- function(..., }) } - -#' @rdname teal_slices -#' @export -#' @keywords internal -#' -as.teal_slices <- function(x) { # nolint: object_name. - checkmate::assert_list(x) - lapply(x, checkmate::assert_list, names = "named", .var.name = "list element") - - attrs <- attributes(unclass(x)) - ans <- lapply(x, function(x) if (is.teal_slice(x)) x else as.teal_slice(x)) - do.call(teal_slices, c(ans, attrs)) -} - - -#' @rdname teal_slices -#' @export -#' @keywords internal -#' -c.teal_slices <- function(...) { - x <- list(...) - checkmate::assert_true(all(vapply(x, is.teal_slices, logical(1L))), .var.name = "all arguments are teal_slices") - - all_attributes <- lapply(x, attributes) - all_attributes <- coalesce_r(all_attributes) - all_attributes <- all_attributes[names(all_attributes) != "class"] - - do.call( - teal_slices, - c( - unique(unlist(x, recursive = FALSE)), - all_attributes - ) - ) -} - - #' Deep copy `teal_slices` #' #' it's important to create a new copy of `teal_slices` when @@ -179,3 +142,29 @@ deep_copy_filter <- function(filter) { filter_copy }) } + + +#' Function to copy functions from other namespaces +#' +#' It differs from `getFromNamespace` as it returns a copy of the function +#' so it is a part of `teal` namespace. Useful when we require function from other namespace +#' where this function calls other functions from `teal` namespace (see `as.teal_slices`, `c.teal_slices`). +#' @inheritParams utils::getFromNamespace +#' @keywords internal +.copy_from_namespace <- function(x, ns) { + original_fun <- utils::getFromNamespace(x, ns = ns) + eval(parse(text = deparse(original_fun))) +} + +#' @rdname teal_slices +#' @export +#' @keywords internal +#' +as.teal_slices <- .copy_from_namespace("as.teal_slices", "teal.slice") + + +#' @rdname teal_slices +#' @export +#' @keywords internal +#' +c.teal_slices <- .copy_from_namespace("c.teal_slices", "teal.slice") diff --git a/man/dot-copy_from_namespace.Rd b/man/dot-copy_from_namespace.Rd new file mode 100644 index 0000000000..07b913160b --- /dev/null +++ b/man/dot-copy_from_namespace.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/teal_slices.R +\name{.copy_from_namespace} +\alias{.copy_from_namespace} +\title{Function to copy functions from other namespaces} +\usage{ +.copy_from_namespace(x, ns) +} +\arguments{ +\item{x}{an object name (given as a character string).} + +\item{ns}{a namespace, or character string giving the namespace.} +} +\description{ +It differs from \code{getFromNamespace} as it returns a copy of the function +so it is a part of \code{teal} namespace. Useful when we require function from other namespace +where this function calls other functions from \code{teal} namespace (see \code{as.teal_slices}, \code{c.teal_slices}). +} +\keyword{internal} From c9ef4f017c5ceaf5d78c48aaa0968a78e6633534 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 22 Jan 2026 11:41:31 +0100 Subject: [PATCH 2/6] tests --- tests/testthat/test-teal_slices.R | 53 ++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-teal_slices.R b/tests/testthat/test-teal_slices.R index a64f518639..7bcc337f23 100644 --- a/tests/testthat/test-teal_slices.R +++ b/tests/testthat/test-teal_slices.R @@ -111,10 +111,6 @@ testthat::test_that( } ) - -# from different file - - testthat::test_that("teal_slices mapping should be an empty list or a named list or missing", { testthat::expect_no_error( teal_slices( @@ -156,3 +152,52 @@ testthat::test_that("teal_slices mapping should be an empty list or a named list "Assertion.+failed" ) }) + +testthat::test_that("c.teal_slices combines mapping of teal_slices objects", { + tss1 <- teal_slices( + teal.slice::teal_slice(dataname = "data1", varname = "var1", id = "test1"), + module_specific = TRUE, + mapping = list(module1 = "test1") + ) + tss2 <- teal_slices( + teal.slice::teal_slice(dataname = "data2", varname = "var2", id = "test2"), + module_specific = TRUE, + mapping = list(module2 = "test2") + ) + testthat::expect_identical( + c(tss1, tss2), + teal_slices( + tss1[[1]], tss2[[1]], + module_specific = TRUE, + mapping = list( + module1 = "test1", + module2 = "test2" + ) + ) + ) +}) + +testthat::test_that("c.teal_slices combines mapping of two equal slices objects but ignores adding duplicated one", { + tss1 <- teal_slices( + teal.slice::teal_slice(dataname = "data1", varname = "var1", id = "test1"), + module_specific = TRUE, + mapping = list(module1 = "test1") + ) + tss2 <- teal_slices( + teal.slice::teal_slice(dataname = "data1", varname = "var1", id = "test1"), + module_specific = TRUE, + mapping = list(module2 = "test1") + ) + + testthat::expect_identical( + c(tss1, tss2), + teal_slices( + tss1[[1]], + module_specific = TRUE, + mapping = list( + module1 = "test1", + module2 = "test1" + ) + ) + ) +}) From a9987aa5a63ea7c23c23382b66a6c030d0619eb7 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 22 Jan 2026 12:02:03 +0100 Subject: [PATCH 3/6] lintr --- R/checkmate.R | 2 +- R/module_transform_data.R | 4 ++-- R/teal_slices.R | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/R/checkmate.R b/R/checkmate.R index a6463c175e..7e754d2e51 100644 --- a/R/checkmate.R +++ b/R/checkmate.R @@ -12,7 +12,7 @@ check_reactive <- function(x, null.ok = FALSE) { # nolint: object_name_linter. paste0(cl, collapse = "','") )) } - return(TRUE) + TRUE } #' @rdname check_reactive test_reactive <- function(x, null.ok = FALSE) { # nolint: object_name_linter. diff --git a/R/module_transform_data.R b/R/module_transform_data.R index 3c9daa7d2f..a9558ebd7f 100644 --- a/R/module_transform_data.R +++ b/R/module_transform_data.R @@ -25,7 +25,7 @@ ui_transform_teal_data <- function(id, transformators, class = "well") { transformators <- list(transformators) } checkmate::assert_list(transformators, "teal_transform_module") - names(transformators) <- sprintf("transform_%d", seq_len(length(transformators))) + names(transformators) <- sprintf("transform_%d", seq_along(transformators)) lapply( names(transformators), @@ -75,7 +75,7 @@ srv_transform_teal_data <- function(id, data, transformators, modules = NULL, is transformators <- list(transformators) } checkmate::assert_list(transformators, "teal_transform_module", null.ok = TRUE) - names(transformators) <- sprintf("transform_%d", seq_len(length(transformators))) + names(transformators) <- sprintf("transform_%d", seq_along(transformators)) moduleServer(id, function(input, output, session) { module_output <- Reduce( diff --git a/R/teal_slices.R b/R/teal_slices.R index a5b386ed67..3c125fd1ec 100644 --- a/R/teal_slices.R +++ b/R/teal_slices.R @@ -160,7 +160,7 @@ deep_copy_filter <- function(filter) { #' @export #' @keywords internal #' -as.teal_slices <- .copy_from_namespace("as.teal_slices", "teal.slice") +as.teal_slices <- .copy_from_namespace("as.teal_slices", "teal.slice") # nolint: object_name_linter. #' @rdname teal_slices From 72b98bc48cc4a4d3674e351c0bff18895e75d56f Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Thu, 22 Jan 2026 12:16:34 +0100 Subject: [PATCH 4/6] linkind dependent --- DESCRIPTION | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DESCRIPTION b/DESCRIPTION index 46ba078dd2..5bf9db86b4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -96,6 +96,8 @@ Language: en-US LazyData: true Roxygen: list(markdown = TRUE, packages = c("roxy.shinylive")) RoxygenNote: 7.3.3 +Remotes: + insightsengineering/teal.slice@1683_ignore_duplicated_slice Collate: 'TealAppDriver.R' 'after.R' From 4b27256c6e5136701c53afe7c1d2946ae671b01d Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Fri, 23 Jan 2026 09:14:33 +0100 Subject: [PATCH 5/6] @averissimo --- R/teal_slices.R | 19 ++++++++----------- man/dot-copy_from_namespace.Rd | 19 ------------------- man/dot-copy_to_teal.Rd | 13 +++++++++++++ 3 files changed, 21 insertions(+), 30 deletions(-) delete mode 100644 man/dot-copy_from_namespace.Rd create mode 100644 man/dot-copy_to_teal.Rd diff --git a/R/teal_slices.R b/R/teal_slices.R index 3c125fd1ec..af234cb115 100644 --- a/R/teal_slices.R +++ b/R/teal_slices.R @@ -144,27 +144,24 @@ deep_copy_filter <- function(filter) { } -#' Function to copy functions from other namespaces +#' Copy functions to `teal` namespace #' -#' It differs from `getFromNamespace` as it returns a copy of the function -#' so it is a part of `teal` namespace. Useful when we require function from other namespace -#' where this function calls other functions from `teal` namespace (see `as.teal_slices`, `c.teal_slices`). -#' @inheritParams utils::getFromNamespace +#' Useful when we require function from other namespace where this function +#' calls other functions from `teal` namespace (see `as.teal_slices`, `c.teal_slices`). #' @keywords internal -.copy_from_namespace <- function(x, ns) { - original_fun <- utils::getFromNamespace(x, ns = ns) - eval(parse(text = deparse(original_fun))) +.copy_to_teal <- function(fun) { + environment(fun) <- getNamespace("teal") + fun } #' @rdname teal_slices #' @export #' @keywords internal #' -as.teal_slices <- .copy_from_namespace("as.teal_slices", "teal.slice") # nolint: object_name_linter. - +as.teal_slices <- .copy_to_teal(teal.slice::as.teal_slices) # nolint: object_name_linter. #' @rdname teal_slices #' @export #' @keywords internal #' -c.teal_slices <- .copy_from_namespace("c.teal_slices", "teal.slice") +c.teal_slices <- .copy_to_teal(utils::getS3method("c", "teal_slices", envir = getNamespace("teal.slice"))) diff --git a/man/dot-copy_from_namespace.Rd b/man/dot-copy_from_namespace.Rd deleted file mode 100644 index 07b913160b..0000000000 --- a/man/dot-copy_from_namespace.Rd +++ /dev/null @@ -1,19 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/teal_slices.R -\name{.copy_from_namespace} -\alias{.copy_from_namespace} -\title{Function to copy functions from other namespaces} -\usage{ -.copy_from_namespace(x, ns) -} -\arguments{ -\item{x}{an object name (given as a character string).} - -\item{ns}{a namespace, or character string giving the namespace.} -} -\description{ -It differs from \code{getFromNamespace} as it returns a copy of the function -so it is a part of \code{teal} namespace. Useful when we require function from other namespace -where this function calls other functions from \code{teal} namespace (see \code{as.teal_slices}, \code{c.teal_slices}). -} -\keyword{internal} diff --git a/man/dot-copy_to_teal.Rd b/man/dot-copy_to_teal.Rd new file mode 100644 index 0000000000..57b83cffb8 --- /dev/null +++ b/man/dot-copy_to_teal.Rd @@ -0,0 +1,13 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/teal_slices.R +\name{.copy_to_teal} +\alias{.copy_to_teal} +\title{Copy functions to \code{teal} namespace} +\usage{ +.copy_to_teal(fun) +} +\description{ +Useful when we require function from other namespace where this function +calls other functions from \code{teal} namespace (see \code{as.teal_slices}, \code{c.teal_slices}). +} +\keyword{internal} From 4d2cbdc47ec5970a0af2aaa361b0d4be998ab7d7 Mon Sep 17 00:00:00 2001 From: Dawid Kaledkowski Date: Fri, 23 Jan 2026 14:18:09 +0100 Subject: [PATCH 6/6] prepare to merge --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5bf9db86b4..40bd0576c3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -97,7 +97,7 @@ LazyData: true Roxygen: list(markdown = TRUE, packages = c("roxy.shinylive")) RoxygenNote: 7.3.3 Remotes: - insightsengineering/teal.slice@1683_ignore_duplicated_slice + insightsengineering/teal.slice@main Collate: 'TealAppDriver.R' 'after.R'