Introduction

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:

To 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 roclet

Add 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.

Multiple 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()

Examples

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 roclet

As mentioned above, there are two tags available:

Note that both can be used at the same time.

We first demonstrate @tests and afterwards @testexamples.

@tests tag

For 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 tag

For 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:

param roclet

To 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 roclet

To 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 roclet

To 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'


Try the roxytest package in your browser

Any scripts or data that you put into this service are public.

roxytest documentation built on Jan. 11, 2023, 5:14 p.m.