diff --git a/R/add_files.R b/R/add_files.R index 663cdd2d..bdd0f9e1 100644 --- a/R/add_files.R +++ b/R/add_files.R @@ -44,7 +44,7 @@ add_js_file <- function( msg = "`name` is required" ) - check_name_length(name) + check_name_length_is_one(name) name <- file_path_sans_ext(name) @@ -112,7 +112,7 @@ add_js_handler <- function( msg = "`name` is required" ) - check_name_length(name) + check_name_length_is_one(name) name <- file_path_sans_ext(name) @@ -177,7 +177,7 @@ add_js_input_binding <- function( msg = "`name` is required" ) - check_name_length(name) + check_name_length_is_one(name) attempt::stop_if( length(events$name) == 0, @@ -319,7 +319,7 @@ add_js_output_binding <- function( msg = "`name` is required" ) - check_name_length(name) + check_name_length_is_one(name) raw_name <- name @@ -403,7 +403,7 @@ add_css_file <- function( msg = "`name` is required" ) - check_name_length(name) + check_name_length_is_one(name) name <- file_path_sans_ext(name) @@ -465,7 +465,7 @@ add_sass_file <- function( msg = "`name` is required" ) - check_name_length(name) + check_name_length_is_one(name) name <- file_path_sans_ext(name) @@ -532,7 +532,7 @@ add_html_template <- function( ) { name <- file_path_sans_ext(name) - check_name_length(name) + check_name_length_is_one(name) old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) @@ -601,7 +601,7 @@ add_partial_html_template <- function( dir_create = TRUE ) { name <- file_path_sans_ext(name) - check_name_length(name) + check_name_length_is_one(name) old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) diff --git a/R/add_r_files.R b/R/add_r_files.R index eb8a42af..881642b4 100644 --- a/R/add_r_files.R +++ b/R/add_r_files.R @@ -9,7 +9,7 @@ add_r_files <- function( ) { name <- file_path_sans_ext(name) - check_name_length(name) + check_name_length_is_one(name) old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) diff --git a/R/modules_fn.R b/R/modules_fn.R index 13b3293b..c2b6b336 100644 --- a/R/modules_fn.R +++ b/R/modules_fn.R @@ -39,7 +39,7 @@ add_module <- function( ... ) { # Let's start with the checks for the validity of the name - check_name_length(name) + check_name_length_is_one(name) check_name_syntax(name) # We now check that: diff --git a/R/use_files.R b/R/use_files.R index 1c322f5d..94df6d19 100644 --- a/R/use_files.R +++ b/R/use_files.R @@ -18,12 +18,12 @@ #' @return The path to the file, invisibly. use_external_js_file <- function( url, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, dir_create = TRUE -) { + ) { old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) @@ -31,17 +31,24 @@ use_external_js_file <- function( name <- basename(url) } - check_name_length(name) + check_name_length_is_one(name) name <- file_path_sans_ext(name) new_file <- sprintf("%s.js", name) - dir_created <- create_if_needed( - dir, - type = "directory" + dir_created <- tryCatch( + create_if_needed( + dir, + type = "directory" + ), + error = function(e) { + out <- FALSE + names(out) <- e[[1]] + return(out) + } ) - if (!dir_created) { + if (isFALSE(dir_created)) { cat_dir_necessary() return(invisible(FALSE)) } @@ -85,12 +92,12 @@ use_external_js_file <- function( #' @rdname use_files use_external_css_file <- function( url, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, dir_create = TRUE -) { + ) { old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) @@ -98,17 +105,24 @@ use_external_css_file <- function( name <- basename(url) } - check_name_length(name) + check_name_length_is_one(name) name <- file_path_sans_ext(name) new_file <- sprintf("%s.css", name) - dir_created <- create_if_needed( - dir, - type = "directory" + dir_created <- tryCatch( + create_if_needed( + dir, + type = "directory" + ), + error = function(e) { + out <- FALSE + names(out) <- e[[1]] + return(out) + } ) - if (!dir_created) { + if (isFALSE(dir_created)) { cat_dir_necessary() return(invisible(FALSE)) } @@ -157,7 +171,7 @@ use_external_html_template <- function( dir = "inst/app/www", open = FALSE, dir_create = TRUE -) { + ) { old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) @@ -166,14 +180,21 @@ use_external_html_template <- function( file_path_sans_ext(name) ) - check_name_length(name) - - dir_created <- create_if_needed( - dir, - type = "directory" + check_name_length_is_one(name) + + dir_created <- tryCatch( + create_if_needed( + dir, + type = "directory" + ), + error = function(e) { + out <- FALSE + names(out) <- e[[1]] + return(out) + } ) - if (!dir_created) { + if (isFALSE(dir_created)) { cat_dir_necessary() return(invisible(FALSE)) } @@ -211,28 +232,34 @@ use_external_html_template <- function( #' @rdname use_files use_external_file <- function( url, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, dir_create = TRUE -) { - check_name_length(name) - + ) { if (missing(name)) { name <- basename(url) } + check_name_length_is_one(name) old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) - dir_created <- create_if_needed( - dir, - type = "directory" + dir_created <- tryCatch( + create_if_needed( + dir, + type = "directory" + ), + error = function(e) { + out <- FALSE + names(out) <- e[[1]] + return(out) + } ) - if (!dir_created) { + if (isFALSE(dir_created)) { cat_dir_necessary() return(invisible(FALSE)) } @@ -260,13 +287,12 @@ use_external_file <- function( #' @rdname use_files use_internal_js_file <- function( path, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, dir_create = TRUE -) { - check_name_length(name) + ) { old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) @@ -274,15 +300,24 @@ use_internal_js_file <- function( name <- basename(path) } + check_name_length_is_one(name) + name <- file_path_sans_ext(name) new_file <- sprintf("%s.js", name) - dir_created <- create_if_needed( - dir, - type = "directory" + dir_created <- tryCatch( + create_if_needed( + dir, + type = "directory" + ), + error = function(e) { + out <- FALSE + names(out) <- e[[1]] + return(out) + } ) - if (!dir_created) { + if (isFALSE(dir_created)) { cat_dir_necessary() return(invisible(FALSE)) } @@ -325,14 +360,12 @@ use_internal_js_file <- function( #' @rdname use_files use_internal_css_file <- function( path, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, dir_create = TRUE -) { - check_name_length(name) - + ) { old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) @@ -340,15 +373,24 @@ use_internal_css_file <- function( name <- basename(path) } + check_name_length_is_one(name) + name <- file_path_sans_ext(name) new_file <- sprintf("%s.css", name) - dir_created <- create_if_needed( - dir, - type = "directory" + dir_created <- tryCatch( + create_if_needed( + dir, + type = "directory" + ), + error = function(e) { + out <- FALSE + names(out) <- e[[1]] + return(out) + } ) - if (!dir_created) { + if (isFALSE(dir_created)) { cat_dir_necessary() return(invisible(FALSE)) } @@ -396,23 +438,30 @@ use_internal_html_template <- function( dir = "inst/app/www", open = FALSE, dir_create = TRUE -) { + ) { old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) - check_name_length(name) + check_name_length_is_one(name) new_file <- sprintf( "%s.html", file_path_sans_ext(name) ) - dir_created <- create_if_needed( - dir, - type = "directory" + dir_created <- tryCatch( + create_if_needed( + dir, + type = "directory" + ), + error = function(e) { + out <- FALSE + names(out) <- e[[1]] + return(out) + } ) - if (!dir_created) { + if (isFALSE(dir_created)) { cat_dir_necessary() return(invisible(FALSE)) } @@ -449,27 +498,34 @@ use_internal_html_template <- function( #' @rdname use_files use_internal_file <- function( path, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, dir_create = TRUE -) { + ) { if (missing(name)) { name <- basename(path) } - check_name_length(name) + check_name_length_is_one(name) old <- setwd(fs_path_abs(pkg)) on.exit(setwd(old)) - dir_created <- create_if_needed( - dir, - type = "directory" + dir_created <- tryCatch( + create_if_needed( + dir, + type = "directory" + ), + error = function(e) { + out <- FALSE + names(out) <- e[[1]] + return(out) + } ) - if (!dir_created) { + if (isFALSE(dir_created)) { cat_dir_necessary() return(invisible(FALSE)) } diff --git a/R/utils.R b/R/utils.R index 31edfb6f..71586c8e 100644 --- a/R/utils.R +++ b/R/utils.R @@ -477,7 +477,7 @@ is_existing_module <- function(module) { # This function is used for checking # that the name argument of the function # creating files is not of length() > 1 -check_name_length <- function(name) { +check_name_length_is_one <- function(name) { stop_if( name, ~ length(.x) > 1, diff --git a/README.md b/README.md index c654d477..f131b398 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ This `README` has been compiled on the ``` r Sys.time() -#> [1] "2023-08-08 14:20:03 UTC" +#> [1] "2023-08-08 18:26:15 UTC" ``` Here are the test & coverage results: @@ -121,21 +121,20 @@ Here are the test & coverage results: devtools::check(quiet = TRUE) #> ℹ Loading golem #> ── R CMD check results ─────────────────────────────────────── golem 0.4.12 ──── -#> Duration: 2m 36.7s +#> Duration: 2m 36.2s #> #> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ ``` ``` r covr::package_coverage() -#> golem Coverage: 75.69% +#> golem Coverage: 84.32% #> R/addins.R: 0.00% #> R/bootstrap_rstudio_api.R: 0.00% #> R/enable_roxygenize.R: 0.00% #> R/get_sysreqs.R: 0.00% #> R/run_dev.R: 0.00% #> R/sanity_check.R: 0.00% -#> R/use_files.R: 0.00% #> R/test_helpers.R: 30.26% #> R/js.R: 43.75% #> R/reload.R: 45.36% @@ -149,7 +148,7 @@ covr::package_coverage() #> R/modules_fn.R: 79.00% #> R/golem-yaml-set.R: 83.02% #> R/use_utils.R: 83.33% -#> R/utils.R: 85.13% +#> R/utils.R: 85.50% #> R/add_rstudio_files.R: 88.52% #> R/add_resource_path.R: 88.89% #> R/create_golem.R: 89.47% @@ -177,6 +176,7 @@ covr::package_coverage() #> R/pkg_tools.R: 100.00% #> R/set_golem_options.R: 100.00% #> R/templates.R: 100.00% +#> R/use_files.R: 100.00% #> R/with_opt.R: 100.00% ``` diff --git a/inst/utils/testfile_template_css.css b/inst/utils/testfile_template_css.css new file mode 100644 index 00000000..2beaf256 --- /dev/null +++ b/inst/utils/testfile_template_css.css @@ -0,0 +1,13 @@ + body { + background-color: lightblue; +} + +h1 { + color: white; + text-align: center; +} + +p { + font-family: verdana; + font-size: 20px; +} diff --git a/inst/utils/testfile_template_html.html b/inst/utils/testfile_template_html.html new file mode 100644 index 00000000..c87692f8 --- /dev/null +++ b/inst/utils/testfile_template_html.html @@ -0,0 +1,10 @@ + + +
+ +My first paragraph.
+ + + diff --git a/inst/utils/testfile_template_js.js b/inst/utils/testfile_template_js.js new file mode 100644 index 00000000..e282ac1d --- /dev/null +++ b/inst/utils/testfile_template_js.js @@ -0,0 +1,2 @@ +const myHeading = document.querySelector("h1"); +myHeading.textContent = "Hello world!"; diff --git a/inst/utils/testfile_template_plainfile.txt b/inst/utils/testfile_template_plainfile.txt new file mode 100644 index 00000000..3e715502 --- /dev/null +++ b/inst/utils/testfile_template_plainfile.txt @@ -0,0 +1 @@ +Some text. diff --git a/man/use_files.Rd b/man/use_files.Rd index 6fabee36..81ca47ca 100644 --- a/man/use_files.Rd +++ b/man/use_files.Rd @@ -13,7 +13,7 @@ \usage{ use_external_js_file( url, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, @@ -22,7 +22,7 @@ use_external_js_file( use_external_css_file( url, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, @@ -40,7 +40,7 @@ use_external_html_template( use_external_file( url, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, @@ -49,7 +49,7 @@ use_external_file( use_internal_js_file( path, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, @@ -58,7 +58,7 @@ use_internal_js_file( use_internal_css_file( path, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, @@ -76,7 +76,7 @@ use_internal_html_template( use_internal_file( path, - name, + name = NULL, pkg = get_golem_wd(), dir = "inst/app/www", open = FALSE, diff --git a/tests/testthat/test-add_files.R b/tests/testthat/test-add_files.R index ba8762e2..8c3d2490 100644 --- a/tests/testthat/test-add_files.R +++ b/tests/testthat/test-add_files.R @@ -10,7 +10,7 @@ expect_add_file <- function( # Be sure to remove all files in case there are remove_files("inst/app/www", ext) - # Checking that check_name_length is throwing an error + # Checking that check_name_length_is_one is throwing an error expect_error( fun(c("a", "b")), ) diff --git a/tests/testthat/test-use_files.R b/tests/testthat/test-use_files.R new file mode 100644 index 00000000..23aece6b --- /dev/null +++ b/tests/testthat/test-use_files.R @@ -0,0 +1,410 @@ +test_that("use_external_XXX_files() function family works properly", { + path_dummy_golem <- tempfile(pattern = "dummygolem") + create_golem( + path = path_dummy_golem, + open = FALSE + ) + with_dir( + path_dummy_golem, + { + # I. test the external ".txt" file download + # I.A standard case + use_external_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_plainfile.txt" + ) + test_file_download <- readLines( + "inst/app/www/testfile_template_plainfile.txt" + ) + expect_identical( + test_file_download, + "Some text." + ) + # I.B corner case: file already exists + expect_false( + use_external_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_plainfile.txt", + name = "testfile_template_plainfile.txt" + ) + ) + # I.C corner case: dir already exists + expect_false( + use_external_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_plainfile.txt", + name = "testfile_template_plainfile3.txt", + dir = "inst/app/www2" + ) + ) + + # II. test the external ".html" file download + # II.A standard case + use_external_html_template( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_html.html", + name = "testfile_template_html.html" + ) + test_file_download <- readLines( + "inst/app/www/testfile_template_html.html" + ) + expect_identical( + test_file_download, + c( + "", + "", + "", + "", + "My first paragraph.
", + "", + "", + "" + ) + ) + # II.B corner case: file already exists + expect_false( + use_external_html_template( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_html.html", + name = "testfile_template_html.html" + ) + ) + # II.C corner case: dir already exists + expect_false( + use_external_html_template( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_html.html", + name = "testfile_template_html2.html", + dir = "inst/app/www2" + ) + ) + + # III. test the external ".js" file download + # III.A standard case + use_external_js_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_js.js" + ) + test_file_download <- readLines( + "inst/app/www/testfile_template_js.js" + ) + expect_identical( + test_file_download, + c( + "const myHeading = document.querySelector(\"h1\");", + "myHeading.textContent = \"Hello world!\";" + ) + ) + # III.B corner case: file already exists + expect_false( + use_external_js_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_js.js", + name = "testfile_template_js.js" + ) + ) + # III.C corner case: dir already exists + expect_false( + use_external_js_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_js.js", + name = "testfile_template_js2.js", + dir = "inst/app/www2" + ) + ) + # III.D corner case: URL does not have extension ".js" + expect_false( + use_external_js_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_js", + name = "testfile_template_js3.js" + ) + ) + + # IV. test the external ".css" file download + # IV.A standard case + use_external_css_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_css.css" + ) + test_file_download <- readLines( + "inst/app/www/testfile_template_css.css" + ) + expect_identical( + test_file_download, + c( + " body {", + " background-color: lightblue;", + "}", + "", + "h1 {", + " color: white;", + " text-align: center;", + "}", + "", + "p {", + " font-family: verdana;", + " font-size: 20px;", + "}" + ) + ) + # IV.B corner case: file already exists + expect_false( + use_external_css_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_css.css", + name = "testfile_template_css.css" + ) + ) + # IV.C corner case: dir already exists + expect_false( + use_external_css_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_css.css", + name = "testfile_template_css2.css", + dir = "inst/app/www2" + ) + ) + # IV.D corner case: URL does not have extension ".css" + expect_false( + use_external_css_file( + url = "https://raw.githubusercontent.com/ThinkR-open/golem/dev/inst/utils/testfile_template_css", + name = "testfile_template_css3.css" + ) + ) + + unlink(path_dummy_golem, recursive = TRUE) + } + ) +}) +test_that("use_internal_XXX_files() function family works properly", { + path_dummy_golem <- tempfile(pattern = "dummygolem") + create_golem( + path = path_dummy_golem, + open = FALSE + ) + dir.create(file.path(path_dummy_golem, "tmp_dump_testfiles")) + file.copy( + from = file.path( + .libPaths()[1], + "golem", + "utils", + c( + "testfile_template_plainfile.txt", + "testfile_template_html.html", + "testfile_template_js.js", + "testfile_template_css.css" + ) + ), + to = file.path( + path_dummy_golem, + "tmp_dump_testfiles" + ) + ) + with_dir( + path_dummy_golem, + { + # I. test the internal ".txt" file usage + # I.A standard case + use_internal_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_plainfile.txt" + ) + ) + test_file_download <- readLines( + "inst/app/www/testfile_template_plainfile.txt" + ) + expect_identical( + test_file_download, + "Some text." + ) + # I.B corner case: file already exists + expect_false( + use_internal_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_plainfile.txt" + ), + name = "testfile_template_plainfile.txt" + ) + ) + # I.C corner case: dir already exists + expect_false( + use_internal_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_plainfile.txt" + ), + name = "testfile_template_plainfile2.txt", + dir = "inst/app/www2" + ) + ) + + # II. test the internal ".html" file usage + # II.A standard case + use_internal_html_template( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_html.html" + ), + name = "testfile_template_html.html" + ) + test_file_download <- readLines( + "inst/app/www/testfile_template_html.html" + ) + expect_identical( + test_file_download, + c( + "", + "", + "", + "", + "My first paragraph.
", + "", + "", + "" + ) + ) + # II.B corner case: file already exists + expect_false( + use_internal_html_template( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_html.html" + ), + name = "testfile_template_html.html" + ) + ) + # II.C corner case: dir already exists + expect_false( + use_internal_html_template( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_html.html" + ), + name = "testfile_template_html2.html", + dir = "inst/app/www2" + ) + ) + + # III. test the internal ".js" file usage + # III.A standard case + use_internal_js_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_js.js" + ) + ) + test_file_download <- readLines( + "inst/app/www/testfile_template_js.js" + ) + expect_identical( + test_file_download, + c( + "const myHeading = document.querySelector(\"h1\");", + "myHeading.textContent = \"Hello world!\";" + ) + ) + # III.B corner case: file already exists + expect_false( + use_internal_js_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_js.js" + ), + name = "testfile_template_js.js" + ) + ) + # III.C corner case: dir already exists + expect_false( + use_internal_js_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_js2.js" + ), + name = "testfile_template_js.js", + dir = "inst/app/www2" + ) + ) + # III.D corner case: file path does not have extension ".js" + expect_false( + use_internal_js_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_js" + ), + name = "testfile_template_js3.js" + ) + ) + + # IV. test the internal ".css" file usage + # IV.A standard case + use_internal_css_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_css.css" + ) + ) + test_file_download <- readLines( + "inst/app/www/testfile_template_css.css" + ) + expect_identical( + test_file_download, + c( + " body {", + " background-color: lightblue;", + "}", + "", + "h1 {", + " color: white;", + " text-align: center;", + "}", + "", + "p {", + " font-family: verdana;", + " font-size: 20px;", + "}" + ) + ) + # IV.B corner case: file already exists + expect_false( + use_internal_css_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_css.css" + ), + name = "testfile_template_css.css" + ) + ) + # IV.C corner case: dir already exists + expect_false( + use_internal_css_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_css.css" + ), + name = "testfile_template_css2.css", + dir = "inst/app/www2" + ) + ) + # IV.D corner case: file path does not have extension ".css" + expect_false( + use_internal_css_file( + path = file.path( + path_dummy_golem, + "tmp_dump_testfiles", + "testfile_template_css" + ), + name = "testfile_template_css3.css" + ) + ) + + unlink(path_dummy_golem, recursive = TRUE) + } + ) +})