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

Add browser2() #1410

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export(TeamcityReporter)
export(announce_snapshot_file)
export(auto_test)
export(auto_test_package)
export(browser2)
export(capture_condition)
export(capture_error)
export(capture_expectation)
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# testthat (development version)

* New `browser2()` function to debug code running `expect_snapshot()`
and equivalent. It temporarily diverts any output back to `stdout`.

* Condition expectations now consistently return the expected
condition instead of the return value (#1371). Previously, they
would only return the condition if the return value was `NULL`,
Expand Down
29 changes: 29 additions & 0 deletions R/snapshot.R
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
#' @param error Do you expect the code to throw an error? The expectation
#' will fail (even on CRAN) if an unexpected error is thrown or the
#' expected error is not thrown.
#'
#' @seealso [browser2()] to debug code running inside `expect_snapshot()`.
#' @export
expect_snapshot <- function(x, cran = FALSE, error = FALSE) {
edition_require(3, "expect_snapshot()")
Expand Down Expand Up @@ -262,3 +264,30 @@ local_snapshot_dir <- function(snap_names, .env = parent.frame()) {
}

indent <- function(x) paste0(" ", x)

#' Call `browser()` with sinks temporarily diverted to `stdout`
#'
#' `browser2()` is useful to browse through code when an output sink
#' like `testthat::expect_snapshot()` is on the stack. The sinks are
#' restored to avoid disturbing the snapshot tests. Of course you will
#' still get failures if you're browsing through any `cat()` code (or
#' equivalent) that should be captured by a snapshot.
#'
#' @param ...,skipCalls Arguments passed to `browser()`.
#' @param frame The execution environment in which to register an
#' `on.exit` expression to restore any existing sinks.
#' @export
browser2 <- function(...,
skipCalls = 0,
frame = parent.frame()) {
if (!identical(stdout(), getConnection(1))) {
sink(getConnection(1))
withr::defer(sink(), envir = frame)
}

# Calling `browser()` on exit avoids RStudio displaying the
# `browser2()` location. We still need one `n` to get to the
# expected place. Ideally `skipCalls` would not skip but exit the
# contexts.
on.exit(browser(..., skipCalls = skipCalls + 1))
}
21 changes: 21 additions & 0 deletions man/browser2.Rd

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

3 changes: 3 additions & 0 deletions man/expect_snapshot.Rd

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