From e28db692e6ed1f1b772250d3a2e27f55547351ed Mon Sep 17 00:00:00 2001 From: howardbaik Date: Fri, 19 Sep 2025 16:57:48 -0400 Subject: [PATCH 1/4] Improve log validation error formatting with CLI styling --- tests/testthat/helper-valid_log.R | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/testthat/helper-valid_log.R b/tests/testthat/helper-valid_log.R index 631367d..cb4054e 100644 --- a/tests/testthat/helper-valid_log.R +++ b/tests/testthat/helper-valid_log.R @@ -67,14 +67,33 @@ expect_valid_log <- local({ stdout = TRUE, stderr = TRUE ) + + # Get rid of elements starting with "For further information visit" + result <- result[!grepl("For further information visit", result)] + # Add .field CLI on the fields + result_length <- length(result) + field_positions <- seq(2, result_length, by = 2) + + for (pos in field_positions) { + result[pos] <- glue::glue("{{.field {result[pos]}}}") + } + + result_with_breaks <- result[1] # Start with first element + for (i in seq(2, length(result), by = 2)) { + result_with_breaks <- c(result_with_breaks, "", result[i:(i + 1)]) + } + + formatted_message <- cli::format_message(c( + "The generated log did not pass the pydantic model:", + "", + result_with_breaks + )) + status <- attr(result, "status") expect( is.null(status) || status == 0, - paste0( - c("The generated log did not pass the pydantic model: ", result), - collapse = "\n" - ) + formatted_message ) } }) From 96f60d79a3a11a7ade908f09b58afa2d14889e01 Mon Sep 17 00:00:00 2001 From: howardbaik Date: Fri, 19 Sep 2025 17:13:17 -0400 Subject: [PATCH 2/4] Fix log validation error handling for single-line output --- tests/testthat/helper-valid_log.R | 43 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/tests/testthat/helper-valid_log.R b/tests/testthat/helper-valid_log.R index cb4054e..fb0a354 100644 --- a/tests/testthat/helper-valid_log.R +++ b/tests/testthat/helper-valid_log.R @@ -68,27 +68,34 @@ expect_valid_log <- local({ stderr = TRUE ) - # Get rid of elements starting with "For further information visit" - result <- result[!grepl("For further information visit", result)] - # Add .field CLI on the fields - result_length <- length(result) - field_positions <- seq(2, result_length, by = 2) + # "inst/test/inspect/logs/2025-03-24T10-39-36-05-00_simple-arithmetic_fQ9mYnqZFhtEuUenPpJgKL.json" + if (length(result) == 1) { + formatted_message <- cli::format_message(c( + "The generated log did not pass the pydantic model:", + glue::glue("{{.field {result[1]}}}") + )) + } else { + # Get rid of elements starting with "For further information visit" + result <- result[!grepl("For further information visit", result)] + # Add .field CLI on the fields + result_length <- length(result) + field_positions <- seq(2, result_length, by = 2) - for (pos in field_positions) { - result[pos] <- glue::glue("{{.field {result[pos]}}}") - } - - result_with_breaks <- result[1] # Start with first element - for (i in seq(2, length(result), by = 2)) { - result_with_breaks <- c(result_with_breaks, "", result[i:(i + 1)]) - } + for (pos in field_positions) { + result[pos] <- glue::glue("{{.field {result[pos]}}}") + } - formatted_message <- cli::format_message(c( - "The generated log did not pass the pydantic model:", - "", - result_with_breaks - )) + result_with_breaks <- result[1] # Start with first element + for (i in seq(2, length(result), by = 2)) { + result_with_breaks <- c(result_with_breaks, "", result[i:(i + 1)]) + } + formatted_message <- cli::format_message(c( + "The generated log did not pass the pydantic model:", + "", + result_with_breaks + )) + } status <- attr(result, "status") expect( From d5a13a5ba638c53ad155375a3961f61f3e6b6b4b Mon Sep 17 00:00:00 2001 From: simonpcouch Date: Mon, 6 Oct 2025 08:49:37 -0500 Subject: [PATCH 3/4] simplify control flow, clarify comments --- tests/testthat/helper-valid_log.R | 43 +++++++++++++++++-------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/tests/testthat/helper-valid_log.R b/tests/testthat/helper-valid_log.R index fb0a354..f7e4bcc 100644 --- a/tests/testthat/helper-valid_log.R +++ b/tests/testthat/helper-valid_log.R @@ -68,35 +68,40 @@ expect_valid_log <- local({ stderr = TRUE ) + status <- attr(result, "status") + # "inst/test/inspect/logs/2025-03-24T10-39-36-05-00_simple-arithmetic_fQ9mYnqZFhtEuUenPpJgKL.json" if (length(result) == 1) { formatted_message <- cli::format_message(c( "The generated log did not pass the pydantic model:", glue::glue("{{.field {result[1]}}}") )) - } else { - # Get rid of elements starting with "For further information visit" - result <- result[!grepl("For further information visit", result)] - # Add .field CLI on the fields - result_length <- length(result) - field_positions <- seq(2, result_length, by = 2) + expect( + is.null(status) || status == 0, + formatted_message + ) + } - for (pos in field_positions) { - result[pos] <- glue::glue("{{.field {result[pos]}}}") - } + # Make the result more readable by removing redundant elements + # and formatting indices with cli (#159) + result <- result[!grepl("For further information visit", result)] + result_length <- length(result) + field_positions <- seq(2, result_length, by = 2) - result_with_breaks <- result[1] # Start with first element - for (i in seq(2, length(result), by = 2)) { - result_with_breaks <- c(result_with_breaks, "", result[i:(i + 1)]) - } + for (pos in field_positions) { + result[pos] <- glue::glue("{{.field {result[pos]}}}") + } - formatted_message <- cli::format_message(c( - "The generated log did not pass the pydantic model:", - "", - result_with_breaks - )) + result_with_breaks <- result[1] + for (i in seq(2, length(result), by = 2)) { + result_with_breaks <- c(result_with_breaks, "", result[i:(i + 1)]) } - status <- attr(result, "status") + + formatted_message <- cli::format_message(c( + "The generated log did not pass the pydantic model:", + "", + result_with_breaks + )) expect( is.null(status) || status == 0, From 053708e81eb9088a7fa19cc8b849f864b5d8c51c Mon Sep 17 00:00:00 2001 From: simonpcouch Date: Mon, 6 Oct 2025 08:51:45 -0500 Subject: [PATCH 4/4] note change in NEWS --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index fc87384..5e17250 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # vitals (development version) +* Internal `expect_valid_log()` now styles Pydantic output for readability + (#159 by howardbaik). + * Manifest files for deployed logs are now named `listing.json` rather than `logs.json` for compatibility with newer Inspect versions. * Removed dependency on the rstudioapi package (#146).