From 06604c9def064eb5bf7bd40c89b2e5761815deec Mon Sep 17 00:00:00 2001 From: Matt Dray <18232097+matt-dray@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:25:18 +0000 Subject: [PATCH] Force error if tab title starts with a numeral (#125) * Force error if tab_title starts with a numeral, doc, test * Note that leading-numeral tab titles will errorin vignette --- DESCRIPTION | 2 +- NEWS.md | 3 +- R/a11ytable.R | 7 +-- R/utils-a11ytable.R | 16 ++++++ man/create_a11ytable.Rd | 6 +-- tests/testthat/test-a11ytable.R | 89 +++++++++++++++++++++++++++++---- vignettes/a11ytables.Rmd | 2 +- 7 files changed, 107 insertions(+), 18 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 8a65f8e..3eaa9cc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: a11ytables Title: Create Spreadsheet Publications Following Best Practice -Version: 0.3.0.9001 +Version: 0.3.1 Authors@R: c( person(given = "Matt", family = "Dray", role = c("aut", "cre"), email = "mwdray@gmail.com"), person(given = "Tim", family = "Taylor", role = "ctb"), diff --git a/NEWS.md b/NEWS.md index 15e1580..2b5223c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ -# a11ytables 0.3.0.9001 +# a11ytables 0.3.1 +* Bug fix: make it an error if tab names are started with a numeric value (#124). * Reduce gif file size, include additional frame (#121). # a11ytables 0.3.0 diff --git a/R/a11ytable.R b/R/a11ytable.R index d94cdde..c363744 100644 --- a/R/a11ytable.R +++ b/R/a11ytable.R @@ -8,9 +8,9 @@ #' #' @param tab_titles Required character vector, one value per sheet. Each title #' will appear literally on each tab of the final spreadsheet output. Keep -#' brief. Letters and numbers only; use underscores for spaces. For example: -#' 'Cover', 'Contents', 'Notes', 'Table_1'. Will be corrected automatically -#' if non-conforming. +#' brief. Letters and numbers only; do not start with a number; use +#' underscores for spaces. For example: 'Cover', 'Contents', 'Notes', +#' 'Table_1'. Will be corrected automatically unless there's an error. #' @param sheet_types Required character vector, one value per sheet. Sheets #' that don't contain publication tables ('meta' sheets) should be of type #' 'contents', 'cover' or 'notes'. Sheets that contain statistical tables of @@ -210,6 +210,7 @@ create_a11ytable <- function( as_a11ytable <- function(x) { if (any(names(x) %in% "tab_title")) { + .check_tab_titles(x[["tab_title"]]) x[["tab_title"]] <- .clean_tab_titles(x[["tab_title"]]) } diff --git a/R/utils-a11ytable.R b/R/utils-a11ytable.R index a4308d6..eab383b 100644 --- a/R/utils-a11ytable.R +++ b/R/utils-a11ytable.R @@ -1,3 +1,19 @@ +#' Clean Sheet Tab Titles +#' @param tab_titles Character vector. Names of tabs in the workbook. +#' @noRd +.check_tab_titles <- function(tab_titles) { + + tab_title_num_start <- grep("^\\d", unlist(tab_titles)) + + if (length(tab_title_num_start) > 0) { + stop( + "Elements in tab_titles must not begin with a numeral (change ", + .vector_to_sentence(tab_titles[tab_title_num_start]), ").", + call. = FALSE + ) + } + +} #' Clean Sheet Tab Titles #' @param tab_titles Character vector. Names of tabs in the workbook. diff --git a/man/create_a11ytable.Rd b/man/create_a11ytable.Rd index 82dff9c..93d4d15 100644 --- a/man/create_a11ytable.Rd +++ b/man/create_a11ytable.Rd @@ -17,9 +17,9 @@ create_a11ytable( \arguments{ \item{tab_titles}{Required character vector, one value per sheet. Each title will appear literally on each tab of the final spreadsheet output. Keep -brief. Letters and numbers only; use underscores for spaces. For example: -'Cover', 'Contents', 'Notes', 'Table_1'. Will be corrected automatically -if non-conforming.} +brief. Letters and numbers only; do not start with a number; use +underscores for spaces. For example: 'Cover', 'Contents', 'Notes', +'Table_1'. Will be corrected automatically unless there's an error.} \item{sheet_types}{Required character vector, one value per sheet. Sheets that don't contain publication tables ('meta' sheets) should be of type diff --git a/tests/testthat/test-a11ytable.R b/tests/testthat/test-a11ytable.R index 4a641d4..8882b81 100644 --- a/tests/testthat/test-a11ytable.R +++ b/tests/testthat/test-a11ytable.R @@ -174,6 +174,44 @@ test_that("absence of note sheets doesn't prevent a11ytable formation", { }) +test_that("tab_titles with starting numeral will error", { + + demo_df[demo_df$tab_title == "Table_2", "tab_title"] <- "2_Table" + + expect_error( + with( + demo_df, + create_a11ytable( + tab_titles = tab_title, + sheet_types = sheet_type, + sheet_titles = sheet_title, + tables = table + ) + ), + "Elements in tab_titles must not begin with a numeral \\(change 2_Table\\)\\." + ) + +}) + +test_that("non-conforming tab_titles are cleaned", { + + expect_warning( + create_a11ytable( + tab_titles = c("cover", "contents", "Table 2"), + sheet_types = c("cover", "contents", "tables"), + sheet_titles = c("Cover", "Contents", "Table"), + source = "Source", + tables = list( + demo_df[["table"]][[1]], + demo_df[["table"]][[2]][3, ], + mtcars + ) + ), + "These tab_titles have been cleaned automatically: Table 2 \\(now Table_2\\)" + ) + +}) + test_that("tab_titles are unique", { demo_df[demo_df$tab_title == "Table_2", "tab_title"] <- "Table_1" @@ -317,21 +355,54 @@ test_that("period added to end of text if needed", { test_that("tab titles are cleaned and warnings provided", { - long_title <- "12345678901234567890123456789012" + long_title <- "X12345678901234567890123456789012" - expect_warning(.clean_tab_titles("Table 1")) - expect_warning(.clean_tab_titles(c("Table 1", "Table 2"))) - expect_warning(.clean_tab_titles(c("Table_1", "Table 2"))) - expect_warning(.clean_tab_titles("Table!@£#$%^&*(){}[]-=+;:'\"\\|<>,.~`/?1")) - expect_warning(.clean_tab_titles(long_title)) + expect_warning( + .clean_tab_titles("Table 1"), + "These tab_titles have been cleaned automatically: Table 1 \\(now Table_1\\)\\." + ) + + expect_warning( + .clean_tab_titles(c("Table 1", "Table 2")), + "These tab_titles have been cleaned automatically: Table 1, Table 2 \\(now Table_1, Table_2\\)\\." + ) + + expect_warning( + .clean_tab_titles(c("Table_1", "Table 2")), + "These tab_titles have been cleaned automatically: Table 2 \\(now Table_2\\)\\." + ) + + expect_warning( + .clean_tab_titles("Table!@£#$%^&*(){}[]-=+;:'\"\\|<>,.~`/?1"), + "These tab_titles have been cleaned automatically:.+now Table1\\)\\." + ) + + expect_warning( + .clean_tab_titles(long_title), + "These tab_titles have been cleaned automatically: X12345678901234567890123456789012 \\(now X123456789012345678901234567890\\)\\." + ) x <- demo_df x[1, "tab_title"] <- long_title expect_warning(as_a11ytable(x)) - y <- demo_df - y[1, "tab_title"] <- "Cover!" - expect_warning(as_a11ytable(y)) + x <- demo_df + x[1, "tab_title"] <- "Cover!" + expect_warning(as_a11ytable(x)) + + x <- demo_df + x["tab_title"][5, ] <- long_title + expect_warning( + .warn_a11ytable(x), + "Each tab_title must be shorter than 31 characters." + ) + + x <- demo_df + x["tab_title"][5, ] <- "Table-1!" + expect_warning( + .warn_a11ytable(x), + "Each tab_title must contain only letters, numbers or underscores." + ) }) diff --git a/vignettes/a11ytables.Rmd b/vignettes/a11ytables.Rmd index d1bead0..807efe2 100644 --- a/vignettes/a11ytables.Rmd +++ b/vignettes/a11ytables.Rmd @@ -190,7 +190,7 @@ my_a11ytable <- ) ``` -The function will return errors or warnings if anything is missing or seems odd. For example, we were warned that a value we supplied to `tab_title` had to be cleaned from 'Table 1' to 'Table_1', since blank spaces are not allowed in tab names. +The function will return errors or warnings if anything is missing or seems odd. For example, we were warned that a value we supplied to `tab_title` had to be cleaned from 'Table 1' to 'Table_1', since blank spaces are not allowed in tab names. Note that there will be an error if there are any tab titles that start with a numeral. Here's a preview of the object that was created: