Expected `grepl(...)` to be TRUE.
Differences:
`actual`:   FALSE
`expected`: TRUE

version = "#1 SMP PREEMPT_DYNAMIC Tue Sep  9 12:21:26 UTC 2025",
dimnames = list(c("R/aaa.R", "R/dr_here.R", "R/here.R", "R/i_am.R", "R/utils.R", "R/zzz.R"))
test_that("handle_null returns 'N/A' for NULL", {
test_that("handle_null returns original value for non-NULL", {
test_that("convert_number_to_abbreviation handles small numbers", {
test_that("convert_number_to_abbreviation handles NA and non-numeric", {
test_that("safe_value returns 'N/A' for NULL", {
test_that("safe_value abbreviates numeric values", {
test_that("safe_value returns character for small numbers", {
# Define the toy assessment_results object
# Test the generate_test_pkg_summary function
check_list = list(res_check = list(rversion = "4.0.2")),
test_framework_type = "standard testing framework"
'Test Coverage Score', 'Date Time', 'Executor',
# Test the generate_test_details function
test_that("generate_coverage_section calls create_file_coverage_df when errors have expected structure", {
file_coverage <- matrix(c(85, 90), ncol = 1,
coverage = list(totalcoverage = mean(file_coverage), filecoverage = file_coverage),
mockery::stub(generate_coverage_section, "create_file_coverage_df", function(fn, fc, err, nt) {
captured_args <<- list(file_names = fn, file_coverage = fc, errors = err, notes = nt)
data.frame(Function = fn, Coverage = fc, Errors = paste0(err$message, "; ", err$status),
Notes = nt, stringsAsFactors = FALSE, row.names = fn)
result <- generate_coverage_section(assessment_results, pkg_name = "mockpkg")
test_that("generate_coverage_section handles NA errors and notes", {
file_coverage <- matrix(c(75, 82), ncol = 1,
test_that("generate_test_report returns message when directory does not exist", {
# Mock the fs::dir_exists function to return FALSE
expect_message(output_file <- generate_test_report(toy_assessment_results, output_dir), "The output directory does not exist.")
test_that("generate_test_report creates an HTML report", {
# Create a temporary directory for output
# Ensure cleanup of all files in tmp_dir
withr::defer(unlink(tmp_dir, recursive = TRUE), envir = parent.frame())
html_files <- list.files(tmp_dir, pattern = "\\.html$", full.names = TRUE)
# Check that at least one HTML file exists and is non-empty
expect_true(length(html_files) > 0, info = "No HTML report was generated")
expect_true(file.info(html_files[1])$size > 0, info = "HTML report is empty")
test_that("generate_coverage_section handles unexpected errors structure (character)", {
file_coverage <- matrix(c(50, 60), ncol = 1,
expect_identical(result$Errors, rep("Some error occurred", 2))
test_that("generate_coverage_section returns NA-row when filecoverage is NULL", {
coverage = list(totalcoverage = NA_real_, filecoverage = NULL),
errors = list(message = "m", status = 1),
test_that("create_file_coverage_df works correctly with toy dataset", {
# Expected output with matching row names
Errors = rep("in callr subprocess.; 0", length(file_names)),
result <- create_file_coverage_df(file_names, file_coverage, errors, notes)
# Check if the result matches the expected output
test_that("convert_vectors_to_df returns named list of data frames for existing elements", {
tests_skipped  = c("glmmPQL.R", "loglm.R", "polr.R"),
res <- convert_vectors_to_df(x, c("tests_skipped", "tests_passing"))
# Each element is a data.frame with column 'file'
test_that("convert_vectors_to_df filters out non-existent elements", {
res <- convert_vectors_to_df(x, c("tests_skipped", "tests_passing", "functions_no_tests"))
# Only existing element should be present
test_that("convert_vectors_to_df returns empty list when no elems exist", {
res <- convert_vectors_to_df(x, c("tests_passing", "functions_no_tests"))
test_that("convert_vectors_to_df handles empty vectors and NA values", {
tests_passing = c(NA_character_, "foo.R", NA_character_)
# NA values are kept as-is in the 'file' column
test_that("convert_vectors_to_df preserves element order as in 'elems' after filtering to existing names", {
res <- convert_vectors_to_df(x, c("c", "a", "missing", "b"))
# Confirm each data frame content matches
test_that("convert_vectors_to_df works with non-character vectors by coercion (data.frame behavior)", {
res <- convert_vectors_to_df(x, c("tests_numeric", "tests_logical"))
# data.frame will coerce non-character to appropriate column types
test_that("convert_vectors_to_df handles elems = character(0)", {
test_that("convert_vectors_to_df handles list with additional names without affecting result", {
res <- convert_vectors_to_df(x, c("tests_skipped", "inner_list"))
# Only elements matching elems and existing in x are included
# For list element, data.frame(file = x[[nm]]) will create a list-column; ensure it exists
# Minimal res_cov structure that satisfies assert_list(... names="named")
filecoverage  = data.frame(file = "R/foo.R", cov = 0.9, stringsAsFactors = FALSE)
make_test_results_stf <- function(pkg = "pkg", ver = "1.0.0") {
make_test_results_nstf <- function(pkg = "pkg", ver = "1.0.0") {
functions_no_tests = data.frame(`function` = c("fn_a", "fn_b"), stringsAsFactors = FALSE),
# A general stub for system.file that returns a temp path for the requested filename
# Expect args like: "report_templates", "<filename>", package = "test.assessr"
filename <- if (length(args) >= 2) args[[2]] else "unknown"
# A simple path_abs stub that mimics fs::path_abs(path, start=output_dir)
stub_path_abs <- function(path, start = NULL) {
normalizePath(path, winslash = "/", mustWork = FALSE)
# Basic stubs for coverage and other section generators
stub_generate_coverage_section    <- function(test_results, pkg_name) "coverage_stub"
test_that("returns NULL with message when rmarkdown is not available", {
# First requireNamespace call should return FALSE -> early exit
mockery::stub(generate_test_report, "requireNamespace", function(pkg, quietly = TRUE) FALSE)
# Output dir doesn't matter because we should exit first
res <- generate_test_report(tr, output_dir = tempdir()),
"Package 'rmarkdown' is required but not installed\\."
test_that("standard testing framework (nstf_none) uses STF template and renders", {
mockery::stub(generate_test_report, "requireNamespace", function(pkg, quietly = TRUE) TRUE)
function(test_results, elements_to_check) list(present = character(0), missing = elements_to_check))
res <- generate_test_report(tr, output_dir = outdir),
expected_outfile <- file.path(outdir, paste0("test_report_", tr$pkg_name, "_", tr$pkg_ver, ".html"))
test_that("non-standard testing framework (nstf present) uses NSTF template and processes data frames", {
present = c("functions_no_tests", "tests_skipped", "tests_passing"),
res <- generate_test_report(tr, output_dir = outdir)
# Environment passed to render should contain processed NSTF data
test_that("uses getwd() and emits message when output_dir is NULL", {
res <- generate_test_report(tr, output_dir = NULL),
"No output directory specified\\. Setting output to"
expect_true(grepl(paste0("^", normalizePath(wd, winslash = "/", mustWork = FALSE)), res))
expect_true(grepl(paste0("test_report_", tr$pkg_name, "_", tr$pkg_ver, "\\.html$"), res))
test_that("errors when required columns are missing", {
expect_error(create_long_summary_details(df_bad), "Input df must contain columns")
test_that("parses file without '#' and returns NA start_line", {
test_that("extracts start_line from after '#' up to the first underscore", {
test_that("trailing '#' with empty after_hash yields NA start_line", {
test_that("filters only rows with status == PASS (case and whitespace tolerant)", {
status = c(" pass ", "FAIL", "PASS", "pAsS"),
test_that("using mockery::stub to override sub allows testing parsing branches", {
# Replacement inspects the pattern argument to decide what to return,
# so we can simulate the three different sub() usages inside the function.
replacement_sub <- function(pattern, replacement, x, ...) {
# Stub `sub` inside create_long_summary_details, then call the function
file = "anything",           # value doesn't matter because sub is stubbed
test_that("stubbing grepl to FALSE simulates no '#' present and results in NA start_line", {
# Force grepl to always say there is no '#'
mockery::stub(create_long_summary_details, "grepl", function(pattern, x, ...) FALSE)
file = "dir/file.R#1_abc",   # original string contains '#', but grepl is stubbed
"Input df must contain columns: file, code_script, status, expectation, line1"
test_that("errors when only some required columns are present", {
test_that("processes valid dataframe with all required columns", {
expectation = "function should handle NA",
expect_equal(res$expectation, "function should handle NA")
test_that("extracts portion before '#' from file column", {
test_that("handles file names without '#' separator", {
test_that("preserves digits in test file names", {
test_that("handles multiple rows correctly", {
file = c("test-a.R#1", "test-b.R", "test-c.R#50_info"),
code_script = c("func_a", "func_b", "func_c"),
expectation = c("expect a", "expect b", "expect c"),
test_that("converts input columns to character type", {
test_that("returns dataframe with correct column names and order", {
expected_cols <- c("Rfunction", "test", "status", "expectation", "start_line")
test_that("removes row names (resets to default numeric indexing)", {
test_that("using mockery::stub to override sub allows testing file parsing", {
# Stub sub() to return predictable values based on pattern
test_that("stubbing sub to identity preserves full file path including '#'", {
# Stub sub() to act as identity (no replacement)
replacement_sub <- function(pattern, replacement, x, .) {
# Since sub is stubbed to return x unchanged, test should be full file string
test_that("handles empty/whitespace in expectation and status columns", {
test_that("handles special characters in expectation column", {
expectation = "function should throw error:  'value < 0' is invalid; see #123",
"function should throw error:  'value < 0' is invalid; see #123"
test_that("line1 column is directly assigned to start_line without modification", {
test_that("stringsAsFactors=FALSE is handled correctly for character conversion", {
# Check that all expected columns are character class
test_that("handles very long file paths and special delimiters", {
expectation = "should handle complex paths",
test_that("stubbing as.character allows testing type coercion behavior", {
# Mock as.character to prefix all values with "MOCK_"
# Note: We can only stub one instance; here we stub the first as.character call
# In practice, you might test the overall behavior instead
# After stubbing, all character conversions should be prefixed