Skip to content

Commit

Permalink
Use {testthat} for mock testing (#2395)
Browse files Browse the repository at this point in the history
* start with linters_with_tags test

* bump testthat

* use testthat mock tests for cache

* all but namespaced functions covered

* mock namespaced functions

* fix hard dep check

* correct signautre

* second site

---------

Co-authored-by: Michael Chirico <[email protected]>
  • Loading branch information
IndrajeetPatil and MichaelChirico authored Dec 6, 2023
1 parent 8ae6da6 commit fbadcfc
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 45 deletions.
3 changes: 1 addition & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@ Suggests:
cli,
httr (>= 1.2.1),
jsonlite,
mockery,
patrick,
rlang,
rmarkdown,
rstudioapi (>= 0.2),
testthat (>= 3.1.5),
testthat (>= 3.2.1),
tibble,
tufte,
withr (>= 2.5.0)
Expand Down
5 changes: 5 additions & 0 deletions R/lintr-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@
#' }
## lintr namespace: end
NULL

# make binding available for mock testing
# ref: https://testthat.r-lib.org/dev/reference/local_mocked_bindings.html#base-functions
unlink <- NULL
quit <- NULL
19 changes: 9 additions & 10 deletions tests/testthat/test-cache.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ fhash <- function(filename) {
# `clear_cache`

test_that("clear_cache deletes the file if a file is given", {
skip_if_not_installed("mockery")

mockery::stub(clear_cache, "read_settings", function(...) invisible(...))
mockery::stub(clear_cache, "unlink", function(...) list(...))
local_mocked_bindings(
read_settings = function(...) invisible(...),
unlink = function(...) list(...)
)

e1 <- new.env(parent = emptyenv())
d1 <- withr::local_tempfile(pattern = "lintr_cache_")
Expand All @@ -50,10 +50,10 @@ test_that("clear_cache deletes the file if a file is given", {
})

test_that("clear_cache deletes the directory if no file is given", {
skip_if_not_installed("mockery")

mockery::stub(clear_cache, "read_settings", function(...) invisible(...))
mockery::stub(clear_cache, "unlink", function(...) list(...))
local_mocked_bindings(
read_settings = function(...) invisible(...),
unlink = function(...) list(...)
)

expect_identical(clear_cache(file = NULL, path = "."), list(".", recursive = TRUE))
})
Expand Down Expand Up @@ -421,10 +421,9 @@ test_that("lint with cache uses the provided relative cache directory", {
})

test_that("it works outside of a package", {
skip_if_not_installed("mockery")
linter <- assignment_linter()

mockery::stub(lintr:::find_default_encoding, "find_package", function(...) NULL)
local_mocked_bindings(find_package = function(...) NULL)
path <- withr::local_tempfile(pattern = "my_cache_dir_")
expect_false(dir.exists(path))
expect_lint("a <- 1", NULL, linter, cache = path)
Expand Down
12 changes: 3 additions & 9 deletions tests/testthat/test-ci.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,41 +27,35 @@ test_that("GitHub Actions functionality works in a subdirectory", {
})

test_that("GitHub Actions - linting on error works", {
skip_if_not_installed("mockery")

# imitate being on GHA whether or not we are
withr::local_envvar(list(GITHUB_ACTIONS = "true", LINTR_ERROR_ON_LINT = "true"))
withr::local_options(lintr.rstudio_source_markers = FALSE)
tmp <- withr::local_tempfile(lines = "x <- 1:nrow(y)")

l <- lint(tmp)

mockery::stub(print.lints, "base::quit", function(...) cat("Tried to quit.\n"))
local_mocked_bindings(quit = function(...) cat("Tried to quit.\n"))
expect_output(print(l), "::warning file", fixed = TRUE)
})

test_that("Printing works for Travis", {
skip_if_not_installed("mockery")

withr::local_envvar(list(GITHUB_ACTIONS = "false", TRAVIS_REPO_SLUG = "test/repo", LINTR_COMMENT_BOT = "true"))
withr::local_options(lintr.rstudio_source_markers = FALSE)
tmp <- withr::local_tempfile(lines = "x <- 1:nrow(y)")

l <- lint(tmp)

mockery::stub(print.lints, "github_comment", function(x, ...) cat(x, "\n"))
local_mocked_bindings(github_comment = function(x, ...) cat(x, "\n"))
expect_output(print(l), "*warning:*", fixed = TRUE)
})

test_that("Printing works for Wercker", {
skip_if_not_installed("mockery")

withr::local_envvar(list(GITHUB_ACTIONS = "false", WERCKER_GIT_BRANCH = "test/repo", LINTR_COMMENT_BOT = "true"))
withr::local_options(lintr.rstudio_source_markers = FALSE)
tmp <- withr::local_tempfile(lines = "x <- 1:nrow(y)")

l <- lint(tmp)

mockery::stub(print.lints, "github_comment", function(x, ...) cat(x, "\n"))
local_mocked_bindings(github_comment = function(x, ...) cat(x, "\n"))
expect_output(print(l), "*warning:*", fixed = TRUE)
})
8 changes: 5 additions & 3 deletions tests/testthat/test-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ test_that("print.lint works", {
})

test_that("print.lint works for inline data, even in RStudio", {
skip_if_not_installed("mockery")

l <- lint("x = 1\n")

# Make sure lints print to console.
Expand All @@ -114,7 +112,11 @@ test_that("print.lint works for inline data, even in RStudio", {
expect_output(print(l), "not =")
)

mockery::stub(print.lints, "rstudioapi::hasFun", function(...) FALSE)
skip_if_not_installed("rstudioapi")
local_mocked_bindings(
hasFun = function(...) FALSE,
.package = "rstudioapi"
)
withr::with_options(
list(lintr.rstudio_source_markers = TRUE),
expect_output(print(l), "not =")
Expand Down
40 changes: 24 additions & 16 deletions tests/testthat/test-rstudio_markers.R
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
test_that("it returns markers which match lints", {
skip_if_not_installed("mockery")

mockery::stub(rstudio_source_markers, "rstudioapi::callFun", function(...) list(...))
mockery::stub(rstudio_source_markers, "rstudioapi::executeCommand", function(...) NULL)
skip_if_not_installed("rstudioapi")
local_mocked_bindings(
callFun = function(...) list(...),
executeCommand = function(...) NULL,
.package = "rstudioapi"
)

lint1 <- list(Lint(
filename = "test_file",
Expand Down Expand Up @@ -53,10 +55,12 @@ test_that("it returns markers which match lints", {
})

test_that("it prepends the package path if it exists", {
skip_if_not_installed("mockery")

mockery::stub(rstudio_source_markers, "rstudioapi::callFun", function(...) list(...))
mockery::stub(rstudio_source_markers, "rstudioapi::executeCommand", function(...) NULL)
skip_if_not_installed("rstudioapi")
local_mocked_bindings(
callFun = function(...) list(...),
executeCommand = function(...) NULL,
.package = "rstudioapi"
)

lint3 <- list(Lint(
filename = "test_file",
Expand All @@ -80,10 +84,12 @@ test_that("it prepends the package path if it exists", {
})

test_that("it returns an empty list of markers if there are no lints", {
skip_if_not_installed("mockery")

mockery::stub(rstudio_source_markers, "rstudioapi::callFun", function(...) list(...))
mockery::stub(rstudio_source_markers, "rstudioapi::executeCommand", function(...) NULL)
skip_if_not_installed("rstudioapi")
local_mocked_bindings(
callFun = function(...) list(...),
executeCommand = function(...) NULL,
.package = "rstudioapi"
)

lint4 <- `class<-`(list(), "lints")
marker4 <- rstudio_source_markers(lint4)
Expand All @@ -92,15 +98,17 @@ test_that("it returns an empty list of markers if there are no lints", {
})

test_that("rstudio_source_markers apply to print within rstudio", {
skip_if_not_installed("mockery")

withr::local_options(lintr.rstudio_source_markers = TRUE)

tmp <- withr::local_tempfile(lines = "1:ncol(x)")
empty <- withr::local_tempfile(lines = character(0L))

mockery::stub(print.lints, "rstudioapi::hasFun", function(x, ...) TRUE)
mockery::stub(print.lints, "rstudio_source_markers", function(x) cat("matched\n"))
skip_if_not_installed("rstudioapi")
local_mocked_bindings(
hasFun = function(...) TRUE,
.package = "rstudioapi"
)
local_mocked_bindings(rstudio_source_markers = function(x) cat("matched\n"))

l <- lint(tmp, seq_linter())
expect_output(print(l), "matched", fixed = TRUE)
Expand Down
14 changes: 9 additions & 5 deletions tests/testthat/test-with.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ test_that("linters_with_defaults warns on unused NULLs", {
})

test_that("linters_with_tags() verifies the output of available_linters()", {
skip_if_not_installed("mockery")
mockery::stub(
linters_with_tags,
"available_linters",
data.frame(linter = c("fake_linter", "very_fake_linter"), package = "lintr", tags = "", stringsAsFactors = FALSE)
local_mocked_bindings(
available_linters = function(...) {
data.frame(
linter = c("fake_linter", "very_fake_linter"),
package = "lintr",
tags = "",
stringsAsFactors = FALSE
)
}
)
expect_error(
linters_with_tags(NULL),
Expand Down

0 comments on commit fbadcfc

Please sign in to comment.