tibble icon indicating copy to clipboard operation
tibble copied to clipboard

Incorrect `expect_snapshot()` trace env

Open lionel- opened this issue 1 year ago • 2 comments

I'm seeing these messages when I run tests:

Error (test-zzz-trunc-mat.R:144): trunc_mat for POSIXlt columns (#86)
Error in `trace_back(top = getOption("testthat_topenv"), bottom = trace_env)`: Can't find `bottom` on the call tree.
Backtrace:
 1. tibble:::expect_output_file_rel(...)
      at test-zzz-trunc-mat.R:144:2
 5. testthat::expect_snapshot(print(df, n = 8L, width = 60L))
 6. testthat:::expect_snapshot_helper(...)
 7. testthat::expect(...)
 8. rlang::trace_back(top = getOption("testthat_topenv"), bottom = trace_env)

That's because expect_snapshot() passes its caller env to trace_back(). Since you are calling it in a data mask, there is no corresponding frame on the stack:

expect_output_file_rel <- function(x, filename) {
  withr::with_options(
    list(digits = 4, width = 80, cli.unicode = l10n_info()$`UTF-8`),
    eval_tidy(quo(expect_snapshot({{ x }})))
  )
}

You could probably do something like:

inject(
  testthat::expect_snapshot(!!substitute(x)),
  caller_env()
)

lionel- avatar Oct 10 '22 12:10 lionel-

These seem to fix it:

expect_output_file_rel <- function(x, filename) {
  withr::with_options(
    list(digits = 4, width = 80, cli.unicode = l10n_info()$`UTF-8`),
    inject(
      expect_snapshot(!!substitute(x)),
      caller_env()
    )
  )
}


expect_snapshot_with_error <- function(code) {
  code <- enexpr(code)

  inject(
    if (packageVersion("testthat") >= "3.1.1") {
      expect_snapshot(variant = rlang_variant(), !!code, error = TRUE)
    } else if (packageVersion("testthat") > "3.0.0") {
      expect_snapshot(!!code, error = TRUE)
    } else {
      expect_snapshot(!!code)
    },
    caller_env()
  )
}

lionel- avatar Oct 10 '22 12:10 lionel-

oh actually expect_snapshot() supports quosures, just not injection. So we can do simpler and better:


expect_output_file_rel <- function(x, filename) {
  local_options(
    digits = 4,
    width = 80,
    cli.unicode = l10n_info()$`UTF-8`
  )
  inject(
    expect_snapshot({{ x }})
  )
}

expect_snapshot_with_error <- function(code) {
  inject(
    if (packageVersion("testthat") >= "3.1.1") {
      expect_snapshot(variant = rlang_variant(), {{ code }}, error = TRUE)
    } else if (packageVersion("testthat") > "3.0.0") {
      expect_snapshot({{ code }}, error = TRUE)
    } else {
      expect_snapshot({{ code }})
    }
  )
}

lionel- avatar Oct 10 '22 12:10 lionel-