Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: checkhelper
Title: Deal with Check Outputs
Version: 1.0.0.9000
Version: 1.0.1
Authors@R: c(
person("Vincent", "Guyader", , "vincent@thinkr.fr", role = c("aut", "cre"),
comment = c(ORCID = "0000-0003-0671-9270")),
Expand All @@ -19,7 +19,7 @@ URL: https://thinkr-open.github.io/checkhelper/,
https://github.com/ThinkR-open/checkhelper
BugReports: https://github.com/ThinkR-open/checkhelper/issues
Depends:
R (>= 4.0)
R (>= 4.1)
Imports:
cli,
covr,
Expand Down Expand Up @@ -51,8 +51,12 @@ Suggests:
VignetteBuilder:
knitr
Config/Needs/website: ThinkR-open/thinkrtemplate
Config/testthat/edition: 3
Config/testthat/parallel: true
Config/testthat/start-first: checkhelper, fix-globals*, audit-globals,
check_as_cran, check_clean_userspace*, check_n_covr, audit-userspace
Encoding: UTF-8
Language: en-US
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.3
Config/roxygen2/version: 8.1.0
50 changes: 29 additions & 21 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,36 @@ export(get_no_visible)
export(get_notes)
export(print_globals)
export(use_data_doc)
importFrom(dplyr,filter)
importFrom(dplyr,first)
importFrom(dplyr,group_by)
importFrom(dplyr,if_else)
importFrom(dplyr,left_join)
importFrom(dplyr,mutate)
importFrom(dplyr,n)
importFrom(dplyr,pull)
importFrom(dplyr,rename)
importFrom(dplyr,select)
importFrom(dplyr,summarise)
importFrom(dplyr,tibble)
importFrom(dplyr,ungroup)
importFrom(glue,glue)
importFrom(glue,glue_collapse)
importFrom(dplyr,
filter,
first,
group_by,
if_else,
left_join,
mutate,
n,
pull,
rename,
select,
summarise,
tibble,
ungroup
)
importFrom(glue,
glue,
glue_collapse
)
importFrom(lifecycle,deprecated)
importFrom(magrittr,"%>%")
importFrom(purrr,compact)
importFrom(purrr,keep)
importFrom(purrr,map)
importFrom(purrr,walk)
importFrom(purrr,
compact,
keep,
map,
walk
)
importFrom(rcmdcheck,rcmdcheck)
importFrom(stringr,str_extract)
importFrom(stringr,str_extract_all)
importFrom(stringr,
str_extract,
str_extract_all
)
importFrom(utils,getFromNamespace)
17 changes: 16 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
# checkhelper 1.0.0.9000 (development version, GitHub only)
# checkhelper 1.0.1

## Bug fixes

- Compatibility with roxygen2 8.x. roxygen2 8.0.0 migrates the
DESCRIPTION `RoxygenNote` field to `Config/roxygen2/version`. On the
CRAN r-devel Fedora flavors (which ship roxygen2 8.x) this made a
`find_missing_tags()` test abort: it used `usethis::use_pipe()` as
scaffolding, and `usethis::uses_roxygen()` still detects roxygen via
the now-removed `RoxygenNote` field, so `use_pipe()` failed with
*"Package ... does not use roxygen2"*. The scaffolding re-exported the
magrittr `%>%` purely to add functions to the fixture; it was never
part of the asserted contract, so it has been removed (modern packages
use the native `|>`, which needs no setup). The audit pipeline itself
(`audit_tags()` / `find_missing_tags()`), which reimplements
`roxygenise()` through roxygen2 internals, was verified to remain
correct under roxygen2 8.1.0. A dedicated regression test
(`test-roxygen2-8x-compat.R`) now guards the whole audit flow against
the roxygen2 8.x field migration and block-classification changes.
- `fix_globals(write = TRUE)` no longer flattens the per-function
`# <fun>:` grouping comments of an existing `R/globals.R` when a
second run has nothing new to declare. When R CMD check surfaces
Expand Down
2 changes: 1 addition & 1 deletion R/globals.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
globalVariables(
utils::globalVariables(
unique(
c(
"is_importfrom", "importfrom_function", "is_global_variable",
Expand Down
1 change: 1 addition & 0 deletions man/checkhelper-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions man/find_missing_tags.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 19 additions & 18 deletions tests/testthat/helpers.R
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
test_that("Package version required", {

# Check the version of the package roxygen2 to take into account the breaking change.
expect_true(packageVersion("roxygen2") > "7.1.2")
# Silence expected lifecycle deprecations for the current test.
local_quiet_deprecation <- function(envir = parent.frame()) {
withr::local_options(lifecycle_verbosity = "quiet", .local_envir = envir)
}

})
# Discard output and messages for the current test.
# For file-scope fixtures, use `quiet_create_example_pkg()` instead.
local_quiet <- function(envir = parent.frame()) {
if (sink.number(type = "message") == 2L) {
withr::local_message_sink(nullfile(), .local_envir = envir)
}
withr::local_output_sink(nullfile(), .local_envir = envir)
invisible()
}
Comment thread
VincentGuyader marked this conversation as resolved.

# Silence lifecycle deprecation warnings globally; tests that explicitly
# exercise the deprecation layer override this with `withr::local_options()`.
options(lifecycle_verbosity = "quiet")
# Create the example package without toolchain output or expected warnings.
quiet_create_example_pkg <- function(...) {
local_quiet(environment())
suppressWarnings(create_example_pkg(...))
}

# Snapshot tempdir() at test entry and unlink anything new at teardown.
# Use this in tests that call rcmdcheck (audit_globals/fix_globals path)
# so they don't leak artefacts that downstream tests
# (test-check_clean_userspace) detect as pre-existing files.
#
# `envir` defaults to the caller's frame, which is the right thing inside
# a `test_that()` block. When called at FILE scope (e.g. before any
# `test_that` runs), pass `envir = testthat::teardown_env()` so the
# deferred cleanup ties to the file's documented teardown environment
# rather than to the source frame's lifetime.
# Remove files added to `tempdir()` when the test or file completes.
local_tempdir_clean <- function(envir = parent.frame()) {
before <- list.files(tempdir(), all.files = TRUE, no.. = TRUE)
withr::defer(
Expand Down
13 changes: 13 additions & 0 deletions tests/testthat/test-asciify-edge-cases.R
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ test_that("asciify_file is byte-equivalent on a no-op pure-ASCII input", {
# ---- return shape: n_tokens populated --------------------------------------

test_that("find_nonascii_files reports a real n_tokens for parseable R files", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines(
Expand All @@ -113,6 +114,7 @@ test_that("find_nonascii_files reports a real n_tokens for parseable R files", {
})

test_that("find_nonascii_files sorts its output by file then line", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
# Three files, intentionally created in non-alphabetical order
Expand All @@ -137,6 +139,7 @@ test_that("find_nonascii_files sorts its output by file then line", {
})

test_that("find_nonascii_files survives a NA file.size (e.g. broken symlink)", {
local_quiet_deprecation()
skip_on_os("windows") # symlinks need elevated perms on Windows
withr::with_tempdir({
dir.create("R")
Expand Down Expand Up @@ -213,6 +216,7 @@ test_that("asciify_file on a .Rnw reports a real n_tokens (Sweave routed read-on
# ---- return shape: asciify_pkg returns invisibly ---------------------------

test_that("asciify_pkg() returns its summary invisibly", {
local_quiet_deprecation()
pkg_path <- tempfile(pattern = "asciify-pkg-")
dir.create(pkg_path)
on.exit(unlink(pkg_path, recursive = TRUE), add = TRUE)
Expand All @@ -232,6 +236,7 @@ test_that("asciify_pkg() returns its summary invisibly", {
# ---- interactive feedback: summary message ---------------------------------

test_that("asciify_pkg() emits a 'would change' message in dry_run", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines(paste0("x <- \"caf", e, "\""), "R/f.R", useBytes = FALSE)
Expand All @@ -243,6 +248,7 @@ test_that("asciify_pkg() emits a 'would change' message in dry_run", {
})

test_that("asciify_pkg() emits a 'rewrote' message in apply mode", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines(paste0("x <- \"caf", e, "\""), "R/f.R", useBytes = FALSE)
Expand All @@ -254,6 +260,7 @@ test_that("asciify_pkg() emits a 'rewrote' message in apply mode", {
})

test_that("asciify_pkg() summary message reports correct counts", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines(paste0("x <- \"caf", e, "\""), "R/f1.R", useBytes = FALSE)
Expand All @@ -266,6 +273,7 @@ test_that("asciify_pkg() summary message reports correct counts", {
})

test_that("asciify_pkg() summary counts every non-ASCII character, not parser tokens", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
a <- "\u00e0"; e2 <- "\u00e9"; c2 <- "\u00e7"; e3 <- "\u00e8"
Expand All @@ -281,6 +289,7 @@ test_that("asciify_pkg() summary counts every non-ASCII character, not parser to
})

test_that("asciify_pkg() message is silenceable", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines(paste0("x <- \"caf", e, "\""), "R/f.R", useBytes = FALSE)
Expand All @@ -291,6 +300,7 @@ test_that("asciify_pkg() message is silenceable", {
})

test_that("asciify_pkg() hints to re-run with dry_run = FALSE in dry-run with changes", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines(paste0("x <- \"caf", e, "\""), "R/f.R", useBytes = FALSE)
Expand All @@ -302,6 +312,7 @@ test_that("asciify_pkg() hints to re-run with dry_run = FALSE in dry-run with ch
})

test_that("asciify_pkg() hints how to inspect the invisible result when there are changes", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines(paste0("x <- \"caf", e, "\""), "R/f.R", useBytes = FALSE)
Expand All @@ -313,6 +324,7 @@ test_that("asciify_pkg() hints how to inspect the invisible result when there ar
})

test_that("asciify_pkg() does not show the apply hint when in apply mode", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines(paste0("x <- \"caf", e, "\""), "R/f.R", useBytes = FALSE)
Expand All @@ -322,6 +334,7 @@ test_that("asciify_pkg() does not show the apply hint when in apply mode", {
})

test_that("asciify_pkg() does not show hints when nothing would change", {
local_quiet_deprecation()
withr::with_tempdir({
dir.create("R")
writeLines("x <- 1", "R/f.R", useBytes = FALSE) # ASCII-clean
Expand Down
10 changes: 9 additions & 1 deletion tests/testthat/test-asciify.R
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ test_that("asciify_r_source(identifiers='skip') stays silent and unchanged", {

test_that("asciify_r_source rewrites strings even in a file with a non-ASCII id (warn)", {
src <- "fa\u00e7on <- \"caf\u00e9\""
out <- expect_warning(asciify_r_source(src, identifiers = "warn"))
expect_warning(out <- asciify_r_source(src, identifiers = "warn"))
# the string was escaped
expect_match(out, "\\\\u00e9", fixed = FALSE)
# the identifier stays
Expand Down Expand Up @@ -240,6 +240,8 @@ test_that("asciify_file rewrites only the R chunks of an Rmd, leaving prose alon
# ---- asciify_pkg ------------------------------------------------------------

test_that("asciify_pkg(dry_run = TRUE) reports without writing", {
local_quiet_deprecation()
local_quiet()
pkg_path <- tempfile(pattern = "asciify-pkg-")
dir.create(pkg_path)
on.exit(unlink(pkg_path, recursive = TRUE), add = TRUE)
Expand All @@ -257,6 +259,8 @@ test_that("asciify_pkg(dry_run = TRUE) reports without writing", {
})

test_that("asciify_pkg(dry_run = FALSE) actually rewrites every R file in scope", {
local_quiet_deprecation()
local_quiet()
pkg_path <- tempfile(pattern = "asciify-pkg-")
dir.create(pkg_path)
on.exit(unlink(pkg_path, recursive = TRUE), add = TRUE)
Expand Down Expand Up @@ -288,6 +292,8 @@ test_that("asciify_pkg(dry_run = FALSE) actually rewrites every R file in scope"
})

test_that("asciify_pkg leaves a pure-ASCII file alone", {
local_quiet_deprecation()
local_quiet()
pkg_path <- tempfile(pattern = "asciify-pkg-")
dir.create(pkg_path)
on.exit(unlink(pkg_path, recursive = TRUE), add = TRUE)
Expand All @@ -300,6 +306,7 @@ test_that("asciify_pkg leaves a pure-ASCII file alone", {
# ---- find_nonascii_files ----------------------------------------------------

test_that("find_nonascii_files returns one row per offending line", {
local_quiet_deprecation()
pkg_path <- tempfile(pattern = "asciify-pkg-")
dir.create(pkg_path)
on.exit(unlink(pkg_path, recursive = TRUE), add = TRUE)
Expand All @@ -314,6 +321,7 @@ test_that("find_nonascii_files returns one row per offending line", {
})

test_that("find_nonascii_files returns an empty frame when there is nothing to flag", {
local_quiet_deprecation()
pkg_path <- tempfile(pattern = "asciify-pkg-")
dir.create(pkg_path)
on.exit(unlink(pkg_path, recursive = TRUE), add = TRUE)
Expand Down
15 changes: 9 additions & 6 deletions tests/testthat/test-audit-ascii.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ test_that("audit_ascii() exists with the expected signature", {
})

test_that("audit_ascii() on an ASCII-clean fixture returns an empty data frame", {
path <- suppressWarnings(create_example_pkg())
on.exit(unlink(path, recursive = TRUE))
local_quiet()
path <- quiet_create_example_pkg()
on.exit(unlink(path, recursive = TRUE), add = TRUE)
out <- suppressMessages(audit_ascii(path))
expect_s3_class(out, "data.frame")
expect_equal(nrow(out), 0L)
})

test_that("audit_ascii() flags non-ASCII bytes when present", {
path <- suppressWarnings(create_example_pkg())
on.exit(unlink(path, recursive = TRUE))
local_quiet()
path <- quiet_create_example_pkg()
on.exit(unlink(path, recursive = TRUE), add = TRUE)
writeLines(
"x <- \"café\"",
file.path(path, "R", "nonascii.R")
Expand All @@ -27,7 +29,8 @@ test_that("audit_ascii() flags non-ASCII bytes when present", {
})

test_that("audit_ascii() emits a cli message", {
path <- suppressWarnings(create_example_pkg())
on.exit(unlink(path, recursive = TRUE))
local_quiet()
path <- quiet_create_example_pkg()
on.exit(unlink(path, recursive = TRUE), add = TRUE)
expect_message(audit_ascii(path), regexp = "ASCII|ascii")
})
Loading