From 64710c5ad031aa495812a6a9dd9cc9b28114ec95 Mon Sep 17 00:00:00 2001 From: Davide Garolini Date: Wed, 17 May 2023 22:06:40 +0200 Subject: [PATCH] `export_as_txt` refactoring (#124) paginate_listing hooked up to formatters machinery. pag_listing_indices defunct. Closes #96 --------- Co-authored-by: shajoezhu Co-authored-by: Gabriel Becker --- DESCRIPTION | 2 +- NAMESPACE | 1 + R/listing_export.R | 148 +--------------------- R/paginate_listing.R | 165 +++++++------------------ R/rlistings.R | 2 +- man/defunct.Rd | 38 ++++++ man/export_as_txt.Rd | 108 ---------------- man/paginate.Rd | 21 +--- man/reexports.Rd | 28 +++++ tests/testthat/test-paginate_listing.R | 23 ++-- 10 files changed, 137 insertions(+), 399 deletions(-) create mode 100644 man/defunct.Rd delete mode 100644 man/export_as_txt.Rd create mode 100644 man/reexports.Rd diff --git a/DESCRIPTION b/DESCRIPTION index d7586cdc..aff6f2fa 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -19,7 +19,7 @@ License: Apache License 2.0 URL: https://github.com/insightsengineering/rlistings BugReports: https://github.com/insightsengineering/rlistings/issues Depends: - formatters (>= 0.4.0), + formatters (>= 0.4.1.9003), methods, tibble Imports: diff --git a/NAMESPACE b/NAMESPACE index d3fd09ee..42d9c02d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -27,6 +27,7 @@ exportMethods(toString) import(formatters) import(methods) import(tibble) +importFrom(formatters,export_as_txt) importFrom(grDevices,dev.off) importFrom(grDevices,pdf) importFrom(grid,convertHeight) diff --git a/R/listing_export.R b/R/listing_export.R index 1d4ac30a..7b41bcbb 100644 --- a/R/listing_export.R +++ b/R/listing_export.R @@ -1,46 +1,6 @@ -#' Export as plain text with page break symbol -#' -#' @inheritParams paginate_listing -#' @param lst Listing object -#' @param file character(1). File to write. -#' @param page_type character(1). Name of a page type. See -#' `page_types`. Ignored when `pg_width` and `pg_height` -#' are set directly. -#' @param landscape logical(1). Should the dimensions of `page_type` -#' be inverted for landscape? Defaults to `FALSE`, ignored when -#' `pg_width` and `pg_height` are set directly. -#' @param font_family character(1). Name of a font family. An error -#' will be thrown if the family named is not monospaced. Defaults -#' to Courier. -#' @param font_size numeric(1). Font size, defaults to 8. -#' @param pg_width numeric(1). Page width in inches. -#' @param pg_height numeric(1). Page height in inches. -#' @param hsep character(1). Characters to repeat to create -#' header/body separator line. -#' @param indent_size numeric(1). Indent size in characters. Ignored -#' when `x` is already a MatrixPrintForm object in favor of information -#' there. -#' @param max_width integer(1), character(1) or NULL. Width that title -#' and footer (including footnotes) materials should be -#' word-wrapped to. If NULL, it is set to the current print width -#' of the session (`getOption("width")`). If set to `"auto"`, -#' the width of the table (plus any table inset) is used. Ignored -#' completely if `tf_wrap` is `FALSE`. -#' @param tf_wrap logical(1). Should the texts for title, subtitle, -#' and footnotes be wrapped? -#' @param paginate logical(1). Should \code{lst} be paginated before writing the file. -#' Defaults to `TRUE` if any sort of page dimension is specified. -#' @param \dots Passed directly to \code{\link{paginate_listing}} -#' @param page_break character(1). Page break symbol (defaults to outputting \code{"\\s"}). -#' @return \code{file} (this function is called for the side effect of writing the file. -#' -#' @note When specified, `font_size` is used *only* to determine pagination based -#' on page dimensions. The written file is populated in raw ASCII text, which -#' does not have the concept of font size. +#' @importFrom formatters export_as_txt #' #' @export -#' -#' #' @examples #' #' dat <- ex_adae @@ -52,108 +12,4 @@ #' main_footer(lsting) <- "this is some footer" #' cat(export_as_txt(lsting, file = NULL, paginate = TRUE)) #' -export_as_txt <- function(lst, file = NULL, - page_type = NULL, - landscape = FALSE, - pg_width = page_dim(page_type)[if (landscape) 2 else 1], - pg_height = page_dim(page_type)[if (landscape) 1 else 2], - font_family = "Courier", - font_size = 8, # grid parameters - paginate = .need_pag(page_type, pg_width, pg_height, lpp, cpp), - cpp = NULL, - lpp = NULL, - ..., page_break = "\\s\\n", - hsep = default_hsep(), - indent_size = 2, - tf_wrap = paginate, - max_width = cpp, - colwidths = propose_column_widths(matrix_form(lst, TRUE))) { - - if (paginate) { - gp_plot <- gpar(fontsize = font_size, fontfamily = font_family) - - pdf(file = tempfile(), width = pg_width, height = pg_height) - on.exit(dev.off()) - grid.newpage() - pushViewport(plotViewport(margins = c(0, 0, 0, 0), gp = gp_plot)) - - cur_gpar <- get.gpar() - if (is.null(page_type) && is.null(pg_width) && is.null(pg_height) && - (is.null(cpp) || is.null(lpp))) { - page_type <- "letter" - pg_width <- page_dim(page_type)[if (landscape) 2 else 1] - pg_height <- page_dim(page_type)[if (landscape) 1 else 2] - } - - if (is.null(lpp)) { - lpp <- floor(convertHeight(unit(1, "npc"), "lines", valueOnly = TRUE) / - (cur_gpar$cex * cur_gpar$lineheight)) - } - if (is.null(cpp)) { - cpp <- floor(convertWidth(unit(1, "npc"), "inches", valueOnly = TRUE) * - font_lcpi(font_family, font_size, cur_gpar$lineheight)$cpi) - } - if (tf_wrap && is.null(max_width)) { - max_width <- cpp - } - - listings <- paginate_listing(lst, - page_type = page_type, - font_family = font_family, - font_size = font_size, - lineheight = cur_gpar$lineheight, - landscape = landscape, - pg_width = pg_width, - pg_height = pg_height, - lpp = lpp, - cpp = cpp, - colwidths = propose_column_widths(lst), - tf_wrap = tf_wrap, - max_width = max_width) - } else { - listings <- list(lst) - } - - res <- paste( - mapply( - function(tb, ...) { - ## 1 and +1 are because cwidths includes rowlabel 'column' - # cinds <- c(1, .figure_out_colinds(tb, lst) + 1L) - toString(tb, ...) - }, - MoreArgs = list(hsep = hsep), - SIMPLIFY = FALSE, - tb = listings - ), - collapse = page_break - ) - - if (!is.null(file)) { - cat(res, file = file) - } else { - res - } -} - - -.do_inset <- function(x, inset) { - if (inset == 0 || !any(nzchar(x))) { - return(x) - } - padding <- strrep(" ", inset) - if (is.character(x)) { - x <- paste0(padding, x) - } else if (is(x, "matrix")) { - x[, 1] <- .do_inset(x[, 1, drop = TRUE], inset) - } - x -} - - -.paste_no_na <- function(x, ...) { - paste(na.omit(x), ...) -} - -.need_pag <- function(page_type, pg_width, pg_height, cpp, lpp) { - !(is.null(page_type) && is.null(pg_width) && is.null(pg_height) && is.null(cpp) && is.null(lpp)) -} +formatters::export_as_txt diff --git a/R/paginate_listing.R b/R/paginate_listing.R index ce8d1668..44862a19 100644 --- a/R/paginate_listing.R +++ b/R/paginate_listing.R @@ -44,16 +44,16 @@ paginate_listing <- function(lsting, page_type = "letter", font_family = "Courier", - font_size = 12, + font_size = 8, lineheight = 1, landscape = FALSE, pg_width = NULL, pg_height = NULL, margins = c(top = .5, bottom = .5, left = .75, right = .75), - lpp, - cpp, + lpp = NA_integer_, + cpp = NA_integer_, colwidths = propose_column_widths(lsting), - tf_wrap = FALSE, + tf_wrap = !is.null(max_width), max_width = NULL, verbose = FALSE) { checkmate::assert_class(lsting, "listing_df") @@ -62,133 +62,60 @@ paginate_listing <- function(lsting, checkmate::assert_count(max_width, null.ok = TRUE) checkmate::assert_flag(verbose) - if (missing(lpp) && missing(cpp) && !is.null(page_type) || - (!is.null(pg_width) && !is.null(pg_height))) { - pg_lcpp <- page_lcpp( - page_type = page_type, - landscape = landscape, - font_family = font_family, - font_size = font_size, - lineheight = lineheight, - margins = margins, - pg_width = pg_width, - pg_height = pg_height - ) - if (missing(lpp)) { - lpp <- pg_lcpp$lpp - } - if (missing(cpp)) { - cpp <- pg_lcpp$cpp - } - } else { - if (missing(cpp)) { - cpp <- NULL - } - if (missing(lpp)) { - lpp <- 70 - } - } - if (is.null(colwidths)) { - colwidths <- propose_column_widths(matrix_form(lsting, indent_rownames = TRUE)) - } - if (!tf_wrap) { - if (!is.null(max_width)) { - warning("tf_wrap is FALSE - ignoring non-null max_width value.") - } - max_width <- NULL - } else if (is.null(max_width)) { - max_width <- cpp - } else if (identical(max_width, "auto")) { - # this 3 is column separator width. - max_width <- sum(colwidths) + 3 * (length(colwidths) - 1) - } - if (!is.null(cpp) && !is.null(max_width) && max_width > cpp) { - warning("max_width specified is wider than characters per page width (cpp).") - } - # row-space pagination. - ret <- if (!is.null(lpp)) { - inds <- pag_listing_indices( - lsting = lsting, - lpp = lpp, - colwidths = colwidths, - verbose = verbose, - max_width = max_width - ) - lapply(inds, function(i) lsting[i, ]) - } else { - list(lsting) - } + indx <- paginate_indices(lsting, + page_type = page_type, + font_family = font_family, + font_size = font_size, + lineheight = lineheight, + landscape = landscape, + pg_width = pg_width, + pg_height = pg_height, + margins = margins, + lpp = lpp, + cpp = cpp, + colwidths = colwidths, + tf_wrap = tf_wrap, + max_width = max_width, + rep_cols = length(get_keycols(lsting)), + verbose = verbose) - # column-space pagination. - if (!is.null(cpp)) { - inds <- vert_pag_indices( - lsting, - cpp = cpp, - colwidths = colwidths, - verbose = verbose, - rep_cols = length(get_keycols(lsting)) - ) - dispcols <- listing_dispcols(lsting) - pag_cols <- lapply(inds, function(i) dispcols[i]) - ret <- lapply( - ret, - function(oneres) { - lapply( - pag_cols, - function(cnames) { - ret <- oneres[, cnames, drop = FALSE] - listing_dispcols(ret) <- cnames - ret - } - ) + + vert_pags <- lapply(indx$pag_row_indices, + function(ii) lsting[ii, ]) + dispnames <- listing_dispcols(lsting) + full_pag <- lapply(vert_pags, + function(onepag) { + if (!is.null(indx$pag_col_indices)) { + lapply(indx$pag_col_indices, + function(jj) { + res <- onepag[, dispnames[jj], drop = FALSE] + listing_dispcols(res) <- intersect(dispnames, names(res)) + res + }) + } else { + list(onepag) } - ) - ret <- unlist(ret, recursive = FALSE) - } + }) + + ret <- unlist(full_pag, recursive = FALSE) ret } -#' @rdname paginate +#' @title Defunct functions +#' +#' @description +#' These functions are defunct and their symbols will be removed entirely +#' in a future release. +#' @rdname defunct +#' @inheritParams paginate_listing #' @export pag_listing_indices <- function(lsting, lpp = 15, colwidths = NULL, max_width = NULL, verbose = FALSE) { - checkmate::assert_class(lsting, "listing_df") - checkmate::assert_numeric(colwidths, lower = 0, len = length(listing_dispcols(lsting)), null.ok = TRUE) - checkmate::assert_count(max_width, null.ok = TRUE) - checkmate::assert_flag(verbose) - - dheight <- divider_height(lsting) - dcols <- listing_dispcols(lsting) - cinfo_lines <- max( - mapply(nlines, x = var_labels(lsting)[dcols], max_width = colwidths) - ) + dheight - tlines <- if (any(nzchar(all_titles(lsting)))) { - length(all_titles(lsting)) + dheight + 1L - } else { - 0 - } - flines <- length(all_footers(lsting)) - if (flines > 0) { - flines <- flines + dheight + 1L - } - rlpp <- lpp - cinfo_lines - tlines - flines - if (verbose) { - message("Adjusted Lines Per Page: ", rlpp, " (original lpp: ", lpp, ")") - } - - pagdf <- make_row_df(lsting, colwidths) - pag_indices_inner( - pagdf = pagdf, - rlpp = rlpp, - min_siblings = 0, - verbose = verbose, - have_col_fnotes = FALSE, - div_height = dheight - ) + .Defunct("paginate_indices", package = "formatters") } diff --git a/R/rlistings.R b/R/rlistings.R index 68c8f3d4..81af7cce 100644 --- a/R/rlistings.R +++ b/R/rlistings.R @@ -176,7 +176,7 @@ get_keycols <- function(df) { #' @export #' @inherit formatters::matrix_form -#' @seealso [formatters::matrix_form()] +#' @seealso [formatters::matrix_form()] #' @param indent_rownames logical(1). Silently ignored, as listings do not have row names #' nor indenting structure. #' diff --git a/man/defunct.Rd b/man/defunct.Rd new file mode 100644 index 00000000..ef89f3f5 --- /dev/null +++ b/man/defunct.Rd @@ -0,0 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/paginate_listing.R +\name{pag_listing_indices} +\alias{pag_listing_indices} +\title{Defunct functions} +\usage{ +pag_listing_indices( + lsting, + lpp = 15, + colwidths = NULL, + max_width = NULL, + verbose = FALSE +) +} +\arguments{ +\item{lsting}{listing_df. The listing to paginate.} + +\item{lpp}{numeric(1) or NULL. Number of row lines (not counting titles and +footers) to have per page. Standard is \code{70} while \code{NULL} disables vertical +pagination.} + +\item{colwidths}{numeric vector. Column widths (in characters) for +use with vertical pagination.} + +\item{max_width}{integer(1), character(1) or NULL. Width that title +and footer (including footnotes) materials should be +word-wrapped to. If NULL, it is set to the current print width +of the session (\code{getOption("width")}). If set to \code{"auto"}, +the width of the table (plus any table inset) is used. Ignored +completely if \code{tf_wrap} is \code{FALSE}.} + +\item{verbose}{logical(1). Should additional informative messages about the search for +pagination breaks be shown. Defaults to \code{FALSE}.} +} +\description{ +These functions are defunct and their symbols will be removed entirely +in a future release. +} diff --git a/man/export_as_txt.Rd b/man/export_as_txt.Rd deleted file mode 100644 index b19683d9..00000000 --- a/man/export_as_txt.Rd +++ /dev/null @@ -1,108 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/listing_export.R -\name{export_as_txt} -\alias{export_as_txt} -\title{Export as plain text with page break symbol} -\usage{ -export_as_txt( - lst, - file = NULL, - page_type = NULL, - landscape = FALSE, - pg_width = page_dim(page_type)[if (landscape) 2 else 1], - pg_height = page_dim(page_type)[if (landscape) 1 else 2], - font_family = "Courier", - font_size = 8, - paginate = .need_pag(page_type, pg_width, pg_height, lpp, cpp), - cpp = NULL, - lpp = NULL, - ..., - page_break = "\\\\s\\\\n", - hsep = default_hsep(), - indent_size = 2, - tf_wrap = paginate, - max_width = cpp, - colwidths = propose_column_widths(matrix_form(lst, TRUE)) -) -} -\arguments{ -\item{lst}{Listing object} - -\item{file}{character(1). File to write.} - -\item{page_type}{character(1). Name of a page type. See -\code{page_types}. Ignored when \code{pg_width} and \code{pg_height} -are set directly.} - -\item{landscape}{logical(1). Should the dimensions of \code{page_type} -be inverted for landscape? Defaults to \code{FALSE}, ignored when -\code{pg_width} and \code{pg_height} are set directly.} - -\item{pg_width}{numeric(1). Page width in inches.} - -\item{pg_height}{numeric(1). Page height in inches.} - -\item{font_family}{character(1). Name of a font family. An error -will be thrown if the family named is not monospaced. Defaults -to Courier.} - -\item{font_size}{numeric(1). Font size, defaults to 8.} - -\item{paginate}{logical(1). Should \code{lst} be paginated before writing the file. -Defaults to \code{TRUE} if any sort of page dimension is specified.} - -\item{cpp}{numeric(1) or NULL. Width (in characters) of the pages for -horizontal pagination. \code{NULL} (the default) indicates no horizontal -pagination should be done.} - -\item{lpp}{numeric(1) or NULL. Number of row lines (not counting titles and -footers) to have per page. Standard is \code{70} while \code{NULL} disables vertical -pagination.} - -\item{\dots}{Passed directly to \code{\link{paginate_listing}}} - -\item{page_break}{character(1). Page break symbol (defaults to outputting \code{"\\s"}).} - -\item{hsep}{character(1). Characters to repeat to create -header/body separator line.} - -\item{indent_size}{numeric(1). Indent size in characters. Ignored -when \code{x} is already a MatrixPrintForm object in favor of information -there.} - -\item{tf_wrap}{logical(1). Should the texts for title, subtitle, -and footnotes be wrapped?} - -\item{max_width}{integer(1), character(1) or NULL. Width that title -and footer (including footnotes) materials should be -word-wrapped to. If NULL, it is set to the current print width -of the session (\code{getOption("width")}). If set to \code{"auto"}, -the width of the table (plus any table inset) is used. Ignored -completely if \code{tf_wrap} is \code{FALSE}.} - -\item{colwidths}{numeric vector. Column widths (in characters) for -use with vertical pagination.} -} -\value{ -\code{file} (this function is called for the side effect of writing the file. -} -\description{ -Export as plain text with page break symbol -} -\note{ -When specified, \code{font_size} is used \emph{only} to determine pagination based -on page dimensions. The written file is populated in raw ASCII text, which -does not have the concept of font size. -} -\examples{ - -dat <- ex_adae -lsting <- as_listing(dat[1:25, ], key_cols = c("USUBJID", "AESOC")) \%>\% - add_listing_col("AETOXGR") \%>\% - add_listing_col("BMRKR1", format = "xx.x") \%>\% - add_listing_col("AESER / AREL", fun = function(df) paste(df$AESER, df$AREL, sep = " / ")) -main_title(lsting) <- "this is some title" -main_footer(lsting) <- "this is some footer" -cat(export_as_txt(lsting, file = NULL, paginate = TRUE)) - -} diff --git a/man/paginate.Rd b/man/paginate.Rd index 545a6eb9..e81e0b0d 100644 --- a/man/paginate.Rd +++ b/man/paginate.Rd @@ -2,31 +2,22 @@ % Please edit documentation in R/paginate_listing.R \name{paginate_listing} \alias{paginate_listing} -\alias{pag_listing_indices} \title{Paginate listings} \usage{ paginate_listing( lsting, page_type = "letter", font_family = "Courier", - font_size = 12, + font_size = 8, lineheight = 1, landscape = FALSE, pg_width = NULL, pg_height = NULL, margins = c(top = 0.5, bottom = 0.5, left = 0.75, right = 0.75), - lpp, - cpp, + lpp = NA_integer_, + cpp = NA_integer_, colwidths = propose_column_widths(lsting), - tf_wrap = FALSE, - max_width = NULL, - verbose = FALSE -) - -pag_listing_indices( - lsting, - lpp = 15, - colwidths = NULL, + tf_wrap = !is.null(max_width), max_width = NULL, verbose = FALSE ) @@ -54,8 +45,8 @@ be inverted for landscape? Defaults to \code{FALSE}, ignored when \item{pg_height}{numeric(1). Page height in inches.} -\item{margins}{numeric(4). Named numeric vector containing \code{'top'}, -\code{'bottom'}, \code{'left'}, and \code{'right'} margins in inches. Defaults +\item{margins}{numeric(4). Named numeric vector containing \code{'bottom'}, +\code{'left'}, \code{'top'}, and \code{'right'} margins in inches. Defaults to \code{.5} inches for both vertical margins and \code{.75} for both horizontal margins.} diff --git a/man/reexports.Rd b/man/reexports.Rd new file mode 100644 index 00000000..6975a288 --- /dev/null +++ b/man/reexports.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/listing_export.R +\docType{import} +\name{reexports} +\alias{reexports} +\alias{export_as_txt} +\title{Objects exported from other packages} +\examples{ + +dat <- ex_adae +lsting <- as_listing(dat[1:25, ], key_cols = c("USUBJID", "AESOC")) \%>\% + add_listing_col("AETOXGR") \%>\% + add_listing_col("BMRKR1", format = "xx.x") \%>\% + add_listing_col("AESER / AREL", fun = function(df) paste(df$AESER, df$AREL, sep = " / ")) +main_title(lsting) <- "this is some title" +main_footer(lsting) <- "this is some footer" +cat(export_as_txt(lsting, file = NULL, paginate = TRUE)) + +} +\keyword{internal} +\description{ +These objects are imported from other packages. Follow the links +below to see their documentation. + +\describe{ + \item{formatters}{\code{\link[formatters]{export_as_txt}}} +}} + diff --git a/tests/testthat/test-paginate_listing.R b/tests/testthat/test-paginate_listing.R index f7bc70df..5ad3e930 100644 --- a/tests/testthat/test-paginate_listing.R +++ b/tests/testthat/test-paginate_listing.R @@ -156,7 +156,7 @@ testthat::test_that("checking vertical pagination line calculation.", { testthat::test_that("pagination: lpp and cpp correctly computed for pg_width and pg_height", { lsting <- h_lsting_adae() pag <- paginate_listing(lsting, lpp = 24, cpp = 135) - res <- paginate_listing(lsting, pg_width = 15, pg_height = 5) + res <- paginate_listing(lsting, pg_width = 15, pg_height = 5, font_size = 12) # 12 no longer default!!! testthat::expect_identical(res, pag) }) @@ -173,22 +173,22 @@ testthat::test_that("pagination: lpp and cpp correctly computed for page_type an testthat::test_that("pagination: lpp and cpp correctly computed for lineheight", { lsting <- h_lsting_adae() - pag <- paginate_listing(lsting, lpp = 20, cpp = 70) - res <- paginate_listing(lsting, lineheight = 3) + pag <- paginate_listing(lsting, lpp = 20, cpp = 70, font_size = 12) + res <- paginate_listing(lsting, lineheight = 3, font_size = 12) testthat::expect_identical(res, pag) }) testthat::test_that("pagination: lpp and cpp correctly computed for landscape", { lsting <- h_lsting_adae() - pag <- paginate_listing(lsting, lpp = 45, cpp = 95) - res <- paginate_listing(lsting, landscape = TRUE) + pag <- paginate_listing(lsting, lpp = 45, cpp = 95, font_size = 12) + res <- paginate_listing(lsting, landscape = TRUE, font_size = 12) testthat::expect_identical(res, pag) }) testthat::test_that("pagination: lpp and cpp correctly computed for margins", { lsting <- h_lsting_adae() - pag <- paginate_listing(lsting, lpp = 42, cpp = 65) - res <- paginate_listing(lsting, margins = c(top = 2, bottom = 2, left = 1, right = 1)) + pag <- paginate_listing(lsting, lpp = 42, cpp = 65, font_size = 12) + res <- paginate_listing(lsting, margins = c(top = 2, bottom = 2, left = 1, right = 1), font_size = 12) testthat::expect_identical(res, pag) }) @@ -196,9 +196,14 @@ testthat::test_that("pagination: lpp and cpp correctly computed for margins", { testthat::test_that("pagination works with col wrapping", { lsting <- h_lsting_adae(disp_cols = c("USUBJID", "AESOC", "RACE")) - testthat::expect_silent(pag <- paginate_listing(lsting, colwidths = c(15, 15, 15, 15))) - pag_no_wrapping <- paginate_listing(lsting) + testthat::expect_silent(pag <- paginate_listing(lsting, colwidths = c(15, 15, 15, 15), font_size = 12)) + pag_no_wrapping <- paginate_listing(lsting, font_size = 12) testthat::expect_equal(length(pag), length(pag_no_wrapping) + 1) testthat::expect_error(paginate_listing(lsting, colwidths = c(12, 15))) }) + + +testthat::test_that("defunct is defunct", { + expect_error(pag_listing_indices(), "defunct") +})