[mirror] Opinionated R package quickstart
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #6 from VisruthSK/workflow-testsuite

workflow testsuite

authored by

Visruth Srimath Kandali and committed by
GitHub
ee92ce8b 36b451ce

+320
+20
tests/testthat/_snaps/workflow.md
··· 1 + # workflow step: create_package creates git-backed package skeleton 2 + 3 + Code 4 + files[!grepl("^\\.git/", files)] 5 + Output 6 + [1] ".Rbuildignore" 7 + [2] ".github/dependabot.yml" 8 + [3] ".github/workflows/check-standard.yaml" 9 + [4] ".github/workflows/format-suggest.yaml" 10 + [5] ".github/workflows/test-coverage.yaml" 11 + [6] ".vscode/extensions.json" 12 + [7] "AGENTS.md" 13 + [8] "DESCRIPTION" 14 + [9] "LICENSE.md" 15 + [10] "NEWS.md" 16 + [11] "README.md" 17 + [12] "air.toml" 18 + [13] "tests/jarl.toml" 19 + [14] "tests/testthat.R" 20 +
+18
tests/testthat/_snaps/workflow/AGENTS.md
··· 1 + # General 2 + - Read DESCRIPTION, README 3 + - Red/green TDD 4 + 5 + # Personality 6 + Literal, direct, concise, high-signal, non-empathic. No hedging, both-sidesing, closing summaries, or offers. Only ask questions if functionally blocked. 7 + 8 + # R Dev Rules 9 + - No manual edits: `.Rd`, `NAMESPACE` 10 + - Use `devtools::document()`, `test()`, `check()` 11 + - Deps: prefer Base R or current closure. Permission required for new deps to make code better 12 + - Add deps via `usethis::use_import_from()` or `use_package()` 13 + - Completion Pipeline (ordered, all must pass): 14 + 1. `air format .` 15 + 2. `jarl check . --fix --allow-dirty` 16 + 3. `devtools::document()` 17 + 4. `devtools::check()` 18 + 5. Report `covr::package_coverage()`
+2
tests/testthat/_snaps/workflow/DESCRIPTION.txt
··· 1 + Package: demoPkg 2 + Version: 0.0.0.9000
+1
tests/testthat/_snaps/workflow/LICENSE.md
··· 1 + MIT License
+1
tests/testthat/_snaps/workflow/NEWS.md
··· 1 + demoPkg 0.0.0.9000
+1
tests/testthat/_snaps/workflow/README.md
··· 1 + # demoPkg
+2
tests/testthat/_snaps/workflow/dot-Rbuildignore.txt
··· 1 + README\.Rmd 2 + AGENTS.md
+6
tests/testthat/_snaps/workflow/dot-github-dependabot.yml
··· 1 + version: 2 2 + updates: 3 + - package-ecosystem: "github-actions" 4 + directory: "/" 5 + schedule: 6 + interval: "weekly"
+5
tests/testthat/_snaps/workflow/dot-github-workflows-check-standard.yaml
··· 1 + name: check 2 + steps: 3 + - uses: actions/checkout@v6 4 + - uses: actions/upload-artifact@v6 5 + - uses: JamesIves/github-pages-deploy-action@v4
+3
tests/testthat/_snaps/workflow/dot-github-workflows-format-suggest.yaml
··· 1 + name: format-suggest 2 + steps: 3 + - uses: actions/checkout@v6
+6
tests/testthat/_snaps/workflow/dot-github-workflows-test-coverage.yaml
··· 1 + name: coverage 2 + permissions: 3 + contents: read 4 + id-token: write 5 + steps: 6 + - use_oidc: true
+6
tests/testthat/_snaps/workflow/dot-vscode-extensions.json
··· 1 + { 2 + "recommendations": [ 3 + "Posit.air-vscode", 4 + "etiennebacher.jarl-vscode" 5 + ] 6 + }
+2
tests/testthat/_snaps/workflow/tests-jarl.toml
··· 1 + [lint] 2 + extend-select = ["TESTTHAT"]
+1
tests/testthat/_snaps/workflow/tests-testthat.R
··· 1 + testthat::test_check("demoPkg")
+246
tests/testthat/test-workflow.R
··· 1 + run_workflow_fixture <- function(setup_AGENTS = TRUE) { 2 + tmp <- tempfile("bootstrapper-workflow-") 3 + dir.create(tmp) 4 + old <- setwd(tmp) 5 + on.exit(setwd(old), add = TRUE) 6 + 7 + pkg <- "demoPkg" 8 + fields <- list("Package" = pkg) 9 + state <- new.env(parent = emptyenv()) 10 + state$github_private <- NULL 11 + state$action_calls <- list() 12 + 13 + testthat::local_mocked_bindings( 14 + create_package = function(path, fields, ...) { 15 + expect_identical(path, pkg) 16 + expect_identical(fields, list("Package" = pkg)) 17 + expect_identical(list(...), list(open = FALSE)) 18 + 19 + fs::dir_create(path) 20 + setwd(path) 21 + writeLines( 22 + c("^.*\\.Rproj$", "^\\.Rproj\\.user$", "README\\.Rmd"), 23 + ".Rbuildignore" 24 + ) 25 + writeLines(c("Package: demoPkg", "Version: 0.0.0.9000"), "DESCRIPTION") 26 + writeLines("project", "demoPkg.Rproj") 27 + fs::dir_create(fs::path(".git", "hooks")) 28 + NULL 29 + }, 30 + use_github = function(private) { 31 + state$github_private <- private 32 + writeLines( 33 + c( 34 + "[remote \"origin\"]", 35 + "\turl = git@github.com:example/demoPkg.git" 36 + ), 37 + fs::path(".git", "config") 38 + ) 39 + NULL 40 + }, 41 + use_testthat = function() { 42 + fs::dir_create(fs::path("tests", "testthat")) 43 + writeLines( 44 + "testthat::test_check(\"demoPkg\")", 45 + fs::path("tests", "testthat.R") 46 + ) 47 + NULL 48 + }, 49 + use_readme_md = function(open = FALSE) { 50 + expect_false(open) 51 + writeLines("# demoPkg", "README.md") 52 + NULL 53 + }, 54 + use_news_md = function(open = FALSE) { 55 + expect_false(open) 56 + writeLines("demoPkg (development version)", "NEWS.md") 57 + NULL 58 + }, 59 + use_github_action = function(...) { 60 + args <- list(...) 61 + state$action_calls <- c(state$action_calls, list(args)) 62 + fs::dir_create(fs::path(".github", "workflows")) 63 + 64 + if (!is.null(args$url)) { 65 + writeLines( 66 + c( 67 + "name: format-suggest", 68 + "steps:", 69 + " - uses: actions/checkout@v4" 70 + ), 71 + fs::path(".github", "workflows", "format-suggest.yaml") 72 + ) 73 + return(invisible(NULL)) 74 + } 75 + 76 + if (identical(args[[1]], "check-standard")) { 77 + writeLines( 78 + c( 79 + "name: check", 80 + "steps:", 81 + " - uses: actions/checkout@v4", 82 + " - uses: actions/upload-artifact@v4", 83 + " - uses: JamesIves/github-pages-deploy-action@v4.5.0" 84 + ), 85 + fs::path(".github", "workflows", "check-standard.yaml") 86 + ) 87 + return(invisible(NULL)) 88 + } 89 + 90 + if (identical(args[[1]], "test-coverage")) { 91 + writeLines( 92 + c( 93 + "name: coverage", 94 + "permissions: read-all", 95 + "steps:", 96 + " - token: ${{ secrets.CODECOV_TOKEN }}" 97 + ), 98 + fs::path(".github", "workflows", "test-coverage.yaml") 99 + ) 100 + return(invisible(NULL)) 101 + } 102 + 103 + NULL 104 + }, 105 + use_pkgdown_github_pages = function() NULL, 106 + use_spell_check = function(error = FALSE) { 107 + expect_true(error) 108 + NULL 109 + }, 110 + use_air = function() { 111 + writeLines("[format]", "air.toml") 112 + NULL 113 + }, 114 + use_tidy_description = function() NULL, 115 + use_build_ignore = function(path, ...) { 116 + writeLines( 117 + c(readLines(".Rbuildignore", warn = FALSE), path), 118 + ".Rbuildignore" 119 + ) 120 + NULL 121 + }, 122 + .package = "usethis" 123 + ) 124 + 125 + testthat::local_mocked_bindings( 126 + use_license = function() { 127 + writeLines("MIT License", "LICENSE.md") 128 + NULL 129 + }, 130 + try_air_jarl_format = function() { 131 + invisible(c(air = TRUE, jarl = TRUE)) 132 + }, 133 + .package = "bootstrapper" 134 + ) 135 + 136 + expect_null( 137 + bootstrapper::bootstrapper( 138 + path = pkg, 139 + fields = fields, 140 + private = TRUE, 141 + setup_AGENTS = setup_AGENTS, 142 + open = FALSE 143 + ) 144 + ) 145 + 146 + list( 147 + pkg_path = fs::path(tmp, pkg), 148 + github_private = state$github_private, 149 + action_calls = state$action_calls 150 + ) 151 + } 152 + 153 + file_in_pkg <- function(fixture, ...) { 154 + fs::path(fixture$pkg_path, ...) 155 + } 156 + 157 + snapshot_name_from_path <- function(path) { 158 + name <- gsub("[/\\\\]+", "-", path) 159 + name <- sub("^\\.+", "dot-", name) 160 + name <- gsub("[^A-Za-z0-9._-]", "-", name) 161 + 162 + if (nzchar(fs::path_ext(path))) { 163 + name 164 + } else { 165 + paste0(name, ".txt") 166 + } 167 + } 168 + 169 + snapshot_workflow_files <- function(fixture, files) { 170 + for (f in files) { 171 + expect_true(file.exists(file_in_pkg(fixture, f)), info = f) 172 + expect_snapshot_file( 173 + file_in_pkg(fixture, f), 174 + compare = testthat::compare_file_text, 175 + name = snapshot_name_from_path(f) 176 + ) 177 + } 178 + } 179 + 180 + test_that("workflow step: create_package creates git-backed package skeleton", { 181 + fixture <- run_workflow_fixture() 182 + 183 + expect_true(isTRUE(fixture$github_private)) 184 + expect_true(file.exists(file_in_pkg(fixture, ".git", "config"))) 185 + expect_false(file.exists(file_in_pkg(fixture, "demoPkg.Rproj"))) 186 + 187 + old <- setwd(fixture$pkg_path) 188 + on.exit(setwd(old), add = TRUE) 189 + files <- sort(list.files( 190 + ".", 191 + recursive = TRUE, 192 + all.files = TRUE, 193 + no.. = TRUE 194 + )) 195 + expect_snapshot(files[!grepl("^\\.git/", files)]) 196 + 197 + snapshot_workflow_files( 198 + fixture, 199 + c("DESCRIPTION", "LICENSE.md", ".Rbuildignore") 200 + ) 201 + }) 202 + 203 + test_that("workflow step: pkg_setup creates core package files", { 204 + fixture <- run_workflow_fixture() 205 + 206 + snapshot_workflow_files( 207 + fixture, 208 + c("README.md", "NEWS.md", "tests/testthat.R") 209 + ) 210 + }) 211 + 212 + test_that("workflow step: setup_gha writes and rewrites workflow files", { 213 + fixture <- run_workflow_fixture() 214 + 215 + expect_length(fixture$action_calls, 3) 216 + expect_identical(fixture$action_calls[[1]][[1]], "check-standard") 217 + expect_identical(fixture$action_calls[[2]][[1]], "test-coverage") 218 + expect_identical( 219 + fixture$action_calls[[3]]$url, 220 + "https://github.com/visruthsk/bootstrapper/blob/main/.github/workflows/format-suggest.yaml" 221 + ) 222 + 223 + snapshot_workflow_files( 224 + fixture, 225 + c( 226 + ".github/workflows/check-standard.yaml", 227 + ".github/workflows/test-coverage.yaml", 228 + ".github/workflows/format-suggest.yaml" 229 + ) 230 + ) 231 + }) 232 + 233 + test_that("workflow step: setup templates are copied to expected locations", { 234 + fixture <- run_workflow_fixture(setup_AGENTS = TRUE) 235 + 236 + snapshot_workflow_files( 237 + fixture, 238 + c( 239 + ".github/dependabot.yml", 240 + "AGENTS.md", 241 + "tests/jarl.toml", 242 + ".vscode/extensions.json" 243 + ) 244 + ) 245 + expect_true(file.exists(file_in_pkg(fixture, ".git", "hooks", "pre-commit"))) 246 + })