From eb71d545fd0400d0157c93abb87038113c1ab950 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Mon, 6 Oct 2025 14:34:18 -0500 Subject: [PATCH 1/2] Improve `show_text()` * Fix `lengths()` type * Handle case where we remove first line of new item * Add some tests Fixes #2249 --- R/expect-match.R | 13 +++++--- tests/testthat/_snaps/expect-match.md | 43 +++++++++++++++++++++++++++ tests/testthat/test-expect-match.R | 24 +++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/R/expect-match.R b/R/expect-match.R index e60ca8734..febd80dcc 100644 --- a/R/expect-match.R +++ b/R/expect-match.R @@ -146,7 +146,7 @@ expect_match_ <- function( # Adapted from print.ellmer_prompt show_text <- function( x, - condition, + matches = rep(TRUE, length(x)), ..., max_items = 20, max_lines = max_items * 25 @@ -155,7 +155,7 @@ show_text <- function( n_extra <- length(x) - max_items if (n_extra > 0) { x <- x[seq_len(max_items)] - condition <- condition[seq_len(max_items)] + matches <- matches[seq_len(max_items)] } if (length(x) == 0) { @@ -165,7 +165,7 @@ show_text <- function( bar <- if (cli::is_utf8_output()) "\u2502" else "|" id <- ifelse( - condition, + matches, cli::col_green(cli::symbol$tick), cli::col_red(cli::symbol$cross) ) @@ -178,10 +178,15 @@ show_text <- function( x <- gsub("\n", paste0("\n", exdent), x) lines <- strsplit(x, "\n") - ids <- rep(seq_along(x), length(lines)) + ids <- rep(seq_along(x), lengths(lines)) + first <- c(TRUE, ids[-length(ids)] != ids[-1]) lines <- unlist(lines) if (length(lines) > max_lines) { + if (first[max_lines + 1]) { + max_lines <- max_lines - 1 + } + lines <- lines[seq_len(max_lines)] lines <- c(lines, paste0(exdent, "...")) n_extra <- n - ids[max_lines - 1] diff --git a/tests/testthat/_snaps/expect-match.md b/tests/testthat/_snaps/expect-match.md index c8e9396e1..0a9902a68 100644 --- a/tests/testthat/_snaps/expect-match.md +++ b/tests/testthat/_snaps/expect-match.md @@ -149,3 +149,46 @@ Actual text: x | test +# show_text() shows success and failure + + Code + base::writeLines(show_text(c("a", "b"), c(TRUE, FALSE))) + Output + ✔ │ a + ✖ │ b + +# show_text() truncates values and lines + + Code + base::writeLines(show_text(lines, max_lines = 3)) + Output + ✔ │ a + │ b + │ ... + ... and 8 more. + + Code + base::writeLines(show_text(lines, max_items = 3)) + Output + ✔ │ a + │ b + │ c + ✔ │ d + │ e + │ f + ✔ │ g + │ h + │ i + ... and 6 more. + + Code + base::writeLines(show_text(lines, max_items = 2, max_lines = 4)) + Output + ✔ │ a + │ b + │ c + ✔ │ d + │ ... + ... and 8 more. + + diff --git a/tests/testthat/test-expect-match.R b/tests/testthat/test-expect-match.R index 342d84669..633b40435 100644 --- a/tests/testthat/test-expect-match.R +++ b/tests/testthat/test-expect-match.R @@ -66,3 +66,27 @@ test_that("expect_no_match works", { test_that("empty string is never a match", { expect_success(expect_no_match(character(), "x")) }) + +# show_text() ------------------------------------------------------------------ + +test_that("show_text() shows success and failure", { + local_reproducible_output(unicode = TRUE) + expect_snapshot({ + base::writeLines(show_text(c("a", "b"), c(TRUE, FALSE))) + }) +}) + +test_that("show_text() truncates values and lines", { + local_reproducible_output(unicode = TRUE) + lines <- map_chr( + split(letters, (seq_along(letters) - 1) %/% 3), + paste, + collapse = "\n" + ) + + expect_snapshot({ + base::writeLines(show_text(lines, max_lines = 3)) + base::writeLines(show_text(lines, max_items = 3)) + base::writeLines(show_text(lines, max_items = 2, max_lines = 4)) + }) +}) From f9f6600527477b6be9e57d7d539fc7d185a1117e Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Mon, 6 Oct 2025 15:02:23 -0500 Subject: [PATCH 2/2] Tweak sig --- R/expect-match.R | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/R/expect-match.R b/R/expect-match.R index febd80dcc..2c6c96ed5 100644 --- a/R/expect-match.R +++ b/R/expect-match.R @@ -144,13 +144,10 @@ expect_match_ <- function( } # Adapted from print.ellmer_prompt -show_text <- function( - x, - matches = rep(TRUE, length(x)), - ..., - max_items = 20, - max_lines = max_items * 25 -) { +show_text <- function(x, matches = NULL, max_items = 20, max_lines = NULL) { + matches <- matches %||% rep(TRUE, length(x)) + max_lines <- max_lines %||% (max_items * 25) + n <- length(x) n_extra <- length(x) - max_items if (n_extra > 0) {