# --- Test Setup Data --- test_data_rt <- data.frame( Group = factor(rep(c("A", "B"), each = 20)), Sub = factor(rep(c("X", "Y", "X", "Y"), each = 10)), Val = rnorm(40), stringsAsFactors = TRUE ) test_data_rl <- data.frame( ID = rep(1:5, each = 4), # Make it slightly longer Time = rep(1:4, times = 5), Result = sample(LETTERS, 20, replace = TRUE), Comment = paste("Comment", 1:20), stringsAsFactors = FALSE ) # Simple rtable layout lyt_rt <- basic_table(title = "RTables Test") %>% split_cols_by("Group") %>% analyze("Val", afun = function(x) list(mean = mean(x), n = length(x))) # Simple rlisting res_rl <- as_listing(test_data_rl, key_cols = "ID", disp_cols = c("Time", "Result", "Comment"), main_title = "RListing Test" ) # --- Tests --- test_that("export_as_docx handles list generated by tt_to_flextable(paginate=TRUE)", { # Setup: Create rtable with implicit pagination defined (e.g., via page_by) lyt_paged <- basic_table() %>% split_rows_by("Group", page_by = TRUE, page_prefix = "Group") %>% # Page per Group analyze("Val", afun = function(x) list(mean = mean(x), sd = sd(x))) # Build table - assume tbl is a single VTableTree object representing the full structure tbl <- build_table(lyt_paged, test_data_rt) expect_s4_class(tbl, "VTableTree") # Check assumption # Action 1: Generate list of flextables using tt_to_flextable pagination # Use a reasonable lpp value that forces pagination based on content/structure # (Exact value depends on table structure, title height etc.) result_pages <- NULL LPP_TEST_VALUE <- 15 # Adjust as needed based on expected table height per page expect_no_error( result_pages <- tt_to_flextable(tbl, paginate = TRUE, lpp = LPP_TEST_VALUE) ) # Verification 1: Check output of tt_to_flextable pagination expect_true( is.list(result_pages) && !is.data.frame(result_pages), "tt_to_flextable with paginate=TRUE should produce a list" ) n_groups <- length(unique(test_data_rt$Group)) # Number of pages expected expect_equal(length(result_pages), n_groups, info = "Number of list elements should match number of pages defined by page_by" ) expect_true( all(sapply(result_pages, inherits, "flextable")), "All elements in the list should be flextable objects" ) # Verification 2: Check error handling for lpp in tt_to_flextable # This tests tt_to_flextable's pagination logic, not export_as_docx expect_error( tt_to_flextable(tbl, paginate = TRUE, lpp = 1), # lpp=1 typically too small # Optionally add regexp to match specific error message if known: # regexp = "Header rows are more than selected lines per pages", label = "tt_to_flextable should error if lpp is too small" ) # File handling for export tf <- tempfile(fileext = ".docx") on.exit(unlink(tf), add = TRUE) # Ensure cleanup # Action 2: Export the list of flextables generated by tt_to_flextable expect_no_error( # Pass the list 'result_pages' directly to export_as_docx export_as_docx(tt = result_pages, file = tf, add_page_break = TRUE) ) # Verification 3: Basic checks on the output DOCX file expect_true(file.exists(tf), "DOCX file was not created by export_as_docx") expect_gt(file.info(tf)$size, 0, "DOCX file appears empty") # NOTE: Verifying content (multiple tables, page breaks) requires docx parsing tools. }) test_that("export_as_docx works with explicit list of rlistings/rtables objects", { # Setup: Create rtable and rlisting res_rt <- build_table(lyt_rt, test_data_rt) # res_rl created above # Create the mixed list mixed_list <- list(Table = res_rt, Listing = res_rl) # File handling tf <- tempfile(fileext = ".docx") on.exit(unlink(tf), add = TRUE) # Action: Export the mixed list directly # export_as_docx should internally convert list elements using tt_to_flextable expect_no_error( export_as_docx(mixed_list, file = tf, add_page_break = TRUE) ) # Basic Verification expect_true(file.exists(tf), "DOCX file was not created") expect_gt(file.info(tf)$size, 0, "DOCX file is empty") # NOTE: Assumes export_as_docx correctly calls tt_to_flextable for list elements. }) test_that("export_as_docx works with pagination via lpp/cpp arguments", { # Setup: Create a single rtable potentially spanning multiple pages # Use a layout without explicit page_by lyt_long <- basic_table(title = "Long Table for Pagination") %>% split_cols_by("Group") %>% split_rows_by("Sub") %>% analyze("Val", afun = function(x) list(mean = mean(x), sd = sd(x), n = length(x))) tbl_long <- build_table(lyt_long, test_data_rt) # File handling tf <- tempfile(fileext = ".docx") on.exit(unlink(tf), add = TRUE) # Action: Export with pagination arguments passed via ... # Choose lpp small enough to likely force pagination test_lpp <- 10 expect_no_error( export_as_docx( tbl_long, file = tf, paginate = TRUE, # This tells tt_to_flextable to paginate lpp = test_lpp, # Passed via ... to tt_to_flextable # cpp = 80, # Optionally pass cpp via ... add_page_break = TRUE # Applies between generated pages ) ) # Basic Verification expect_true(file.exists(tf), "DOCX file was not created") expect_gt(file.info(tf)$size, 0, "DOCX file is empty") # NOTE: This test confirms the call path works. Verifying *actual* pagination # (i.e., multiple flextables were created and exported) requires either # inspecting the DOCX or intercepting the list passed to officer internally. # We assume if it runs without error, the pagination args were processed. }) test_that("export_as_docx works with column widths and autofit settings", { # Setup: Create a basic rtable res_rt <- build_table(lyt_rt, test_data_rt) num_cols <- ncol(res_rt) + 1 # +1 for row labels column # File handling tf1 <- tempfile(fileext = ".docx") tf2 <- tempfile(fileext = ".docx") on.exit(unlink(c(tf1, tf2)), add = TRUE) # Action 1: Manual Column Widths (autofit should become FALSE) # Provide relative widths matching number of columns manual_widths <- rep(1 / num_cols, num_cols) # Equal widths expect_no_error( expect_warning( out <- export_as_docx( res_rt, file = tf1, colwidths = manual_widths, # Passed via ... to tt_to_flextable # autofit_to_page = FALSE, # Should be set automatically by tt_to_flextable section_properties = section_properties_default(orientation = "landscape") # Ensure width context ) ) ) # Basic Verification 1 expect_true(file.exists(tf1), "DOCX file (manual width) was not created") expect_gt(file.info(tf1)$size, 0, "DOCX file (manual width) is empty") # Action 2: Autofit (Default Behavior) expect_no_error( export_as_docx( res_rt, file = tf2 # Default autofit_to_page = TRUE in tt_to_flextable is used ) ) # Basic Verification 2 expect_true(file.exists(tf2), "DOCX file (autofit) was not created") expect_gt(file.info(tf2)$size, 0, "DOCX file (autofit) is empty") # NOTE: Verifying the actual layout ("fixed" vs "autofit") or specific # column widths within the DOCX requires parsing the document. # These tests primarily ensure the arguments can be passed without error. })