R Under development (unstable) (2024-08-15 r87022 ucrt) -- "Unsuffered Consequences" Copyright (C) 2024 The R Foundation for Statistical Computing Platform: x86_64-w64-mingw32/x64 R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(unittest) > > R_binary <- file.path(R.home("bin"), "R") > > run_script <- function(script, expected_status, expected_out, description) { + # solaris does not like pipes so use tmp files as intermediaries + tmpfiles <- tempfile(pattern = c('R_unittest_stdout_','R_unittest_stderr_'), tmpdir = tempdir()) + exit_status <- withCallingHandlers( + system2( + R_binary, + c("--vanilla", "--slave"), + input = paste0(script, collapse = "\n"), + wait = TRUE, stdout = tmpfiles[1], stderr = tmpfiles[2]), + warning = function (w) { + invokeRestart("muffleWarning") + } + ) + actual <- readLines(tmpfiles[1]) # only interested in stdout + if( isTRUE(all.equal(actual, expected_out)) && exit_status == expected_status) { + cat("ok\n") + } else { + cat("\nExpected status", + expected_status, + "\nGot status", + exit_status, + "\nExpected stdout:", + expected_out, + "\nGot stdout:", + actual, + sep = "\n" + ) + stop( description ) + } + invisible(c(exit_status, actual)) + } > > expect_equal <- function (expr, expected) { + actual <- capture.output(expr) + if (!identical(all.equal(actual, expected), TRUE)) { + stop("ok_group output didn't match: ", actual) + } + } > > # Expression printed > expect_equal(ok_group("camels", TRUE), c( + "# camels")) > > # Can have multiple lines in a vector > expect_equal(ok_group(c("camels", "ostriches"), TRUE), c( + "# camels", + "# ostriches")) > > # Can divide lines with newlines too > expect_equal(ok_group(c("camels\nbadgers\r\nhoney badgers", "ostriches"), FALSE), c( + "# camels", + "# badgers", + "# honey badgers", + "# ostriches")) > > # Expression evaluated after printing section message > expect_equal(ok_group("camels", print("moo")), c( + "# camels", + '[1] "moo"')) > > # Return NULL > expect_equal({ + if (!is.null(ok_group("camels", 6))) stop("Didn't return NULL") + }, c("# camels")) > > run_script(' + library(unittest) + options(unittest.stop_on_fail = FALSE) + ok_group("snake", { + ok(1==1) + ok(1==2) + stop("hiss!") + ok(1==3) + }) + print("badger") + ', 10, c( + "# snake", + "ok - 1 == 1", + "not ok - 1 == 2", + "# Test returned non-TRUE value:", + "# [1] FALSE", + "not ok - ok_group 'snake'", + "# Exception: hiss!", + "# Traceback:", + '# 1: stop("hiss!")', + '[1] "badger"', + "1..3", + "# Looks like you failed 1 of 2 tests.", + "# 2: 1 == 2", + "# Looks like 1 groups raised an exception.", + "# 1: ok_group 'snake'", + NULL ), "Execution continues after an exception, if stop_on_fail FALSE") ok > > run_script(' + library(unittest) + options(unittest.stop_on_fail = TRUE) + ok_group("snake", stop("hiss!")) + print("badger") + ', 11, c( + "# snake", + "not ok - ok_group 'snake'", + "# Exception: hiss!", + "# Traceback:", + '# 1: stop("hiss!")', + "Bail out! Looks like 0 tests ran, but a group failed and unittest.stop_on_fail is set", + NULL ), "Execution stops after an exception, if stop_on_fail TRUE") ok > > run_script(' + library(unittest) + options(unittest.stop_on_fail = FALSE) + ok_group("snake", reptile <- snake) + ', 10, c( + "# snake", + "not ok - ok_group 'snake'", + "# Exception: object 'snake' not found", + "# Traceback:", + '# (none)', + "1..1", + "# Looks like 1 groups raised an exception.", + "# 1: ok_group 'snake'", + NULL ), "Don't output an empty call stack") ok > > proc.time() user system elapsed 0.25 0.07 1.31