Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use {testthat} for mock testing #2395

Merged
merged 8 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
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(x, ...) FALSE,
IndrajeetPatil marked this conversation as resolved.
Show resolved Hide resolved
.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(x, ...) 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