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'
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.