From 98fdf1aeab081146c5be4c85103bb311ca5a8203 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Sat, 24 Sep 2022 08:17:44 -0500 Subject: [PATCH] Improve capture_output() encoding handling (#1693) Fixes #1574 --- NEWS.md | 3 +++ R/capture-output.R | 5 ++++- tests/testthat/test-capture-output.R | 20 ++++++++++++++++++++ tests/testthat/test-evaluate-promise.R | 13 ------------- 4 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 tests/testthat/test-capture-output.R diff --git a/NEWS.md b/NEWS.md index 41b421523..6bb88384e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # testthat (development version) +* Improve way `capture_output()` handles encoding thanks to suggestion from + Kurt Hornik. + * `test_check()` now suppresses hyperlinks since they'll take you to the wrong places (#1648). diff --git a/R/capture-output.R b/R/capture-output.R index 0f868543c..66da46f07 100644 --- a/R/capture-output.R +++ b/R/capture-output.R @@ -47,15 +47,18 @@ eval_with_output <- function(code, print = FALSE, width = 80) { if (!is.null(width)) { local_width(width) } + result <- withr::with_output_sink(path, withVisible(code)) if (result$visible && print) { withr::with_output_sink(path, testthat_print(result$value), append = TRUE) } + # A sink() will always write in the native encoding, so we read with + # base::readLines() then convert to UTF-8 list( val = result$value, vis = result$visible, - out = brio::read_lines(path) + out = enc2utf8(base::readLines(path, warn = FALSE)) ) } diff --git a/tests/testthat/test-capture-output.R b/tests/testthat/test-capture-output.R new file mode 100644 index 000000000..d1d967f1b --- /dev/null +++ b/tests/testthat/test-capture-output.R @@ -0,0 +1,20 @@ +test_that("multiplication works", { + utf8 <- "M\u00e4chler" + latin1 <- "M\xe4chler" + Encoding(latin1) <- "latin1" + + expect_equal(capture_output_lines(cat(latin1)), utf8) +}) + +test_that("capture output captures output", { + out1 <- capture_output(print(1:5)) + out2 <- capture_output(1:5, print = TRUE) + + expect_equal(out1, "[1] 1 2 3 4 5") + expect_equal(out2, "[1] 1 2 3 4 5") +}) + +test_that("capture output doesn't print invisible things", { + out <- capture_output(invisible(1), print = TRUE) + expect_equal(out, "") +}) diff --git a/tests/testthat/test-evaluate-promise.R b/tests/testthat/test-evaluate-promise.R index 2f90f572e..d5d95c887 100644 --- a/tests/testthat/test-evaluate-promise.R +++ b/tests/testthat/test-evaluate-promise.R @@ -25,16 +25,3 @@ test_that("capture_messages captures messages", { }) expect_equal(out, c("a\n", "b\n")) # message adds LF by default }) - -test_that("capture output captures output", { - out1 <- capture_output(print(1:5)) - out2 <- capture_output(1:5, print = TRUE) - - expect_equal(out1, "[1] 1 2 3 4 5") - expect_equal(out2, "[1] 1 2 3 4 5") -}) - -test_that("capture output doesn't print invisible things", { - out <- capture_output(invisible(1), print = TRUE) - expect_equal(out, "") -})