Title: | Add Tests to Examples |
Version: | 0.2.0 |
Description: | Add tests in-line in examples. Provides standalone functions for facilitating easier test writing in Rd files. However, a more familiar interface is provided using 'roxygen2' tags. Tools are also provided for facilitating package configuration and use with 'testthat'. |
URL: | https://github.com/dgkf/testex, https://dgkf.github.io/testex/ |
License: | MIT + file LICENSE |
Depends: | R (≥ 3.2.0) |
Imports: | utils |
Suggests: | testthat, withr, callr, roxygen2, spelling, knitr, rmarkdown |
Encoding: | UTF-8 |
RoxygenNote: | 7.3.1 |
Language: | en-US |
VignetteBuilder: | knitr |
Config/testex/options: | list(version = "0.2.0") |
NeedsCompilation: | no |
Packaged: | 2024-04-14 23:16:45 UTC; root |
Author: | Doug Kelkhoff [aut, cre] |
Maintainer: | Doug Kelkhoff <doug.kelkhoff@gmail.com> |
Repository: | CRAN |
Date/Publication: | 2024-04-14 23:30:02 UTC |
Convert to srcref
Description
Convert to srcref
Usage
as.srcref(x)
## S3 method for class 'character'
as.srcref(x)
Arguments
x |
an object to coerce |
Value
A srcref
Methods (by class)
-
as.srcref(character)
: Convert from asrcref_key
to a srcref object
Deparse an expression and indent for pretty-printing
Description
Deparse an expression and indent for pretty-printing
Usage
deparse_indent(x, indent = 0L)
Arguments
x |
A |
indent |
An |
Value
An indented version of the deparsed string from x
.
Deparse pretty
Description
Deparse to a single string with two spaces of indentation
Usage
deparse_pretty(expr)
Arguments
expr |
An expression to deparse |
Value
A pretty-formatted string representation of expr
.
Expect no Error
Description
Expect no Error
Usage
fallback_expect_no_error(object, ...)
Arguments
object |
An expression to evaluate |
... |
Additional arguments unused |
Value
The value produced by the expectation code
Note
This is a stop-gap implementation, and will only be used for legacy
versions of testthat
before this was properly supported.
A testthat
expectation that the provided code can be evaluated without
producing an error. This is the most basic expectation one should expect of
any example code. Further expectations are provided in subsequent testthat
code.
Return the number of characters in a line of a file
Description
Return the number of characters in a line of a file
Usage
file_line_nchar(file, line)
Arguments
file |
A file to use as reference |
line |
A line number to retrieve the length of |
Value
The number of characters in line line
.
Determine which symbol to use by default when testing examples
Description
Determine which symbol to use by default when testing examples
Usage
get_example_value()
Value
The value of the last test expression
Test whether currently executing R checks
Description
Test whether currently executing R checks
Usage
is_r_cmd_check()
Value
A logical indicating whether R CMD check
is currently running
Package source file helpers
Description
Discover specific package related file paths
Usage
find_package_root(path = ".", quiet = FALSE)
find_package_rds(package, path = getwd())
package_desc(path = getwd())
Arguments
path |
A file path within a package's source code or installation
directory. Only considered if |
quiet |
Whether to suppress output |
package |
A package name |
Value
NULL, invisibly
A list of package Rd objects, as returned by tools::Rd_db()
Register a method for a suggested dependency
Description
Generally, the recommend way to register an S3 method is to use the
S3Method()
namespace directive (often generated automatically by the
@export
roxygen2
tag). However, this technique requires that the generic
be in an imported package, and sometimes you want to suggest a package,
and only provide a method when that package is loaded. s3_register()
can be called from your package's .onLoad()
to dynamically register
a method only if the generic's package is loaded.
Arguments
generic |
Name of the generic in the form |
class |
Name of the class |
method |
Optionally, the implementation of the method. By default,
this will be found by looking for a function called Note that providing |
Details
For R 3.5.0 and later, s3_register()
is also useful when demonstrating
class creation in a vignette, since method lookup no longer always involves
the lexical scope. For R 3.6.0 and later, you can achieve a similar effect
by using "delayed method registration", i.e. placing the following in your
NAMESPACE
file:
if (getRversion() >= "3.6.0") { S3method(package::generic, class) }
Value
No return value, called for side-effect of registering an S3 generic.
Usage in other packages
To avoid taking a dependency on vctrs
, you copy the source of
s3_register()
into your own package. It is licensed under the permissive
unlicense
to make it
crystal clear that we're happy for you to do this. There's no need to include
the license or even credit us when using this function.
Examples
# A typical use case is to dynamically register tibble/pillar methods
# for your class. That way you avoid creating a hard dependency on packages
# that are not essential, while still providing finer control over
# printing when they are used.
.onLoad <- function(...) {
s3_register("pillar::pillar_shaft", "vctrs_vctr")
s3_register("tibble::type_sum", "vctrs_vctr")
}
Split a Source Reference at specific lines
Description
Split a Source Reference at specific lines
Usage
split_srcref(sr, where)
Arguments
sr |
An original srcref object |
where |
A numeric vector of line numbers where the srcref should be split |
Value
A list of srcref
Build a source location from a minimal numeric vector
Description
Build a length four source location from a length two source location. The starting column on the first line is assumed to be 1, and the final column is taken to be the length of the line if the source file exists, or 1 as a fallback.
Usage
srclocs(x, file)
Arguments
x |
A numeric vector of at least length 2 |
file |
A file to use to determine the length of the final line |
Value
A numeric vector similar to a utils::getSrcLocation
object
Convert a srcref
to a character
representation
Description
Convert a srcref
to a character
representation
Usage
srcref_key(x, nloc = 2, path = c("base", "root", "full"))
Arguments
x |
A |
nloc |
The number of locations ( |
path |
A form of file path to use for the key. One of |
Value
A string hash of a srcref
Determine the number of source code lines of a given srcref
Description
Determine the number of source code lines of a given srcref
Usage
srcref_nlines(x)
Arguments
x |
A srcref object |
Value
The number of lines in the original source of a srcref
Get String Line Count
Description
Get String Line Count
Usage
string_newline_count(x)
Arguments
x |
A character value |
Value
The number of newline characters in a multiline string
Execute examples from Rd files as testthat
tests
Description
Reads examples from Rd files and constructs testthat
-style tests.
testthat
expectations are built such that
Usage
test_examples_as_testthat(
package,
path,
...,
test_dir = file.path(tempdir(), "testex-tests"),
clean = TRUE,
overwrite = TRUE,
roxygenize = !is_r_cmd_check() && uses_roxygen2(path),
reporter = testthat::get_reporter()
)
Arguments
package |
A package name whose examples should be tested |
path |
Optionally, a path to a source code directory to use. Will only
have an effect if parameter |
... |
Additional argument unused |
test_dir |
An option directory where test files should be written. Defaults to a temporary directory. |
clean |
Whether the |
overwrite |
Whether files should be overwritten if |
roxygenize |
Whether R documentation files should be re-written using
|
reporter |
A |
Details
Each example expression is expected to run without error
Any
testex
expectations are expected to pass
Generally, you won't need to use this function directly. Instead, it
is called by a file generated by use_testex_as_testthat()
which will add
any testex
example tests to your existing testthat
testing suite.
Value
The result of testthat::source_file()
, after iterating over
generated test files.
Note
It is assumed that this function is used within a testthat
run, when
the necessary packages are already installed and loaded.
Examples
# library(pkg.example)
path <- system.file("pkg.example", package = "testex")
test_examples_as_testthat(path = path)
Test a list of files
Description
Test a list of files
Usage
test_files(files, context, ...)
Arguments
files |
A collection of file paths to test |
context |
An optional context message to display in |
... |
Additional arguments passed to |
Value
The result of testthat::source_file()
, after iterating over
generated test files.
A syntactic helper for writing quick and easy example tests
Description
A wrapper around stopifnot
that allows you to use .
to refer to
.Last.value
and preserve the last non-test output from an example.
Usage
testex(
...,
srcref = NULL,
example_srcref = NULL,
value = get_example_value(),
envir = parent.frame(),
style = "standalone"
)
Arguments
... |
Expressions to evaluated. |
srcref |
An option |
example_srcref |
An option |
value |
A value to test against. By default, this will use the example's
|
envir |
An environment in which tests should be evaluated. By default the parent environment where tests are evaluated. |
style |
A syntactic style used by the test. Defaults to |
Value
Invisibly returns the .Last.value
as it existed prior to evaluating
the test.
Documenting with testex
testex
is a simple wrapper around execution that propagates the
.Last.value
returned before running, allowing you to chain tests
more easily.
Use in Rd
files:
\examples{ f <- function(a, b) a + b f(3, 4) \testonly{ testex::testex( is.numeric(.), identical(., 7) ) } }
But Rd
files are generally regarded as being a bit cumbersome to author
directly. Instead, testex
provide helpers that generate this style of
documentation, which use this function internally.
Use with roxygen2
Within a roxygen2
@examples
block you can instead use the @test
tag
which will generate Rd code as shown above.
#' @examples #' f <- function(a, b) a + b #' f(3, 4) #' @test is.numeric(.) #' @test identical(., 7)
Cached retrieval of testex options from package DESCRIPTION
Description
As long as the fingerprint
has not changed, the package DESCRIPTION
will
be read only once to parse and retrieve configuration options. If the
DESCRIPTION
file is modified or if run from a separate process, the
configured settings will be refreshed based on the most recent version of
the file.
Usage
memoise_testex_desc(path, fingerprint, ...)
testex_options(path = package_desc(), ...)
Arguments
path |
A path in which to search for a package |
fingerprint |
An object used to indicate when the cached values have been invalidated |
Value
The test options environment, invisibly.
The test options environment as a list
Functions
-
testex_options()
:
Rd Example Parsing Helpers
Description
Rd Example Parsing Helpers
Usage
rd_extract_examples(rd)
rd_code_as_string(rd)
split_testonly_as_expr(rd)
split_testonly(rd)
Arguments
rd |
An Rd object |
Value
The examples section of an Rd object
A formatted Rd example
An interlaced list of expressions, either representing example
code or tests. The names of the list are either \testonly
or RDCODE
depending on the originating source of the expression.
A list of Rd tag contents
Functions
-
rd_extract_examples()
: Extract examples tag from an Rd file -
rd_code_as_string()
: Convert an Rd example to string -
split_testonly_as_expr()
: Split sections of an example into evaluated example code blocks and code blocks wrapped in\testonly
Rd_tag
s, reassigningsrcref
s as the example code is split. -
split_testonly()
: Split sections of an example into lists ofRd_tag
s. Note thatsrcref
s are split by line number. If a line is split between two sections, it is attributed to the first section. As this is used primarily for giving line numbers to test messages, this is sufficient for providing test failures locations.
testex
roxygen2
tags
Description
testex
provides two new roxygen2
tags, @test
and @testthat
.
tags
testex tags are all sub-tags meant to be used within an
@examples
block. They should be considered as tags within the
@examples
block and used to construct blocks of testing code within
example code.
@test
:-
In-line expectations to test the output of the previous command within an example. If
.
is used within the test expression, it will be used to refer to the output of the previous example command. Otherwise, the result of the expression is expected to be identical to the previous output.#' @examples #' 1 + 2 #' @test 3 #' @test . == 3 #' #' @examples #' 3 + 4 #' @test identical(., 7)
@testthat
:-
Similar to
@test
,@testthat
can be used to make in-line assertions usingtestthat
expectations.testthat
expectations follow a convention where the first argument is an object to compare against an expected value or characteristic. Since the value will always be the result of the previous example, this part of the code is implicitly constructed for you.If you want to use the example result elsewhere in your expectation, you can refer to it with a
.
. When used in this way, testex will not do any further implicit modification of your expectation.#' @examples #' 1 + 2 #' @testthat expect_equal(3) #' @testthat expect_gt(0) #' #' @examples #' 3 + 4 #' @testthat expect_equal(., 7)
Support for testthat
Expectations
Description
testthat
support is managed through a "style" provided to testex
.
When using the testthat
style (automatically when using the @testthat
tag), expectations are processed such that they always refer to the previous
example. Special care is taken to manage propagation of this value through
your test code, regardless of how testthat
is executed.
Examples
# example code
1 + 2
# within `testex` block, test code refers to previous result with `.`
testex(style = "testthat", srcref = "abc.R:1:3", {
test_that("addition holds up", {
expect_equal(., 3)
})
})
Add testex
tags and configure package to fully use testex
features
Description
Add testex
tags and configure package to fully use testex
features
Usage
use_testex(path = getwd(), check = TRUE, quiet = FALSE)
Arguments
path |
A package source code working directory |
check |
A |
quiet |
Whether output should be suppressed |
Value
The result of write.dcf()
upon modifying the package
DESCRIPTION
file.
Note
The testex
roxygen2
tags behave similarly to roxygen2
@examples
tags, with the minor addition of some wrapping code to manage the tests. This
means that they will be integrated into your @examples
and can be
intermixed between @examples
tags
Run examples as testthat
expectations
Description
Run examples as testthat
expectations
Usage
use_testex_as_testthat(path = getwd(), context = "testex", quiet = FALSE)
Arguments
path |
A package source code working directory |
context |
A |
quiet |
Whether to emit output messages. |
Value
The result of writeLines()
after writing a new testthat
file.
Checks for use of roxygen2
Description
Checks for use of roxygen2
Usage
uses_roxygen2(path)
Arguments
path |
A file path to a package source code directory |
Value
A logical value indicating whether a package takes roxygen2
as
a dependency.
vapply
shorthand alternatives
Description
Simple wrappers around vapply
for common data types
Usage
vlapply(..., FUN.VALUE = logical(1L))
vcapply(..., FUN.VALUE = character(1L))
vnapply(..., FUN.VALUE = numeric(1L))
Arguments
... |
Arguments passed to |
FUN.VALUE |
A preset signature for the flavor of |
Value
The result of vapply
Temporarily attach a namespace
Description
This function is primarily for managing attaching of namespaces needed for
testing internally. It is exported only because it is needed in code
generated within Rd
files, but is otherwise unlikely to be needed.
Usage
with_attached(ns, expr)
Arguments
ns |
A namespace or namespace name to attach |
expr |
An expression to evaluate while the namespace is attached |
Value
The result of evaluating expr
Raise testthat
Expectations With A Known Source Reference
Description
Retroactively assigns a source file and location to a expectation. This
allows testthat
to report an origin for any code that raised an example
test failure from the source roxygen2
code, even though the test code is
reconstructed from package documentation files.
Usage
with_srcref(src, expr, envir = parent.frame())
Arguments
src |
A |
expr |
An expression to be evaluated. If an |
envir |
An environment in which to evaluate |
Value
The result of evaluating expr
, or an expectation with appended
srcref
information if an expectation is raised.
Wraps an example expression in a testthat
expectation to not error
Description
Wraps an example expression in a testthat
expectation to not error
Usage
wrap_expect_no_error(expr, value)
Arguments
expr |
An expression to wrap in a |
value |
A symbol to use to store the result of |
Value
A testthat::test_that()
call