knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(roxytest)
knitr::knit_engines$set(roxy = function(options) { code <- paste(options$code, collapse = '\n') code <- paste0( "# ----------------------------------------------------\n", "# The code example below....\n", "# ----------------------------------------------------\n", "\n", code ) #out <- knitr::knit_child(text = options$code) out <- roxygen2::roc_proc_text(testthat_roclet(), code) out <- unlist(lapply(out, function(l) l[["<text>"]])) out <- paste0(out, collapse = "\n") #out <- out$tests[["<text>"]] out <- paste0( "\n", "# ----------------------------------------------------\n", "# ...will result in a generated file in tests/ folder:\n", "# ----------------------------------------------------\n", "\n", out) # To get syntax highlight options$engine <- "r" options$comment <- NA knitr::engine_output(options, code, out) })
There are a number of roclets included:
testthat_roclet
: Write testthat
tests in the roxygen2
documentation@tests
: Generate test skeletons@testexamples
: Generate test skeletons with @examples
included first such that e.g. variables can be reusedtinytest_roclet
: Write tinytest
tests in the roxygen2
documentation@tests
: Generate test skeletons@testexamples
: Generate test skeletons with @examples
included first such that e.g. variables can be reusedparam_roclet
: Checks for consistency in documentation of parameters (too many/too few)return_roclet
: Checks if @export
ed functions has @return
documentation (possibly just @return None
)examples_roclet
: Checks if @export
ed functions has @examples
documentationTo use the package in your own package you do not need to add any additional
dependencies in your package's DESCRIPTION
file apart from the usual
Suggests: testthat
that is required for testing with testthat
or the Suggests: tinytest
that is required for testing with tinytest
.
(If you only use param_roclet
, return_roclet
or examples_roclet
you do not need to add anything to Suggests
.)
Suggests: testthat # or tinytest
However, any developer working on your package needs to have roxytest
installed
to be able to successfully run roxygen2::roxygenise()
(or devtools::document()
).
For this reason you may consider adding roxytest
to Suggests
, but this is
not required.
testthat
rocletAdd the following lines to your package's DESCRIPTION
file (along with
Suggests: testthat
):
Roxygen: list(roclets = c("namespace", "rd", "roxytest::testthat_roclet"))
(Or make appropriate changes to obtain similar results.)
Then run the following:
roxygen2::roxygenise()
Similarly for the other roclets.
You can of course also add multiple, e.g.:
Roxygen: list(roclets = c("namespace", "rd", "roxytest::testthat_roclet", "roxytest::param_roclet", "roxytest::return_roclet"))
(Or make appropriate changes to obtain similar results.)
Then run the following:
roxygen2::roxygenise()
Below we show based on testthat
, but it is the same for tinytest
except
the output which then happens at inst/tinytest
without contest()
and testthat()
boilerplate.
testthat
rocletAs mentioned above, there are two tags available:
@tests
: Generate test skeletons@testexamples
: Generate test skeletons with @examples
included first such that e.g. variables can be reusedNote that both can be used at the same time.
We first demonstrate @tests
and afterwards @testexamples
.
@tests
tagFor example, if the file R/functions.R
contains this code (from roxytestdemo):
#' A function to do x #' #' @param x A number #' #' @tests #' expect_equal(foo(2), sqrt(2)) #' expect_error(foo("a string")) #' #' @return something foo <- function(x) { return(sqrt(x)) } #' A function to do y #' #' @param x Character vector #' @param y Character vector #' #' @tests #' expect_equal(bar("A", "B"), paste("A", "B", sep = "/")) #' #' @export bar <- function(x, y) { paste0(x, "/", y) }
Then roxygen2::roxygenise()
will generate (with the testthat_roclet
roclet)
the file tests/testthat/test-roxytest-tests-functions.R
with this content:
# Generated by roxytest: Do not edit by hand! context("File R/functions.R: @tests") test_that("Function foo() @ L10", { expect_equal(foo(2), sqrt(2)) expect_error(foo("a string")) }) test_that("Function bar() @ L23", { expect_equal(bar("A", "B"), paste("A", "B", sep = "/")) })
@testexamples
tagFor example, if the file R/functions.R
contains this code (from roxytestdemo):
#' A function to do w #' #' @param x A number #' #' @examples #' x <- 2 #' foo(x) #' #' @testexamples #' expect_equal(foo(x), foo(2)) #' #' @return something foo2 <- function(x) { return(sqrt(x)) }
Then roxygen2::roxygenise()
will generate (with the testthat_roclet
roclet)
the file tests/testthat/test-roxytest-testexamples-functions.R
with this content:
# Generated by roxytest: Do not edit by hand! context("File R/functions.R: @testexamples") test_that("Function foo2() @ L13", { x <- 2 foo(x) expect_equal(foo(x), foo(2)) })
Note that:
\dontrun
: Everything including content is removed\donttest
: Only the tag itself is removed\dontshow
: Only the tag itself is removedparam
rocletTo demonstrate the param_roclet
roclet assume that this block of documentation exists:
#' Summing two numbers #' #' @param x A number foobar <- function(x, y) { x + y }
When the package is documented, the following output will be displayed:
Functions with @param inconsistency: * Function 'foobar' with title 'Summing two numbers': - Missing @param's: y
Similarly if there are too many documented arguments.
return
rocletTo demonstrate the return_roclet
roclet assume that this block of documentation exists:
#' Summing two numbers #' #' @param x A number #' #' @export foobar2 <- function(x, y) { x + y }
When the package is documented, the following output will be displayed:
Functions with @export but no @return: * Function 'foobar2()' with title 'Summing two numbers'
examples
rocletTo demonstrate the examples_roclet
roclet assume that this block of documentation exists:
#' Summing two numbers #' #' @param x A number #' #' @export foobar2 <- function(x, y) { x + y }
When the package is documented, the following output will be displayed:
Functions with @export but no @example(s): * Function 'foobar2()' with title 'Summing two numbers'
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.