From 0ede485e6416daaa2a5f96d952558d240ece0de1 Mon Sep 17 00:00:00 2001 From: kpagacz Date: Thu, 12 May 2022 16:10:17 +0200 Subject: [PATCH] feat: added human-readable string represtations of filtering classes * minor improvements to docs Related to insightsengineering/teal.reporter#8 --- R/FilterState.R | 69 +++++++++++++++++++---- R/FilterStates.R | 61 +++++++++----------- R/FilteredDataset.R | 2 +- man/DFFilterStates.Rd | 64 +++------------------ man/DateFilterState.Rd | 23 +++++++- man/DatetimeFilterState.Rd | 23 +++++++- man/MAEFilterStates.Rd | 40 +++---------- man/MatrixFilterStates.Rd | 26 ++------- man/SEFilterStates.Rd | 26 ++------- tests/testthat/test-DFFilterStates.R | 46 +++++++++++++++ tests/testthat/test-DateFilterState.R | 47 +++++++++++++++ tests/testthat/test-DatetimeFilterState.R | 52 +++++++++++++++++ tests/testthat/test-FilterState.R | 38 ++++--------- tests/testthat/test-FilteredDataset.R | 16 ++++++ tests/testthat/test-MAEFilterStates.R | 55 ++++++++++++++++++ tests/testthat/test-RangeFilterState.R | 42 +++++--------- tests/testthat/test-SEFilterStates.R | 52 +++++++++++++++++ tests/testthat/test-init_filter_state.R | 7 ++- 18 files changed, 452 insertions(+), 237 deletions(-) diff --git a/R/FilterState.R b/R/FilterState.R index accc2285d..55a945305 100644 --- a/R/FilterState.R +++ b/R/FilterState.R @@ -362,13 +362,15 @@ FilterState <- R6::R6Class( # nolint #' @return `character(1)` the formatted string #' format = function(indent = 0) { - checkmate::assert_number(indent, finite = TRUE) + checkmate::assert_number(indent, finite = TRUE, lower = 0) - whitespace_indent <- paste0(rep(" ", indent), collapse = "") - formatted <- c(paste0(whitespace_indent, "Filtering on: ", self$get_varname())) - selected <- paste0(format(self$get_selected(), nsmall = 3), collapse = " ") - formatted <- c(formatted, paste0(whitespace_indent, " ", "Selected: ", selected)) - paste(formatted, collapse = "\n") + sprintf( + "%sFiltering on: %s\n%1$s Selected values: %s\n%1$s Include missing values: %s", + format("", width = indent), + self$get_varname(deparse = TRUE), + paste0(format(self$get_selected(), nsmall = 3), collapse = " "), + format(self$get_keep_na()) + ) }, #' @description @@ -1296,13 +1298,16 @@ RangeFilterState <- R6::R6Class( # nolint #' @return `character(1)` the formatted string #' format = function(indent = 0) { - checkmate::assert_number(indent, finite = TRUE) + checkmate::assert_number(indent, finite = TRUE, lower = 0) - whitespace_indent <- paste0(rep(" ", indent), collapse = "") - formatted <- c(paste0(whitespace_indent, "Filtering on: ", self$get_varname())) - selected <- format(self$get_selected(), nsmall = 3) - formatted <- c(formatted, paste0(whitespace_indent, " ", "Range: ", selected[1], " - ", selected[2])) - paste(formatted, collapse = "\n") + sprintf( + "%sFiltering on: %s\n%1$s Selected range: %s - %s\n%1$s Include missing values: %s", + format("", width = indent), + self$get_varname(deparse = TRUE), + format(self$get_selected(), nsmall = 3)[1], + format(self$get_selected(), nsmall = 3)[2], + format(self$get_keep_na()) + ) }, #' @description @@ -2082,6 +2087,26 @@ DateFilterState <- R6::R6Class( # nolint return(invisible(self)) }, + #' @description + #' Returns a formatted string representing this `DateFilterState`. + #' + #' @param indent (`numeric(1)`) the number of spaces before after each new line character of the formatted string. + #' Default: 0 + #' @return `character(1)` the formatted string + #' + format = function(indent = 0) { + checkmate::assert_number(indent, finite = TRUE, lower = 0) + + sprintf( + "%sFiltering on: %s\n%1$s Selected range: %s - %s\n%1$s Include missing values: %s", + format("", width = indent), + self$get_varname(deparse = TRUE), + format(self$get_selected(), nsmall = 3)[1], + format(self$get_selected(), nsmall = 3)[2], + format(self$get_keep_na()) + ) + }, + #' @description #' Answers the question of whether the current settings and values selected actually filters out any values. #' @return logical scalar @@ -2380,6 +2405,26 @@ DatetimeFilterState <- R6::R6Class( # nolint return(invisible(self)) }, + #' @description + #' Returns a formatted string representing this `DatetimeFilterState`. + #' + #' @param indent (`numeric(1)`) the number of spaces before after each new line character of the formatted string. + #' Default: 0 + #' @return `character(1)` the formatted string + #' + format = function(indent = 0) { + checkmate::assert_number(indent, finite = TRUE, lower = 0) + + sprintf( + "%sFiltering on: %s\n%1$s Selected range: %s - %s\n%1$s Include missing values: %s", + format("", width = indent), + self$get_varname(deparse = TRUE), + format(self$get_selected(), nsmall = 3)[1], + format(self$get_selected(), nsmall = 3)[2], + format(self$get_keep_na()) + ) + }, + #' @description #' Answers the question of whether the current settings and values selected actually filters out any values. #' @return logical scalar diff --git a/R/FilterStates.R b/R/FilterStates.R index bc3645746..5ed00b0d2 100644 --- a/R/FilterStates.R +++ b/R/FilterStates.R @@ -665,14 +665,15 @@ FilterStates <- R6::R6Class( # nolint ) ) -#' Specialization of `FilterStates` for a base `data.frame`. +#' @title DFFFilterStates +#' @description Specialization of `FilterStates` for a base `data.frame`. #' #' @keywords internal DFFilterStates <- R6::R6Class( # nolint classname = "DFFilterStates", inherit = FilterStates, public = list( - #' Initializes `DFFilterStates` object + #' @description Initializes `DFFilterStates` object #' #' Initializes `DFFilterStates` object by setting `input_dataname`, #' `output_dataname` and initializing `ReactiveQueue`. This class contains a @@ -712,14 +713,13 @@ DFFilterStates <- R6::R6Class( # nolint #' #' @param indent (`numeric(1)`) the number of spaces before each line of the representation #' @return `character(1)` the formatted string - #' @examples - #' format = function(indent = 0) { - formatted_states <- c() + checkmate::assert_number(indent, finite = TRUE, lower = 0) - for (state in self$queue_get(1L)) { - formatted_states <- c(formatted_states, paste0(state$format(indent = indent))) - } + formatted_states <- vapply( + self$queue_get(1L), function(state) state$format(indent = indent), + USE.NAMES = FALSE, FUN.VALUE = character(1) + ) paste(formatted_states, collapse = "\n") }, @@ -1076,13 +1076,14 @@ DFFilterStates <- R6::R6Class( # nolint ) -#' Specialization of `FilterStates` for `MultiAssayExperiment`. +#' @title MAEFilterStates +#' @description Specialization of `FilterStates` for `MultiAssayExperiment`. #' @keywords internal MAEFilterStates <- R6::R6Class( # nolint classname = "MAEFilterStates", inherit = FilterStates, public = list( - #' Initialize `MAEFilterStates` object + #' @description Initializes `MAEFilterStates` object #' #' Initialize `MAEFilterStates` object #' @@ -1122,24 +1123,19 @@ MAEFilterStates <- R6::R6Class( # nolint #' #' @param indent (`numeric(1)`) the number of spaces before each line of the representation #' @return `character(1)` the formatted string - #' @examples - #' format = function(indent = 0) { - checkmate::assert_number(indent, finite = TRUE) + checkmate::assert_number(indent, finite = TRUE, lower = 0) if (length(self$queue_get(1L)) > 0) { - whitespace_indent <- paste0(rep(" ", indent), collapse = "") - formatted_states <- c(paste0(whitespace_indent, "Subject filters:")) + formatted_states <- sprintf("%sSubject filters:", format("", width = indent)) for (state in self$queue_get(1L)) formatted_states <- c(formatted_states, state$format(indent = indent + 2)) paste(formatted_states, collapse = "\n") } }, - #' Get function name - #' - #' Get function name used to create filter call. - #' For `MAEFilterStates` - #' `MultiAssayExperiment::subsetByColData` is used. + #' @description + #' Returns function name used to create filter call. + #' For `MAEFilterStates` `MultiAssayExperiment::subsetByColData` is used. #' @return `character(1)` get_fun = function() { return("MultiAssayExperiment::subsetByColData") @@ -1248,7 +1244,8 @@ MAEFilterStates <- R6::R6Class( # nolint NULL }, - #' @description Remove a variable from the `ReactiveQueue` and its corresponding UI element. + #' @description + #' Removes a variable from the `ReactiveQueue` and its corresponding UI element. #' #' @param element_id (`character(1)`)\cr name of `ReactiveQueue` element. #' @@ -1456,13 +1453,14 @@ MAEFilterStates <- R6::R6Class( # nolint ) ) -#' Specialization of `FilterStates` for `SummaryExperiment`. +#' @title SEFilterStates +#' @description Specialization of `FilterStates` for `SummaryExperiment`. #' @keywords internal SEFilterStates <- R6::R6Class( # nolint classname = "SEFilterStates", inherit = FilterStates, public = list( - #' Initialize `SEFilterStates` object + #' @description Initialize `SEFilterStates` object #' #' Initialize `SEFilterStates` object #' @@ -1493,12 +1491,10 @@ SEFilterStates <- R6::R6Class( # nolint #' #' @param indent (`numeric(1)`) the number of spaces before each line of the representation #' @return `character(1)` the formatted string - #' @examples - #' format = function(indent = 0) { - checkmate::assert_number(indent, finite = TRUE) + checkmate::assert_number(indent, finite = TRUE, lower = 0) - whitespace_indent <- paste0(rep(" ", indent), collapse = "") + whitespace_indent <- format("", width = indent) formatted_states <- c() if (!is.null(self$queue_get(queue_index = "subset"))) { formatted_states <- c(formatted_states, paste0(whitespace_indent, " Subsetting:")) @@ -1508,7 +1504,7 @@ SEFilterStates <- R6::R6Class( # nolint } if (!is.null(self$queue_get(queue_index = "select"))) { - formatted_states <- c(formatted_states, paste0(whitespace_indent, "Selecting:")) + formatted_states <- c(formatted_states, paste0(whitespace_indent, " Selecting:")) for (state in self$queue_get(queue_index = "select")) { formatted_states <- c(formatted_states, state$format(indent = indent + 4)) } @@ -2027,13 +2023,14 @@ SEFilterStates <- R6::R6Class( # nolint ) ) -#' Specialization of `FilterStates` for a base matrix. +#' @title MatrixFilterStates +#' @description Specialization of `FilterStates` for a base matrix. #' @keywords internal MatrixFilterStates <- R6::R6Class( # nolint classname = "MatrixFilterStates", inherit = FilterStates, public = list( - #' Initialize `MatrixFilterStates` object + #' @description Initialize `MatrixFilterStates` object #' #' Initialize `MatrixFilterStates` object #' @@ -2060,10 +2057,8 @@ MatrixFilterStates <- R6::R6Class( # nolint #' #' @param indent (`numeric(1)`) the number of spaces before each line of the representation #' @return `character(1)` the formatted string - #' @examples - #' format = function(indent = 0) { - checkmate::assert_number(indent, finite = TRUE) + checkmate::assert_number(indent, finite = TRUE, lower = 0) formatted_states <- c() whitespace_indent <- paste0(rep(" ", indent), collapse = "") diff --git a/R/FilteredDataset.R b/R/FilteredDataset.R index be6575c7f..99c39a98c 100644 --- a/R/FilteredDataset.R +++ b/R/FilteredDataset.R @@ -173,7 +173,7 @@ FilteredDataset <- R6::R6Class( # nolint #' @return `character(1)` the formatted string representing the filter state #' get_formatted_filter_state = function() { - out <- c(paste0("Filters for dataset: ", self$get_dataname())) + out <- paste0("Filters for dataset: ", self$get_dataname()) for (states in self$get_filter_states()) out <- c(out, states$format(indent = 2)) paste(out, collapse = "\n") }, diff --git a/man/DFFilterStates.Rd b/man/DFFilterStates.Rd index 0bf0a8fe2..adaf3edce 100644 --- a/man/DFFilterStates.Rd +++ b/man/DFFilterStates.Rd @@ -2,20 +2,12 @@ % Please edit documentation in R/FilterStates.R \name{DFFilterStates} \alias{DFFilterStates} -\title{Specialization of \code{FilterStates} for a base \code{data.frame}.} +\title{DFFFilterStates} \description{ -Specialization of \code{FilterStates} for a base \code{data.frame}. - Specialization of \code{FilterStates} for a base \code{data.frame}. } \examples{ -## ------------------------------------------------ -## Method `DFFilterStates$format` -## ------------------------------------------------ - - - ## ------------------------------------------------ ## Method `DFFilterStates$set_filter_state` ## ------------------------------------------------ @@ -35,46 +27,7 @@ dffs$set_filter_state(state = fs, data = iris) shiny::isolate(dffs$get_filter_state()) } -\keyword{(`...`).} -\keyword{(`dplyr::filter`),} -\keyword{Initializes} -\keyword{This} -\keyword{`DFFilterStates`} -\keyword{`ReactiveQueue`} -\keyword{`ReactiveQueue`.} -\keyword{`input_dataname`,} -\keyword{`output_dataname`} -\keyword{a} -\keyword{and} -\keyword{are} -\keyword{arguments} -\keyword{associated} -\keyword{by} -\keyword{calling} -\keyword{class} -\keyword{conditions} -\keyword{contains} -\keyword{function} -\keyword{initializing} \keyword{internal} -\keyword{list} -\keyword{means} -\keyword{name} -\keyword{no} -\keyword{object} -\keyword{of} -\keyword{passed} -\keyword{setting} -\keyword{single} -\keyword{specified} -\keyword{that} -\keyword{the} -\keyword{this} -\keyword{to} -\keyword{unnamed} -\keyword{when} -\keyword{which} -\keyword{with} \section{Super class}{ \code{\link[teal.slice:FilterStates]{teal.slice::FilterStates}} -> \code{DFFilterStates} } @@ -111,6 +64,13 @@ shiny::isolate(dffs$get_filter_state()) \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-new}{}}} \subsection{Method \code{new()}}{ +Initializes \code{DFFilterStates} object + +Initializes \code{DFFilterStates} object by setting \code{input_dataname}, +\code{output_dataname} and initializing \code{ReactiveQueue}. This class contains a +single \code{ReactiveQueue} with no specified name which means that +when calling the function associated to this class (\code{dplyr::filter}), a list of +conditions are passed to unnamed arguments (\code{...}). \subsection{Usage}{ \if{html}{\out{
}}\preformatted{DFFilterStates$new(input_dataname, output_dataname, datalabel, varlabels, keys)}\if{html}{\out{
}} } @@ -156,14 +116,6 @@ Returns the formatted string representing this \code{FilterStates} object. \subsection{Returns}{ \code{character(1)} the formatted string } -\subsection{Examples}{ -\if{html}{\out{
}} -\preformatted{ -} -\if{html}{\out{
}} - -} - } \if{html}{\out{
}} \if{html}{\out{}} diff --git a/man/DateFilterState.Rd b/man/DateFilterState.Rd index f9d2cfcc6..31fa8d7ae 100644 --- a/man/DateFilterState.Rd +++ b/man/DateFilterState.Rd @@ -45,6 +45,7 @@ filter$set_selected(c(date + 1, date + 2)) \subsection{Public methods}{ \itemize{ \item \href{#method-new}{\code{DateFilterState$new()}} +\item \href{#method-format}{\code{DateFilterState$format()}} \item \href{#method-is_any_filtered}{\code{DateFilterState$is_any_filtered()}} \item \href{#method-get_call}{\code{DateFilterState$get_call()}} \item \href{#method-ui}{\code{DateFilterState$ui()}} @@ -57,7 +58,6 @@ filter$set_selected(c(date + 1, date + 2)) \out{
Inherited methods} \itemize{ \item \out{}\href{../../teal.slice/html/FilterState.html#method-destroy_observers}{\code{teal.slice::FilterState$destroy_observers()}}\out{} -\item \out{}\href{../../teal.slice/html/FilterState.html#method-format}{\code{teal.slice::FilterState$format()}}\out{} \item \out{}\href{../../teal.slice/html/FilterState.html#method-get_dataname}{\code{teal.slice::FilterState$get_dataname()}}\out{} \item \out{}\href{../../teal.slice/html/FilterState.html#method-get_keep_na}{\code{teal.slice::FilterState$get_keep_na()}}\out{} \item \out{}\href{../../teal.slice/html/FilterState.html#method-get_selected}{\code{teal.slice::FilterState$get_selected()}}\out{} @@ -115,6 +115,27 @@ whether condition calls should be prefixed by dataname. Possible values: } } \if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-format}{}}} +\subsection{Method \code{format()}}{ +Returns a formatted string representing this \code{DateFilterState}. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{DateFilterState$format(indent = 0)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{indent}}{(\code{numeric(1)}) the number of spaces before after each new line character of the formatted string. +Default: 0} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{character(1)} the formatted string +} +} +\if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-is_any_filtered}{}}} \subsection{Method \code{is_any_filtered()}}{ diff --git a/man/DatetimeFilterState.Rd b/man/DatetimeFilterState.Rd index 509ad12e6..8b540a5bf 100644 --- a/man/DatetimeFilterState.Rd +++ b/man/DatetimeFilterState.Rd @@ -45,6 +45,7 @@ filter$set_selected(c(date + 1, date + 2)) \subsection{Public methods}{ \itemize{ \item \href{#method-new}{\code{DatetimeFilterState$new()}} +\item \href{#method-format}{\code{DatetimeFilterState$format()}} \item \href{#method-is_any_filtered}{\code{DatetimeFilterState$is_any_filtered()}} \item \href{#method-get_call}{\code{DatetimeFilterState$get_call()}} \item \href{#method-ui}{\code{DatetimeFilterState$ui()}} @@ -57,7 +58,6 @@ filter$set_selected(c(date + 1, date + 2)) \out{
Inherited methods} \itemize{ \item \out{}\href{../../teal.slice/html/FilterState.html#method-destroy_observers}{\code{teal.slice::FilterState$destroy_observers()}}\out{} -\item \out{}\href{../../teal.slice/html/FilterState.html#method-format}{\code{teal.slice::FilterState$format()}}\out{} \item \out{}\href{../../teal.slice/html/FilterState.html#method-get_dataname}{\code{teal.slice::FilterState$get_dataname()}}\out{} \item \out{}\href{../../teal.slice/html/FilterState.html#method-get_keep_na}{\code{teal.slice::FilterState$get_keep_na()}}\out{} \item \out{}\href{../../teal.slice/html/FilterState.html#method-get_selected}{\code{teal.slice::FilterState$get_selected()}}\out{} @@ -119,6 +119,27 @@ whether condition calls should be prefixed by dataname. Possible values: } } \if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-format}{}}} +\subsection{Method \code{format()}}{ +Returns a formatted string representing this \code{DatetimeFilterState}. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{DatetimeFilterState$format(indent = 0)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{indent}}{(\code{numeric(1)}) the number of spaces before after each new line character of the formatted string. +Default: 0} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{character(1)} the formatted string +} +} +\if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-is_any_filtered}{}}} \subsection{Method \code{is_any_filtered()}}{ diff --git a/man/MAEFilterStates.Rd b/man/MAEFilterStates.Rd index 48809bc43..d2099093d 100644 --- a/man/MAEFilterStates.Rd +++ b/man/MAEFilterStates.Rd @@ -2,29 +2,11 @@ % Please edit documentation in R/FilterStates.R \name{MAEFilterStates} \alias{MAEFilterStates} -\title{Specialization of \code{FilterStates} for \code{MultiAssayExperiment}.} +\title{MAEFilterStates} \description{ Specialization of \code{FilterStates} for \code{MultiAssayExperiment}. - -Specialization of \code{FilterStates} for \code{MultiAssayExperiment}. -} -\examples{ - -## ------------------------------------------------ -## Method `MAEFilterStates$format` -## ------------------------------------------------ - - -Get function name - -Get function name used to create filter call. -For `MAEFilterStates` -`MultiAssayExperiment::subsetByColData` is used. } -\keyword{Initialize} -\keyword{`MAEFilterStates`} \keyword{internal} -\keyword{object} \section{Super class}{ \code{\link[teal.slice:FilterStates]{teal.slice::FilterStates}} -> \code{MAEFilterStates} } @@ -61,6 +43,9 @@ For `MAEFilterStates` \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-new}{}}} \subsection{Method \code{new()}}{ +Initializes \code{MAEFilterStates} object + +Initialize \code{MAEFilterStates} object \subsection{Usage}{ \if{html}{\out{
}}\preformatted{MAEFilterStates$new( input_dataname, @@ -112,24 +97,13 @@ Returns the formatted string representing this \code{MAEFilterStates} object. \subsection{Returns}{ \code{character(1)} the formatted string } -\subsection{Examples}{ -\if{html}{\out{
}} -\preformatted{ -Get function name - -Get function name used to create filter call. -For `MAEFilterStates` -`MultiAssayExperiment::subsetByColData` is used. -} -\if{html}{\out{
}} - -} - } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-get_fun}{}}} \subsection{Method \code{get_fun()}}{ +Returns function name used to create filter call. +For \code{MAEFilterStates} \code{MultiAssayExperiment::subsetByColData} is used. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{MAEFilterStates$get_fun()}\if{html}{\out{
}} } @@ -207,7 +181,7 @@ column in \code{colData(data)}.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-remove_filter_state}{}}} \subsection{Method \code{remove_filter_state()}}{ -Remove a variable from the \code{ReactiveQueue} and its corresponding UI element. +Removes a variable from the \code{ReactiveQueue} and its corresponding UI element. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{MAEFilterStates$remove_filter_state(element_id)}\if{html}{\out{
}} } diff --git a/man/MatrixFilterStates.Rd b/man/MatrixFilterStates.Rd index c90e11b61..4ce532e8a 100644 --- a/man/MatrixFilterStates.Rd +++ b/man/MatrixFilterStates.Rd @@ -2,24 +2,11 @@ % Please edit documentation in R/FilterStates.R \name{MatrixFilterStates} \alias{MatrixFilterStates} -\title{Specialization of \code{FilterStates} for a base matrix.} +\title{MatrixFilterStates} \description{ Specialization of \code{FilterStates} for a base matrix. - -Specialization of \code{FilterStates} for a base matrix. -} -\examples{ - -## ------------------------------------------------ -## Method `MatrixFilterStates$format` -## ------------------------------------------------ - - } -\keyword{Initialize} -\keyword{`MatrixFilterStates`} \keyword{internal} -\keyword{object} \section{Super class}{ \code{\link[teal.slice:FilterStates]{teal.slice::FilterStates}} -> \code{MatrixFilterStates} } @@ -56,6 +43,9 @@ Specialization of \code{FilterStates} for a base matrix. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-new}{}}} \subsection{Method \code{new()}}{ +Initialize \code{MatrixFilterStates} object + +Initialize \code{MatrixFilterStates} object \subsection{Usage}{ \if{html}{\out{
}}\preformatted{MatrixFilterStates$new(input_dataname, output_dataname, datalabel)}\if{html}{\out{
}} } @@ -95,14 +85,6 @@ Returns the formatted string representing this \code{MatrixFilterStates} object. \subsection{Returns}{ \code{character(1)} the formatted string } -\subsection{Examples}{ -\if{html}{\out{
}} -\preformatted{ -} -\if{html}{\out{
}} - -} - } \if{html}{\out{
}} \if{html}{\out{}} diff --git a/man/SEFilterStates.Rd b/man/SEFilterStates.Rd index 0e4078d6a..e616c2f49 100644 --- a/man/SEFilterStates.Rd +++ b/man/SEFilterStates.Rd @@ -2,24 +2,11 @@ % Please edit documentation in R/FilterStates.R \name{SEFilterStates} \alias{SEFilterStates} -\title{Specialization of \code{FilterStates} for \code{SummaryExperiment}.} +\title{SEFilterStates} \description{ Specialization of \code{FilterStates} for \code{SummaryExperiment}. - -Specialization of \code{FilterStates} for \code{SummaryExperiment}. -} -\examples{ - -## ------------------------------------------------ -## Method `SEFilterStates$format` -## ------------------------------------------------ - - } -\keyword{Initialize} -\keyword{`SEFilterStates`} \keyword{internal} -\keyword{object} \section{Super class}{ \code{\link[teal.slice:FilterStates]{teal.slice::FilterStates}} -> \code{SEFilterStates} } @@ -56,6 +43,9 @@ Specialization of \code{FilterStates} for \code{SummaryExperiment}. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-new}{}}} \subsection{Method \code{new()}}{ +Initialize \code{SEFilterStates} object + +Initialize \code{SEFilterStates} object \subsection{Usage}{ \if{html}{\out{
}}\preformatted{SEFilterStates$new(input_dataname, output_dataname, datalabel)}\if{html}{\out{
}} } @@ -95,14 +85,6 @@ Returns the formatted string representing this \code{MAEFilterStates} object. \subsection{Returns}{ \code{character(1)} the formatted string } -\subsection{Examples}{ -\if{html}{\out{
}} -\preformatted{ -} -\if{html}{\out{
}} - -} - } \if{html}{\out{
}} \if{html}{\out{}} diff --git a/tests/testthat/test-DFFilterStates.R b/tests/testthat/test-DFFilterStates.R index ea4e0e5b5..4c98cb8a1 100644 --- a/tests/testthat/test-DFFilterStates.R +++ b/tests/testthat/test-DFFilterStates.R @@ -255,3 +255,49 @@ testthat::test_that( testthat::expect_identical(dffs$ui_add_filter_state("id", data.frame(A = numeric(0))), div("no samples available")) } ) + +# Format +testthat::test_that("$format() is a method of DFFilterStates", { + testthat::expect_error(DFFilterStates$new( + input_dataname = "test", + output_dataname = "test", + datalabel = character(0), + varlabels = "test", + keys = "test" + )$format(), NA) +}) + +testthat::test_that("$format() asserts the indent argument is a number", { + testthat::expect_error( + DFFilterStates$new( + input_dataname = "test", + output_dataname = "test", + datalabel = character(0), + varlabels = "test", + keys = "test" + )$format(indent = "wrong type"), + regexp = "Assertion on 'indent' failed: Must be of type 'number'" + ) +}) + +testthat::test_that("$format() concatenates its FilterState elements using \\n without additional indent", { + dffs <- DFFilterStates$new( + input_dataname = "iris", + output_dataname = "iris_filtered", + datalabel = character(0), + varlabels = character(0), + keys = character(0) + ) + fs <- list( + Sepal.Length = list(selected = c(5.1, 6.4), keep_na = TRUE, keep_inf = TRUE), + Species = list(selected = c("setosa", "versicolor"), keep_na = FALSE) + ) + dffs$set_filter_state(state = fs, data = iris) + + sepal_filter <- dffs$queue_get(1L)[[1]] + species_filter <- dffs$queue_get(1L)[[2]] + shiny::isolate(testthat::expect_equal( + dffs$format(), + paste(sepal_filter$format(indent = 0), species_filter$format(indent = 0), sep = "\n") + )) +}) diff --git a/tests/testthat/test-DateFilterState.R b/tests/testthat/test-DateFilterState.R index 3a36b5735..33dad5208 100644 --- a/tests/testthat/test-DateFilterState.R +++ b/tests/testthat/test-DateFilterState.R @@ -199,3 +199,50 @@ testthat::test_that( ) } ) + +# Format +testthat::test_that("$format() is a FilterStates's method that accepts indent", { + test_date <- as.Date("13/07/2013", format = "%d/%m/%y") + filter_state <- DateFilterState$new(test_date, varname = "test_date") + testthat::expect_error(shiny::isolate(filter_state$format(indent = 0)), regexp = NA) +}) + +testthat::test_that("$format() asserts that indent is numeric", { + test_date <- as.Date("13/07/2013", format = "%d/%m/%y") + filter_state <- DateFilterState$new(test_date, varname = "test_date") + testthat::expect_error( + filter_state$format(indent = "wrong type"), + regexp = "Assertion on 'indent' failed: Must be of type 'number'" + ) +}) + +testthat::test_that("$format() returns a string representation the FilterState object", { + test_date <- as.Date("13/07/2013", format = "%d/%m/%y") + filter_state <- DateFilterState$new(test_date, varname = "test") + filter_state$set_state(list(selected = c(test_date, test_date))) + testthat::expect_equal( + shiny::isolate(filter_state$format(indent = 0)), + paste( + "Filtering on: test", + " Selected range: 2020-07-13 - 2020-07-13", + " Include missing values: FALSE", + sep = "\n" + ) + ) +}) + +testthat::test_that("$format() prepends spaces to every line of the returned string", { + test_date <- as.Date("13/07/2013", format = "%d/%m/%y") + filter_state <- DateFilterState$new(test_date, varname = "test") + filter_state$set_state(list(selected = c(test_date, test_date))) + for (i in 1:3) { + whitespace_indent <- paste0(rep(" ", i), collapse = "") + testthat::expect_equal( + shiny::isolate(filter_state$format(indent = !!(i))), + sprintf( + "%sFiltering on: test\n%1$s Selected range: 2020-07-13 - 2020-07-13\n%1$s Include missing values: FALSE", + format("", width = i) + ) + ) + } +}) diff --git a/tests/testthat/test-DatetimeFilterState.R b/tests/testthat/test-DatetimeFilterState.R index a5d1f690b..8e5091ccb 100644 --- a/tests/testthat/test-DatetimeFilterState.R +++ b/tests/testthat/test-DatetimeFilterState.R @@ -211,3 +211,55 @@ testthat::test_that( ) } ) + +# Format +testthat::test_that("$format() is a FilterStates's method that accepts indent", { + object <- as.POSIXct(8, origin = "1900/01/01") + filter_state <- DatetimeFilterState$new(object, varname = "test") + testthat::expect_error(shiny::isolate(filter_state$format(indent = 0)), regexp = NA) +}) + +testthat::test_that("$format() asserts that indent is numeric", { + object <- as.POSIXct(8, origin = "1900/01/01") + filter_state <- DatetimeFilterState$new(object, varname = "test") + testthat::expect_error( + filter_state$format(indent = "wrong type"), + regexp = "Assertion on 'indent' failed: Must be of type 'number'" + ) +}) + +testthat::test_that("$format() returns a string representation the FilterState object", { + object <- as.POSIXct(8, origin = "1900/01/01") + filter_state <- DatetimeFilterState$new(object, varname = "test") + filter_state$set_state(list(selected = c(object, object))) + testthat::expect_equal( + shiny::isolate(filter_state$format(indent = 0)), + paste( + "Filtering on: test", + " Selected range: 1900-01-01 01:24:08 - 1900-01-01 01:24:08", + " Include missing values: FALSE", + sep = "\n" + ) + ) +}) + +testthat::test_that("$format() prepends spaces to every line of the returned string", { + object <- as.POSIXct(8, origin = "1900/01/01") + filter_state <- DatetimeFilterState$new(object, varname = "test") + filter_state$set_state(list(selected = c(object, object))) + for (i in 1:3) { + whitespace_indent <- paste0(rep(" ", i), collapse = "") + testthat::expect_equal( + shiny::isolate(filter_state$format(indent = !!(i))), + sprintf( + paste( + "%sFiltering on: test", + "%1$s Selected range: 1900-01-01 01:24:08 - 1900-01-01 01:24:08", + "%1$s Include missing values: FALSE", + sep = "\n" + ), + format("", width = i) + ) + ) + } +}) diff --git a/tests/testthat/test-FilterState.R b/tests/testthat/test-FilterState.R index 95c52275c..958e3da8e 100644 --- a/tests/testthat/test-FilterState.R +++ b/tests/testthat/test-FilterState.R @@ -201,55 +201,41 @@ testthat::test_that( ) # Format -testthat::test_that("$format is a FilterStates's method that accepts indent", { +testthat::test_that("$format() is a FilterStates's method that accepts indent", { testthat::expect_error(shiny::isolate(FilterState$new(c(7), varname = "test")$format(indent = 0)), regexp = NA) }) -testthat::test_that("$format asserts that indent is numeric", { +testthat::test_that("$format() asserts that indent is numeric", { testthat::expect_error( FilterState$new(c(7), varname = "test")$format(indent = "wrong type"), regexp = "Assertion on 'indent' failed: Must be of type 'number'" ) }) -testthat::test_that("$format returns a string representation the FilterState object", { +testthat::test_that("$format() returns a string representation the FilterState object", { filter_state <- FilterState$new(c(7), varname = "test") filter_state$set_state(list(selected = c(7, 7))) testthat::expect_equal( shiny::isolate(filter_state$format(indent = 0)), - paste0(c( + paste( "Filtering on: test", - " Selected: 7.000 7.000"), - collapse = "\n" + " Selected values: 7.000 7.000", + " Include missing values: FALSE", + sep = "\n" ) ) }) -testthat::test_that("$format appends NULL when there is no selection", { - filter_state <- FilterState$new(c(7), varname = "test") - testthat::expect_equal( - shiny::isolate(filter_state$format(indent = 0)), - paste0(c( - "Filtering on: test", - " Selected: NULL" - ), - collapse = "\n" - ) - ) -}) - -testthat::test_that("$format prepends spaces to every line of the returned string", { +testthat::test_that("$format() prepends spaces to every line of the returned string", { filter_state <- FilterState$new(c(7), varname = "test") filter_state$set_state(list(selected = c(7, 7))) - for(i in 1:3) { + for (i in 1:3) { whitespace_indent <- paste0(rep(" ", i), collapse = "") testthat::expect_equal( shiny::isolate(filter_state$format(indent = !!(i))), - paste0(c( - paste0(whitespace_indent, "Filtering on: test"), - paste0(whitespace_indent, " Selected: 7.000 7.000") - ), - collapse = "\n" + sprintf( + "%sFiltering on: test\n%1$s Selected values: 7.000 7.000\n%1$s Include missing values: FALSE", + format("", width = i) ) ) } diff --git a/tests/testthat/test-FilteredDataset.R b/tests/testthat/test-FilteredDataset.R index 6a456a87a..f5374ee26 100644 --- a/tests/testthat/test-FilteredDataset.R +++ b/tests/testthat/test-FilteredDataset.R @@ -140,3 +140,19 @@ testthat::test_that("get_metadata returns the metadata of the data passed to the ) testthat::expect_null(filtered_dataset$get_metadata()) }) + +# Format +testthat::test_that("$get_formatted_filter_state returns a string representation of filters", { + dataset <- DefaultFilteredDataset$new(teal.data::dataset("iris", iris)) + fs <- list( + Sepal.Length = list(selected = c(5.1, 6.4), keep_na = TRUE, keep_inf = TRUE), + Species = list(selected = c("setosa", "versicolor"), keep_na = FALSE) + ) + dataset$set_filter_state(state = fs) + states <- dataset$get_filter_states()[[1]] + + testthat::expect_equal( + shiny::isolate(dataset$get_formatted_filter_state()), + paste("Filters for dataset: iris", shiny::isolate(states$format(indent = 2)), sep = "\n") + ) +}) diff --git a/tests/testthat/test-MAEFilterStates.R b/tests/testthat/test-MAEFilterStates.R index d4452acc5..64b81a5e2 100644 --- a/tests/testthat/test-MAEFilterStates.R +++ b/tests/testthat/test-MAEFilterStates.R @@ -283,3 +283,58 @@ testthat::test_that( ) } ) + +# Format +testthat::test_that("$format() is a method of DFFilterStates", { + testthat::expect_error(MAEFilterStates$new( + input_dataname = "iris", + output_dataname = "iris_filtered", + datalabel = character(0), + varlabels = character(0), + keys = character(0) + )$format(), NA) +}) + +testthat::test_that("$format() asserts the indent argument is a number", { + testthat::expect_error( + MAEFilterStates$new( + input_dataname = "iris", + output_dataname = "iris_filtered", + datalabel = character(0), + varlabels = character(0), + keys = character(0) + )$format(indent = "wrong type"), + regexp = "Assertion on 'indent' failed: Must be of type 'number'" + ) +}) + +testthat::test_that("$format() concatenates its FilterState elements using \\n and indents the FilterState objects", { + utils::data(miniACC, package = "MultiAssayExperiment") + maefs <- MAEFilterStates$new( + input_dataname = "test", + output_dataname = "test_filtered", + datalabel = character(0), + varlabels = character(0), + keys = character(0) + ) + + maefs$set_filter_state( + state = list( + years_to_birth = c(30, 50), + vital_status = 1 + ), + data = miniACC + ) + + years_to_birth_filter <- maefs$queue_get(1L)[[1]] + vital_status_filter <- maefs$queue_get(1L)[[2]] + shiny::isolate(testthat::expect_equal( + maefs$format(), + paste( + "Subject filters:", + years_to_birth_filter$format(indent = 2), + vital_status_filter$format(indent = 2), + sep = "\n" + ) + )) +}) diff --git a/tests/testthat/test-RangeFilterState.R b/tests/testthat/test-RangeFilterState.R index 31698354a..3d748a394 100644 --- a/tests/testthat/test-RangeFilterState.R +++ b/tests/testthat/test-RangeFilterState.R @@ -258,55 +258,41 @@ testthat::test_that( # Format -testthat::test_that("$format is a FilterStates's method that accepts indent", { - testthat::expect_error(shiny::isolate(RangeFilterState$new(c(7), varname = "test")$format(indent = 0)), regexp = NA) +testthat::test_that("$format() is a FilterStates's method that accepts indent", { + filter_state <- RangeFilterState$new(7, varname = "test") + testthat::expect_error(shiny::isolate(filter_state$format(indent = 0)), regexp = NA) }) -testthat::test_that("$format asserts that indent is numeric", { +testthat::test_that("$format() asserts that indent is numeric", { testthat::expect_error( RangeFilterState$new(c(7), varname = "test")$format(indent = "wrong type"), regexp = "Assertion on 'indent' failed: Must be of type 'number'" ) }) -testthat::test_that("$format returns a string representation the FilterState object", { +testthat::test_that("$format() returns a string representation the FilterState object", { filter_state <- RangeFilterState$new(c(7), varname = "test") filter_state$set_state(list(selected = c(7, 7))) testthat::expect_equal( shiny::isolate(filter_state$format(indent = 0)), - paste0(c( - "Filtering on: test", - " Range: 7.000 - 7.000"), - collapse = "\n" - ) - ) -}) - -testthat::test_that("$format appends a default value from a range when there is no default selection", { - filter_state <- RangeFilterState$new(c(7), varname = "test") - testthat::expect_equal( - shiny::isolate(filter_state$format(indent = 0)), - paste0(c( + paste( "Filtering on: test", - " Range: 7.000 - 7.000" - ), - collapse = "\n" + " Selected range: 7.000 - 7.000", + " Include missing values: FALSE", + sep = "\n" ) ) }) -testthat::test_that("$format prepends spaces to every line of the returned string", { +testthat::test_that("$format() prepends spaces to every line of the returned string", { filter_state <- RangeFilterState$new(c(7), varname = "test") filter_state$set_state(list(selected = c(7, 7))) - for(i in 1:3) { - whitespace_indent <- paste0(rep(" ", i), collapse = "") + for (i in 1:3) { testthat::expect_equal( shiny::isolate(filter_state$format(indent = !!(i))), - paste0(c( - paste0(whitespace_indent, "Filtering on: test"), - paste0(whitespace_indent, " Range: 7.000 - 7.000") - ), - collapse = "\n" + sprintf( + "%sFiltering on: test\n%1$s Selected range: 7.000 - 7.000\n%1$s Include missing values: FALSE", + format("", width = i) ) ) } diff --git a/tests/testthat/test-SEFilterStates.R b/tests/testthat/test-SEFilterStates.R index c79352a6d..b1fce8bc6 100644 --- a/tests/testthat/test-SEFilterStates.R +++ b/tests/testthat/test-SEFilterStates.R @@ -412,3 +412,55 @@ testthat::test_that( ) } ) + +# Format +testthat::test_that("$format() is a method of SEFilterStates", { + testthat::expect_error( + SEFilterStates$new( + input_dataname = "test", + output_dataname = "test_filtered", + datalabel = character(0) + )$format(), + NA + ) +}) + +testthat::test_that("$format() asserts the indent argument is a number", { + testthat::expect_error( + SEFilterStates$new( + input_dataname = "test", + output_dataname = "test_filtered", + datalabel = character(0) + )$format(indent = "wrong type"), + regexp = "Assertion on 'indent' failed: Must be of type 'number'" + ) +}) + +testthat::test_that("$format() concatenates its FilterState elements using \\n and indents the FilterState strings", { + test <- get_test_data() + sefs <- SEFilterStates$new( + input_dataname = "test", + output_dataname = "test_filtered", + datalabel = "Label" + ) + + fs <- list( + select = list(Treatment = "ChIP"), + subset = list(feature_id = c("ID001", "ID002")) + ) + sefs$set_filter_state(state = fs, data = test) + + treatment_filter <- sefs$queue_get("select")[[1]] + feature_filter <- sefs$queue_get("subset")[[1]] + shiny::isolate(testthat::expect_equal( + sefs$format(), + paste( + "Assay Label filters:", + " Subsetting:", + feature_filter$format(indent = 4), + " Selecting:", + treatment_filter$format(indent = 4), + sep = "\n" + ) + )) +}) diff --git a/tests/testthat/test-init_filter_state.R b/tests/testthat/test-init_filter_state.R index 8fd907fbc..253f94e0c 100644 --- a/tests/testthat/test-init_filter_state.R +++ b/tests/testthat/test-init_filter_state.R @@ -19,8 +19,6 @@ test_that("'extract_type' must be specified with 'input_dataname'", { ) }) - - testthat::test_that("init_filter_state accepts, name or call as input_dataname", { testthat::expect_error( init_filter_state(7, varname = "test", input_dataname = NULL), @@ -98,3 +96,8 @@ testthat::test_that("init_filter_state return a LogicalFilterState, if passed a testthat::expect_error(fs <- init_filter_state(c(TRUE), varname = "test"), NA) testthat::expect_true(is(fs, "LogicalFilterState")) }) + +testthat::test_that("init_filter_state default accepts a list", { + fs <- init_filter_state(list(1, 2, 3), varname = "test") + testthat::expect_true(inherits(fs, "FilterState")) +})