assert {testit}R Documentation

Assertions with an optional message

Description

The function assert() was inspired by stopifnot(). It emits a message in case of errors, which can be a helpful hint for diagnosing the errors (stopifnot() only prints the possibly truncated source code of the expressions).

The infix operator %==% is simply an alias of the identical() function to make it slightly easier and intuitive to write test conditions. x %==% y is the same as identical(x, y). When it is used inside assert(), a message will be printed if the returned value is not TRUE, to show the values of the LHS (x) and RHS (y) via str(), which can be helpful for you to check why the assertion failed.

Usage

assert(fact, ...)

x %==% y

Arguments

fact

a message for the assertions when any of them fails; treated the same way as expressions in ... if it is not a character string, which means you do not have to provide a message to this function

...

any number of R expressions; see Details

x, y

two R objects to be compared

Details

There are two ways to write R expressions in the ... argument.

The first way is a single R expression wrapped in {} and passed as a single argument. This expression may contain multiple sub-expressions. A sub-expression is treated as a test condition if it is wrapped in () (meaning its value will be checked to see if it is a logical vector containing any FALSE values) , otherwise it is evaluated in the normal way and its value will not be checked. If the value of the last sub-expression is logical, it will also be treated as a test condition.

The second way is a series of R expressions (each expression is passed as an individual argument) that return vectors of TRUE's (if FALSE is returned anywhere, an error will show up).

Value

For assert(), invisible NULL if all expressions returned TRUE, otherwise an error is signalled and the user-provided message is emitted. For %==%, TRUE or FALSE.

Note

The internal implementation of assert() is different with the stopifnot() function in R base: (1) the custom message fact is emitted if an error occurs; (2) assert() requires the logical values to be non-empty (logical(0) will trigger an error); (3) if ... contains a compound expression in {} that returns FALSE (e.g., if (TRUE) {1+1; FALSE}), the first and the last but one line of the source code from deparse() are printed in the error message, otherwise the first line is printed; (4) the arguments in ... are evaluated sequentially, and assert() will signal an error upon the first failed assertion, and will ignore the rest of assertions.

Examples

## The first way to write assertions -------------------

assert("T is bad for TRUE, and so is F for FALSE", {
    T = FALSE
    F = TRUE
    (T != TRUE)  # note the parentheses
    (F != FALSE)
})

assert("A Poisson random number is non-negative", {
    x = rpois(1, 10)
    (x >= 0)
    (x > -1)  # () is optional because it's the last expression
})


## The second way to write assertions --------------------

assert("one equals one", 1 == 1)
assert("seq and : produce equal sequences", seq(1L, 10L) == 1L:10L)
assert("seq and : produce identical sequences", identical(seq(1L, 10L), 1L:10L))

# multiple tests
T = FALSE
F = TRUE
assert("T is bad for TRUE, and so is F for FALSE", T != TRUE, F != FALSE)

# a mixture of tests
assert("Let's pray all of them will pass", 1 == 1, 1 != 2, letters[4] == "d", 
    rev(rev(letters)) == letters)

# logical(0) cannot pass assert(), although stopifnot() does not care
try(assert("logical(0) cannot pass", 1 == integer(0)))
stopifnot(1 == integer(0))  # it's OK!

# a compound expression
try(assert("this if statement returns TRUE", if (TRUE) {
    x = 1
    x == 2
}))

# no message
assert(!FALSE, TRUE, is.na(NA))

[Package testit version 0.7.1 Index]