diff --git a/NEWS.md b/NEWS.md index 10975f6..e73e41b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,7 +2,7 @@ * `+` now works in more situations, and gives errors when one side isn't a character vector. It no longer automatically applies glue interpolation to - both sides; you'll need to do that yourself as needed (#286). + a non-glue input, if there is one. You'll need to do that yourself (#286). * `glue_collapse(character())` (and hence `glue_sql_collapse(character())`) now return `""`, so that they always return a single string (#88). diff --git a/R/glue.R b/R/glue.R index 1f52bc2..5384a76 100644 --- a/R/glue.R +++ b/R/glue.R @@ -354,14 +354,18 @@ as.character.glue <- function(x, ...) { #' @export `+.glue` <- function(e1, e2) { - if (!is.character(e1)) { + if (!is.null(e1) && !is.character(e1)) { stop("LHS must be a character vector.") } - if (!is.character(e2)) { + if (!is.null(e2) && !is.character(e2)) { stop("RHS must be a character vector.") } - as_glue(paste0(e1, e2)) + glue_data( + "{e1}{e2}", + .x = list(e1 = e1, e2 = e2), + .envir = parent.frame() + ) } #' @importFrom methods setOldClass diff --git a/tests/testthat/_snaps/glue.md b/tests/testthat/_snaps/glue.md index 72c7de7..570b5e0 100644 --- a/tests/testthat/_snaps/glue.md +++ b/tests/testthat/_snaps/glue.md @@ -1,4 +1,4 @@ -# + method requires character vectors +# `+` method requires character vectors Code as_glue("a") + 1 @@ -9,6 +9,13 @@ Error LHS must be a character vector. +# `+` method errors for inputs of incompatible size + + Code + as_glue(letters[1:2]) + letters[1:3] + Error + Variables must be length 1 or 3 + # unterminated comment Code diff --git a/tests/testthat/test-glue.R b/tests/testthat/test-glue.R index 7b85e0e..4f4bb6d 100644 --- a/tests/testthat/test-glue.R +++ b/tests/testthat/test-glue.R @@ -507,22 +507,40 @@ test_that("throws informative error if interpolating a function", { } }) -test_that("+ method for glue works", { - expect_identical(glue("foo") + "bar", as_glue("foobar")) - expect_identical(glue("x = ") + "{x}", as_glue("x = {x}")) +test_that("`+` method for glue works", { + expect_identical(glue("foo") + "bar", "foobar") + expect_identical("foo" + glue("bar"), "foobar") +}) - x <- c("a", "b", "c") - expect_identical("(" + as_glue(x) + ")", paste0("(", x, ")")) +test_that("`+` method requires character vectors", { + expect_snapshot(error = TRUE, { + as_glue("a") + 1 + 1 + as_glue("a") + }) }) test_that("`+` method does not interpolate twice", { - expect_identical(glue("{x}", x = "{wut}") + "y", as_glue("{wut}y")) + expect_identical(glue("{x}", x = "{wut}") + "y", "{wut}y") +}) + +test_that("`+` method returns length-0 if there is a length-0 input", { + expect_identical(as_glue("hello") + character(), character()) }) -test_that("+ method requires character vectors", { +test_that("`+` method returns length-0 if there is a `NULL` input", { + expect_identical(as_glue("hello") + NULL, character()) +}) + +test_that("`+` recycles", { + x <- c("a", "b", "c") + expect_identical("(" + as_glue(x) + ")", paste0("(", x, ")")) + y <- as.character(1:3) + expect_identical(as_glue(x) + y, c("a1", "b2", "c3")) +}) + +test_that("`+` method errors for inputs of incompatible size", { expect_snapshot(error = TRUE, { - as_glue("a") + 1 - 1 + as_glue("a") + as_glue(letters[1:2]) + letters[1:3] }) })