testextra/ 0000755 0001751 0000144 00000000000 13576367061 012331 5 ustar hornik users testextra/NAMESPACE 0000644 0001751 0000144 00000000272 13372405355 013542 0 ustar hornik users exportPattern("^[[:alpha:]]+")
import(methods)
import(parsetools)
import(pkgcond)
import(testthat)
import(postlogic)
importFrom(assertthat,is.string)
importFrom(assertthat,validate_that) testextra/README.md 0000644 0001751 0000144 00000013633 13411530303 013571 0 ustar hornik users
testextra
====================================================================
[](https://travis-ci.org/RDocTaskForce/testextra) [](https://codecov.io/github/RDocTaskForce/testextra?branch=master) [](https://cran.r-project.org/package=testextra) [](https://www.tidyverse.org/lifecycle/#experimental)
The goal of testextra is to facilitate extraction of tests embedded in source code.
Installation
------------
You will be able to install the released version of testextra from [CRAN](https://CRAN.R-project.org) once it is released with:
``` r
install.packages("testextra")
```
Until then or if you wish to get the latest version prior to release you may install directly from GitHub with:
``` r
remotes::install_github("RDocTaskForce/testextra")
```
Including Tests in Source Code.
-------------------------------
To include tests in source code put your tests following the function definition nested in an `if(FALSE){...}` block and tag it with a `#@testing` block tag.
``` r
#' Hello World Example
hello_world <- function(){
message("hello world!")
}
if(FALSE){#@testing
expect_message(hello_world(), "hello world!")
}
```
Assuming the preceding code is in a package file `./R/hello_world.R` running the `extract_tests()` command will create a file `./tests/testthat/test-hello_world.R` with the contents as below.
``` r
#! This file was automatically produced by the testextra package.
#! Changes will be overwritten.
context('tests extracted from file `hello_world.R`')
#line 5 "./R/hello_world.R"
test_that('hello_world', {#@testing
expect_message(hello_world(), "hello world!")
})
```
When run, if there are error messages, the line given will be the line and file from the original source code.
Combination Functions
---------------------
The functions `test()` and `test_file()` provided in `testextra` will both extract tests from source files, run said tests, and output the results. `test()` operates on a package as a whole or a subset of a package by
setting the filter argument, see the help file for details. `test_file()` is intended to work with the [RStudio](http://rstudio.com) GUI. It takes the currently selected file, extracts tests and runs the tests. This way a tests may be run only for the current file being evaluated.
Both `test()` and `test_file()` are available through the add-ins, and made accessible through the menu of RStudio.
Other Helpers
-------------
The 'testextra\` package provides a number of useful testing functions to use when testing code.
### Inheritance
- **`all_inherit()`** - tests if all elements of a list are of the given class or classes.
- **`are()`** - similar to `all_inherit()`, however uses the `is()` mechanism which is more appropriate for S4 classes.
- **`is_exactly()`** - Tests if an object is a class, but disallows inheritance.
- **`all_are_exactly()`** - The `is_exactly()` test mapped over a list of objects.
### Strings
- **`is_nonempty_string()`** - similar to `asssertthat::is.string()` but also ensures that the provided string is not missing (`NA`) and not empty (`""`)
- **`is_optional_string()`** - same as `is_nonempty_string()` except does allow a character vector of length 0.
### Validity
- **`is_valid()`** - Performs `validObject()` in a manner that is compatible with
`validate_that()`, `assert_that()`, or `see_if()` from the `assertthat` package.
- **`are_valid()`** - `is_valid()` over a list, which when used with the functions listed above gives the indices of objects that are not valid.
- **`expect_valid()`** - Check validity which is to be used with the `testthat` framework.
### Namespaces
When testing dynamic class creation and modification, it is often necessary to have a package environment other that the package environment in which the creation functions are defined. For this purpose, `testextra` provides these namespace manipulation functions.
- **`new_namespace_env()`** - Create a namespace environment. \*Similar functionality exists in `pkgload`, but is not exposed and registers the namespace by default, which `new_namespace_env()` does not.
- **`new_pkg_environment()`** - Create a package environment. Technically a namespace does not have to be a package environment, however that is essentially always the case. This function does allow for registration of the environment as a namespace but does not do so by default.
- **`register_namespace`** - Explicitly register a previously created namespace.
- **`is_namespace_registered`** - Check if a namespace is registered.
### Others
A few other helpers that do not fit into one of the above categories.
- **`catch_condition()`** - Evaluates code and captures any signals that may be raised. Useful for capturing and subsequently running multiple tests on the error captured, as an alternative to `expect_error()`, `expect_warning()`, and `expect_message()` from the `testthat` package.
- **`class0`** - retrieve the class of an object as a single string. Separates elements by a '/' if there are more than one. *Same functionality as the `knitr::klass()` function.*
- **`is_valid_regex`** - Check if a regular expression is valid, not that it does what is intended just that it is valid.
Documentation
-------------
The `testextra` package is developed by the R Documentation Task Force, an [R Consortium](https://www.r-consortium.org) [Infrastructure Steering Committee working group](https://www.r-consortium.org/projects/isc-working-groups).
testextra/man/ 0000755 0001751 0000144 00000000000 13402562417 013072 5 ustar hornik users testextra/man/covr_files.Rd 0000644 0001751 0000144 00000000774 13411527141 015517 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/coverage.R
\name{covr_files}
\alias{covr_files}
\title{Compute coverage for a group of files.}
\usage{
covr_files(filter, pkg = ".", report = TRUE)
}
\arguments{
\item{filter}{A regular expression filter to apply to the files from \code{pkg}.}
\item{pkg}{The package to compute coverage for.}
\item{report}{If a report should be constructed and shown.}
}
\description{
Compute coverage for a group of files.
}
testextra/man/catch_condition.Rd 0000644 0001751 0000144 00000001664 13411527141 016513 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/catch_condition.R
\name{catch_condition}
\alias{catch_condition}
\alias{catch_all_conditions}
\title{Catch a condition for testing.}
\usage{
catch_condition(code)
catch_all_conditions(code)
}
\arguments{
\item{code}{code to run that should assert a condition.}
}
\description{
This function captures a condition object such as a warning or
error, to allow for testing components and classes.
}
\examples{
(cond <- catch_condition(stop("catch me.")))
class(cond)
my_fun <- function(){
message("a message")
warning("a warning")
pkg_message("a package message", scope="test")
pkg_warning("a package warning", scope="test")
pkg_error("a package error", scope='test')
}
conditions <- catch_all_conditions(my_fun())
conditions$messages
conditions$warnings
conditions$error # only one error can be caught at a time.
}
testextra/man/namespaces.Rd 0000644 0001751 0000144 00000004334 13411527141 015477 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/new_namespace.R
\name{namespaces}
\alias{namespaces}
\alias{new_namespace_env}
\alias{new_pkg_environment}
\alias{register_namespace}
\alias{unregister_namespace}
\alias{is_namespace_registered}
\title{Create namespace environments}
\usage{
new_namespace_env(name, path = file.path(tempdir()),
import = "methods")
new_pkg_environment(name = "test package environment", ...,
register = FALSE)
register_namespace(ns)
unregister_namespace(ns)
is_namespace_registered(ns)
}
\arguments{
\item{name}{The name of the environment}
\item{path}{An optional path.}
\item{import}{Package to include in the imports.}
\item{...}{Arguments passed on to \code{new_namespace_env}
\describe{
\item{name}{The name of the environment}
\item{path}{An optional path.}
\item{import}{Package to include in the imports.}
}}
\item{register}{Should the package namespace be registered?}
\item{ns}{a namespace environment or a character name of a namespace.}
}
\description{
Create and manipulate namespace and test package environments.
}
\section{Functions}{
\itemize{
\item \code{new_namespace_env}: Create a new namespace environment
\item \code{new_pkg_environment}: Create a package environment.
All package environments are namespaces but not all
namespaces qualify as package environments.
\item \code{register_namespace}: Register a namespace
\item \code{unregister_namespace}: Remove a namespace from the registry
\item \code{is_namespace_registered}: Check if a namespace is registered
}}
\examples{
ns <- new_namespace_env('my namespace')
isNamespace(ns)
environmentName(ns)
packageName(ns) # not a package
pkg <- new_pkg_environment("myPackage")
isNamespace(pkg)
environmentName(pkg)
packageName(pkg) # now a package
is_namespace_registered(pkg) # but not registered
\dontrun{
asNamespace("myPackage") # so this WILL NOT work.
}
register_namespace(pkg)
is_namespace_registered(pkg) # now registered
asNamespace("myPackage") # so this WILL work.
unregister_namespace(pkg)
is_namespace_registered(pkg) # now unregistered
isNamespace(pkg) # but still a namespace
}
testextra/man/addin_covr_file.Rd 0000644 0001751 0000144 00000000446 13411527142 016470 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/coverage.R
\name{addin_covr_file}
\alias{addin_covr_file}
\title{Add-in for \code{covr_file}}
\usage{
addin_covr_file()
}
\description{
This allows for \link{covr_file} to be run from a menu in RStudio.
}
testextra/man/extract_tests.Rd 0000644 0001751 0000144 00000002605 13411527141 016253 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/extract_tests.R
\name{extract_tests}
\alias{extract_tests}
\title{Extract tests from source}
\usage{
extract_tests(pkg = ".", filter = NULL,
verbose = getOption("verbose", FALSE), full.path = NA,
force = FALSE)
}
\arguments{
\item{pkg}{The root directory of the package.}
\item{filter}{If specified, only tests from files matching
this regular expression are extracted.}
\item{verbose}{Print message?}
\item{full.path}{Include full file paths in generated files.
TRUE, indicates full path,
FALSE, indicated only basename, and
NA(default) implies path relative to \code{pkg}.}
\item{force}{Force test extraction even if the generated test file
is newer than the corresponding source file.}
}
\description{
Use this function to extract tests from package source files.
In-source testing blocks are contained in blocks that are prevented
from running when sourced by an \code{if(FALSE){...}} statement.
It also contains a documentation tag to denote a testing block.
}
\details{
The first line of the block should look similar to\preformatted{ if(FALSE){#@testing [optional information]
...
}
}
}
\examples{
\dontrun{
# Extract all files
extract_tests('.')
# Extract only files that start with 'Class-' or 'class-'
extract_tests('.', filter="^[Cc]lass-.*\\\\.[Rr]$")
}
}
testextra/man/covr-rendering-single.Rd 0000644 0001751 0000144 00000002115 13411527141 017556 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/coverage.R
\name{covr-rendering-single}
\alias{covr-rendering-single}
\alias{.renderSourceRow}
\alias{.renderSourceFile}
\alias{.single_file_summary}
\alias{.renderReport}
\title{Rendering for single file report}
\usage{
.renderSourceRow(line, source, coverage)
.renderSourceFile(lines, file = "source", highlight = TRUE)
.single_file_summary(file_stats)
.renderReport(coverage, report.file, dir = dirname(report.file),
libdir = file.path(dir, "lib"))
}
\arguments{
\item{line, lines}{Line(s) number}
\item{source}{source file}
\item{coverage}{The number of times covered}
\item{file}{the file in question}
\item{highlight}{Highlight the row.}
\item{file_stats}{The coverage object for the file.}
\item{report.file}{Where to output the HTML report.}
\item{dir}{the base directory for the HTML output}
\item{libdir}{Where to put html dependencies?}
}
\description{
These functions facilitate the creation of reports for coverage of a
single file.
}
\concept{coverage}
testextra/man/covr-single.Rd 0000644 0001751 0000144 00000003106 13411530130 015574 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/coverage.R
\name{covr-single}
\alias{covr-single}
\alias{file_coverage}
\alias{covr_file}
\title{Single File Coverage}
\usage{
file_coverage(file = rstudioapi::getSourceEditorContext()$path,
pkg = ".", ...)
covr_file(coverage = file_coverage(), report.file = NULL,
show.report = interactive())
}
\arguments{
\item{file}{The file to extract test from and compute coverage.}
\item{pkg}{The package \code{file} is associated with.}
\item{...}{Arguments passed on to \code{covr::file_coverage}
\describe{
\item{source_files}{Character vector of source files with function
definitions to measure coverage}
\item{test_files}{Character vector of test files with code to test the
functions}
\item{line_exclusions}{a named list of files with the lines to exclude from
each file.}
\item{function_exclusions}{a vector of regular expressions matching function
names to exclude. Example \code{print\\\\.} to match print methods.}
\item{parent_env}{The parent environment to use when sourcing the files.}
}}
\item{coverage}{Coverage returned from \code{file_coverage()}.}
\item{report.file}{Where to save the HTML report.}
\item{show.report}{if the HTML report should be displayed.}
}
\description{
These functions extract tests, run tests and create a report of the coverage for
a single file.
}
\section{Functions}{
\itemize{
\item \code{file_coverage}: Extract tests and compute the coverage for the given file.
\item \code{covr_file}: Create a report for a single
}}
testextra/man/class-expectations.Rd 0000644 0001751 0000144 00000002710 13411527141 017165 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/inheritance.R
\name{class-expectations}
\alias{class-expectations}
\alias{expect_is_not}
\alias{expect_is_exactly}
\alias{expect_all_inherit}
\title{Class Expectations}
\usage{
expect_is_not(object, class, info = NULL, label = NULL)
expect_is_exactly(object, class, info = NULL, label = NULL)
expect_all_inherit(object, class, info = NULL, label = NULL)
}
\arguments{
\item{object}{the object in question.}
\item{class}{the expected class object is to be.}
\item{info}{extra information to be included in the message (useful when
writing tests in loops).}
\item{label}{object label. When \code{NULL}, computed from deparsed object.}
}
\description{
These extend the \link[testthat:expect_is]{testthat::expect_is} to have finer grain tests.
}
\section{Functions}{
\itemize{
\item \code{expect_is_not}: test that an object does \strong{not} inherit from a class.
\item \code{expect_is_exactly}: test that an object is exactly a specific class
and not a child class.
\item \code{expect_all_inherit}: test that all elements of a list inherit a given class.
}}
\examples{
# Test to make sure an object is not of a class.
\dontrun{
# will return an error.
expect_is_not(1L, "numeric")
}
# but this is fine.
expect_is_not('a', "numeric")
expect_is_exactly('a', "character")
}
\seealso{
Other class: \code{\link{class-tests}}
}
\concept{class}
testextra/man/expect_valid.Rd 0000644 0001751 0000144 00000001607 13411527141 016027 0 ustar hornik users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/validity.R
\name{expect_valid}
\alias{expect_valid}
\title{Expect an S4 object is valid}
\usage{
expect_valid(object, complete = FALSE, info = NULL, label = NULL)
}
\arguments{
\item{object}{an S4 object to test for validity}
\item{complete}{logical; if \code{TRUE}, \code{validObject} is
called recursively for each of the slots. The default is \code{FALSE}.}
\item{info}{extra information to be included in the message (useful when
writing tests in loops).}
\item{label}{object label. When \code{NULL}, computed from deparsed object.}
}
\description{
Similar to \code{\link[=is_valid]{is_valid()}} except designed to work in the
\code{\link[testthat:test_that]{testthat::test_that()}} framework.
}
\seealso{
Other validity-tests: \code{\link{validity-tests}}
}
\concept{validity-tests}
testextra/man/figures/ 0000755 0001751 0000144 00000000000 13375317063 014542 5 ustar hornik users testextra/man/figures/logo.png 0000644 0001751 0000144 00000024233 13375317134 016213 0 ustar hornik users PNG
IHDR y X sBIT|d pHYs ` `֝ tEXtSoftware www.inkscape.org< IDATxw`TUƟNd3BABJET\Eˊ]ׂJquEB !BHLzr!@ȄL`L_0ssO{9/BTTI|}}\\\ڻ\mwڂ( K5?cǎmkbȡ] |
d?3ڦTmm)rr|f~?X.Jߊ/o9.A`" :g (>[{
f659888L% Jwt<0 UUjKM(V,rEH$oxӥюWkjE\JMl3FQ_INNjՋhe:}+ `*Ϡ~dMb_`W\USYr27w6o\}o:!!!h S2
BfhJ
P##[wL"*6o-P"$qFt###]Z[ ĈYcGUpu CY"J-((( 3̼Zɓ|VƪE?ADp3'g{'λ~vcQԴJχpuDND >,55U944t% JpY*鷃"{0UdūbnMSv^NHHjX9$$+} `t
x^g-[TVl:wN!PEذjP]xuݢ(|ڢEFdsJ77x7oj @93wD(JI|E=Xփ`Z ,vbbbzX6 2ggB=ͱ[NfdNCBxPXbUfGYI)Oga8Va
Z~v}ٮ"3f4^oE>8 B#/2V녪ZBn*gdb8β&e