From fea04c5893739ff41997b7d3744e7040eb30fe39 Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Thu, 27 Jun 2024 17:28:40 -0400 Subject: [PATCH] fix: Throw an error if template uses a parameter without a value Otherwise `glue::glue()` will just return an empty string. This gives a much better and more focused error message. --- R/app_json.R | 40 +++++++++++++++++++++++++++++----- tests/testthat/test-app_json.R | 19 ++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 tests/testthat/test-app_json.R diff --git a/R/app_json.R b/R/app_json.R index cdc690b..b465219 100644 --- a/R/app_json.R +++ b/R/app_json.R @@ -190,11 +190,10 @@ write_app_json <- function( for (template_file in template_html_files) { file_content <- brio::read_file(template_file) - file_content_interp <- glue::glue_data( - template_params, - file_content, - .open = "{{", - .close = "}}" + file_content_interp <- glue_template( + template = file_content, + params = template_params, + file = template_file ) dest_file <- fs::path(app_destdir, fs::path_rel(template_file, html_source_dir)) @@ -213,3 +212,34 @@ write_app_json <- function( ) verbose_print(": ", fs::file_info(app_json_output_file)$size[1], " bytes") } + +glue_template <- function(template, params, file = NULL) { + params <- list2env(params) + transformer <- glue_template_transformer(file) + + glue::glue( + template, + .envir = params, + .open = "{{", + .close = "}}", + .na = "", + .null = "", + .transformer = transformer + ) +} + +glue_template_transformer <- function(file) { + function(text, envir) { + text <- trimws(text) + + if (!exists(text, envir = envir)) { + rlang::abort(paste0( + "The template parameter `{{ ", text, " }}` was used ", + "in the export template in '", file, "', ", + "but a value was not provided to `template_params`." + )) + } + + get(text, envir = envir, inherits = FALSE) + } +} \ No newline at end of file diff --git a/tests/testthat/test-app_json.R b/tests/testthat/test-app_json.R new file mode 100644 index 0000000..4fe75c8 --- /dev/null +++ b/tests/testthat/test-app_json.R @@ -0,0 +1,19 @@ +test_that("glue_template() errors if template param is not defined", { + expect_snapshot( + glue_template("{{ not_defined }}", list(), "export_template/index.html"), + error = TRUE + ) +}) + +test_that("glue_template() ignores unused parameters", { + expect_equal( + glue_template("{{ x }}", list(x = "a", y = "b"), "export_template/index.html"), + glue::glue("a") + ) + + expect_equal( + glue_template("{{ a }}{{ b }}", list(a = NULL, b = NA), "export_template/index.html"), + glue::glue("") + ) +}) +