From 98642d851005282b6d8c257f66ed91a68ab2c210 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 6 Aug 2024 15:30:49 +0200 Subject: [PATCH 1/6] helper function to throw error demoted to warning --- R/utilities.R | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/R/utilities.R b/R/utilities.R index a3357e6119..f69c2de52b 100644 --- a/R/utilities.R +++ b/R/utilities.R @@ -846,3 +846,15 @@ as_unordered_factor <- function(x) { class(x) <- setdiff(class(x), "ordered") x } + +warn_dots_used <- function(env = caller_env(), call = caller_env()) { + check_dots_used( + env = env, call = call, + # Demote from error to warning + error = function(cnd) { + # cli uses \f as newlines, not \n + msg <- gsub("\n", "\f", cnd_message(cnd)) + cli::cli_warn(msg, call = call) + } + ) +} From f637cb410d7104b0b56a1fe73d6a3695238125ec Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 6 Aug 2024 15:31:23 +0200 Subject: [PATCH 2/6] check `fortify()` dots --- R/fortify.R | 7 +++++-- man/fortify.Rd | 2 +- tests/testthat/_snaps/plot.md | 7 +++++++ tests/testthat/test-plot.R | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/R/fortify.R b/R/fortify.R index 3a61e3ce49..5b5b7c5171 100644 --- a/R/fortify.R +++ b/R/fortify.R @@ -8,9 +8,12 @@ #' @seealso [fortify.lm()] #' @param model model or other R object to convert to data frame #' @param data original dataset, if needed -#' @param ... other arguments passed to methods +#' @inheritParams rlang::args_dots_used #' @export -fortify <- function(model, data, ...) UseMethod("fortify") +fortify <- function(model, data, ...) { + warn_dots_used() + UseMethod("fortify") +} #' @export fortify.data.frame <- function(model, data, ...) model diff --git a/man/fortify.Rd b/man/fortify.Rd index 59dcfea9ec..36d1837025 100644 --- a/man/fortify.Rd +++ b/man/fortify.Rd @@ -11,7 +11,7 @@ fortify(model, data, ...) \item{data}{original dataset, if needed} -\item{...}{other arguments passed to methods} +\item{...}{Arguments passed to methods.} } \description{ Rather than using this function, I now recommend using the \pkg{broom} diff --git a/tests/testthat/_snaps/plot.md b/tests/testthat/_snaps/plot.md index 6035364389..157ebb6635 100644 --- a/tests/testthat/_snaps/plot.md +++ b/tests/testthat/_snaps/plot.md @@ -8,6 +8,13 @@ `data` cannot be a function. i Have you misspelled the `data` argument in `ggplot()` +--- + + Arguments in `...` must be used. + x Problematic argument: + * foobar = "nonsense" + i Did you misspell an argument name? + # construction have user friendly errors Cannot use `+` with a single argument. diff --git a/tests/testthat/test-plot.R b/tests/testthat/test-plot.R index dc1b507c13..2cccf79034 100644 --- a/tests/testthat/test-plot.R +++ b/tests/testthat/test-plot.R @@ -1,6 +1,7 @@ test_that("ggplot() throws informative errors", { expect_snapshot_error(ggplot(mapping = letters)) expect_snapshot_error(ggplot(data)) + expect_snapshot_warning(ggplot(foobar = "nonsense")) }) test_that("construction have user friendly errors", { From 43f1058341ca205b80ed3c1c7b0f43e6000e9f1d Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 6 Aug 2024 15:34:57 +0200 Subject: [PATCH 3/6] check `get_alt_text()` dots --- R/labels.R | 3 ++- man/get_alt_text.Rd | 2 +- tests/testthat/_snaps/labels.md | 7 +++++++ tests/testthat/test-labels.R | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/R/labels.R b/R/labels.R index 3012868874..a0f8bc8c05 100644 --- a/R/labels.R +++ b/R/labels.R @@ -166,7 +166,7 @@ ggtitle <- function(label, subtitle = waiver()) { #' text from the information stored in the plot. #' #' @param p a ggplot object -#' @param ... Currently ignored +#' @inheritParams rlang::args_dots_used #' #' @return A text string #' @@ -189,6 +189,7 @@ ggtitle <- function(label, subtitle = waiver()) { #' get_alt_text(p) #' get_alt_text <- function(p, ...) { + warn_dots_used() UseMethod("get_alt_text") } #' @export diff --git a/man/get_alt_text.Rd b/man/get_alt_text.Rd index b0da28a783..c9f6bdeb1e 100644 --- a/man/get_alt_text.Rd +++ b/man/get_alt_text.Rd @@ -10,7 +10,7 @@ get_alt_text(p, ...) \arguments{ \item{p}{a ggplot object} -\item{...}{Currently ignored} +\item{...}{Arguments passed to methods.} } \value{ A text string diff --git a/tests/testthat/_snaps/labels.md b/tests/testthat/_snaps/labels.md index e1f6ed4140..bf6cb0c57f 100644 --- a/tests/testthat/_snaps/labels.md +++ b/tests/testthat/_snaps/labels.md @@ -5,6 +5,13 @@ Output [1] "A plot showing class on a discrete x-axis and count on a continuous y-axis using a bar layer." +# get_alt_text checks dots + + Arguments in `...` must be used. + x Problematic argument: + * foo = "bar" + i Did you misspell an argument name? + # plot.tag.position rejects invalid input The `plot.tag.position` theme element must be a object. diff --git a/tests/testthat/test-labels.R b/tests/testthat/test-labels.R index e338226bd4..fc1d0b513a 100644 --- a/tests/testthat/test-labels.R +++ b/tests/testthat/test-labels.R @@ -89,6 +89,10 @@ test_that("alt text can take a function", { expect_snapshot(get_alt_text(p)) }) +test_that("get_alt_text checks dots", { + expect_snapshot_warning(get_alt_text(ggplot(), foo = "bar")) +}) + test_that("plot.tag.position rejects invalid input", { p <- ggplot(mtcars, aes(mpg, disp)) + geom_point() + labs(tag = "Fig. A)") From b57aaa7d7a1cd31934308d9179ada5780e2977e3 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 6 Aug 2024 15:44:38 +0200 Subject: [PATCH 4/6] check `deprecated_guide_args()` dots --- R/guide-legend.R | 1 + tests/testthat/_snaps/guides.md | 11 +++++++++++ tests/testthat/test-guides.R | 9 +++++++++ 3 files changed, 21 insertions(+) diff --git a/R/guide-legend.R b/R/guide-legend.R index 95dba1cfa0..c35e432230 100644 --- a/R/guide-legend.R +++ b/R/guide-legend.R @@ -688,6 +688,7 @@ deprecated_guide_args <- function( default.unit = "line", ..., .call = caller_call()) { + warn_dots_used(call = .call) args <- names(formals(deprecated_guide_args)) args <- setdiff(args, c("theme", "default.unit", "...", ".call")) diff --git a/tests/testthat/_snaps/guides.md b/tests/testthat/_snaps/guides.md index 62d1e41d24..be7c84d7f3 100644 --- a/tests/testthat/_snaps/guides.md +++ b/tests/testthat/_snaps/guides.md @@ -1,3 +1,14 @@ +# dots are checked when making guides + + Ignoring unknown argument to `guide_axis()`: `foo`. + +--- + + Arguments in `...` must be used. + x Problematic argument: + * foo = "bar" + i Did you misspell an argument name? + # Using non-position guides for position scales results in an informative error `guide_legend()` cannot be used for x, xmin, xmax, or xend. diff --git a/tests/testthat/test-guides.R b/tests/testthat/test-guides.R index a2e5ae918d..a2e4af3e4f 100644 --- a/tests/testthat/test-guides.R +++ b/tests/testthat/test-guides.R @@ -87,6 +87,15 @@ test_that("show.legend handles named vectors", { expect_equal(n_legends(p), 1) }) +test_that("dots are checked when making guides", { + expect_snapshot_warning( + new_guide(foo = "bar", super = GuideAxis) + ) + expect_snapshot_warning( + guide_legend(foo = "bar") + ) +}) + test_that("axis_label_overlap_priority always returns the correct number of elements", { expect_identical(axis_label_priority(0), numeric(0)) expect_setequal(axis_label_priority(1), seq_len(1)) From 7a6c1cbf0af6a5adeec0d78ca5af2a5d6312d32b Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 6 Aug 2024 16:39:50 +0200 Subject: [PATCH 5/6] check for unknown labels --- R/labels.R | 25 ++++++++++++++++++++++--- tests/testthat/_snaps/labels.md | 5 +++++ tests/testthat/test-labels.R | 5 +++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/R/labels.R b/R/labels.R index a0f8bc8c05..aa04732095 100644 --- a/R/labels.R +++ b/R/labels.R @@ -18,8 +18,8 @@ update_labels <- function(p, labels) { # Called in `ggplot_build()` to set default labels not specified by user. setup_plot_labels <- function(plot, layers, data) { - # Initiate from user-defined labels - labels <- plot$labels + # Initiate empty labels + labels <- list() # Find labels from every layer for (i in seq_along(layers)) { @@ -63,7 +63,26 @@ setup_plot_labels <- function(plot, layers, data) { labels <- defaults(labels, current) } } - labels + + # Warn for spurious labels that don't have a mapping. + # Note: sometimes, 'x' and 'y' might not have a mapping, like in + # `geom_function()`. We can display these labels anyway, so we include them. + plot_labels <- plot$labels + known_labels <- c(names(labels), fn_fmls_names(labs), "x", "y") + extra_labels <- setdiff(names(plot_labels), known_labels) + + if (length(extra_labels) > 0) { + extra_labels <- paste0( + "{.code ", extra_labels, " = \"", plot_labels[extra_labels], "\"}" + ) + names(extra_labels) <- rep("*", length(extra_labels)) + cli::cli_warn(c( + "Ignoring unknown labels:", + extra_labels + )) + } + + defaults(plot_labels, labels) } #' Modify axis, legend, and plot labels diff --git a/tests/testthat/_snaps/labels.md b/tests/testthat/_snaps/labels.md index bf6cb0c57f..49efe59a72 100644 --- a/tests/testthat/_snaps/labels.md +++ b/tests/testthat/_snaps/labels.md @@ -12,6 +12,11 @@ * foo = "bar" i Did you misspell an argument name? +# warnings are thrown for unknown labels + + Ignoring unknown labels: + * `foo = "bar"` + # plot.tag.position rejects invalid input The `plot.tag.position` theme element must be a object. diff --git a/tests/testthat/test-labels.R b/tests/testthat/test-labels.R index fc1d0b513a..f0d5c4e974 100644 --- a/tests/testthat/test-labels.R +++ b/tests/testthat/test-labels.R @@ -93,6 +93,11 @@ test_that("get_alt_text checks dots", { expect_snapshot_warning(get_alt_text(ggplot(), foo = "bar")) }) +test_that("warnings are thrown for unknown labels", { + p <- ggplot(mtcars, aes(mpg, disp)) + geom_point() + labs(foo = 'bar') + expect_snapshot_warning(ggplot_build(p)) +}) + test_that("plot.tag.position rejects invalid input", { p <- ggplot(mtcars, aes(mpg, disp)) + geom_point() + labs(tag = "Fig. A)") From f47d829274eafbe15bbb2141eaa663960abaf651 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 6 Aug 2024 17:18:45 +0200 Subject: [PATCH 6/6] add news bullet --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 4c0ea1e891..c1d1ae252b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # ggplot2 (development version) +* The ellipsis argument is now checked in `fortify()`, `get_alt_text()`, + `labs()` and several guides (@teunbrand, #3196). * Missing values from discrete palettes are no longer translated (@teunbrand, #5929). * Fixed bug in `facet_grid(margins = TRUE)` when using expresssions