gentest
-- evaluates a given function for all the combinations of the arguments provided as vectors/lists; the results are presented in a data frame (including possible errors and warnings)
docgen
-- automatically generates the .Rd doc/help file from thegentest
's result; it helps keeping your documentation up-to-date and in sync with the test resultsName
-- use it to tag the return values of your own generator function in a human-readable way, useful whendocgen
is used
Bool
SingleCharacter
String
NumericInRange
IntegerInRange
Scalar
-- randomly selects a random element from a vector (i.e. making the length of a vector == 1).withNA
-- injects a fraction ofNA
s into a vectorwithZero
-- injects a fraction of zeros (0) into a vector (ensuring that zeros are included in the tests)
List
-- a wrapper for listsDataFrame
-- a wrapper for data frames%|%
-- a binary operator to combine different generators in a list; to be read as "or"AsOne
-- the vector wrapped byAsOne
is used as one argument value in an evaluations instead of element-by-element (as scalars)Replicate
-- produces a vector (list) of values generated by a given generator or expression multiple times repeatedlyAnything
-- a convenience wrapper around a few most typical generators
Terminators if something goes wrong in tests:
stopIfErr
stopIfWarn
stopIfErrOrWarn
library(gentest)
# A trivial example to demonstrate
# the data frame generated by `gentest`
res1 <- gentest(paste,
x = c('a','b','c'),
y = 1:2,
z = list(100.5, 'Zzzzz'),
sep = '_')
res1
## x y z sep x..type y..type z..type sep..type ..value ..warning ..error ..value..type
## 1 a 1 100.5 _ character integer numeric character a_1_100.5 NA NA character
## 2 b 1 100.5 _ character integer numeric character b_1_100.5 NA NA character
## 3 c 1 100.5 _ character integer numeric character c_1_100.5 NA NA character
## 4 a 2 100.5 _ character integer numeric character a_2_100.5 NA NA character
## 5 b 2 100.5 _ character integer numeric character b_2_100.5 NA NA character
## 6 c 2 100.5 _ character integer numeric character c_2_100.5 NA NA character
## 7 a 1 Zzzzz _ character integer character character a_1_Zzzzz NA NA character
## 8 b 1 Zzzzz _ character integer character character b_1_Zzzzz NA NA character
## 9 c 1 Zzzzz _ character integer character character c_1_Zzzzz NA NA character
## 10 a 2 Zzzzz _ character integer character character a_2_Zzzzz NA NA character
## 11 b 2 Zzzzz _ character integer character character b_2_Zzzzz NA NA character
## 12 c 2 Zzzzz _ character integer character character c_2_Zzzzz NA NA character
library(magrittr) # for the pipe operator: %>%
tagNA <- function(x) # Helper function used below
if (x %>% is.na)
x %>% gentest:::addClass('NA') else x
# Assume we want to test the function
# `mean(x, na.rm)` paying attention to the
# combinations of arguments when NA is returned:
res2 <- gentest(mean,
tagNA, # this function is applied to the value returned by `mean`
x = NumericInRange(-1e6,1e6) %|%
String(string_length=3) %|% # max 3 chars to fit the table when printed below
(NumericInRange(-1e6,1e6) %>% withNA),
na.rm = T %|% F)
# Now lets' generate file 'mean.Rd' in sub-directory 'man'
# of the current working directory:
docgen(res2, 'Type-checked mean()')
## Saved the doc file in the current working directory as:
## "man/mean.Rd"
See the help file below (as rendered by GitHub):
<title> R: Type-checked mean() </title>
mean | R Documentation |
mean(x, ...)
x
|
NumericInRange(-1e+06,1e+06) or |
na.rm
|
TRUE or |
Returned value
|
x
|
na.rm
|
numeric | NumericInRange(-1e+06,1e+06) | FALSE |
numeric | NumericInRange(-1e+06,1e+06) | TRUE |
numeric | NumericInRange(-1e+06,1e+06) withNA(in 10% of observations) | TRUE |
numeric NA | NumericInRange(-1e+06,1e+06) withNA(in 10% of observations) | FALSE |
numeric NA | String(string\_length = 3) | FALSE |
numeric NA | String(string\_length = 3) | TRUE |
A generator can be any function. If you want to use the result of the gentest
to create automatically the .Rd doc/help file, it's best (though not mandatory) to tag the return value of your generator with a human-readable name through the function Name
:
# Assume you have a generator function that
# generates one of the 3 characters:
# either A or B or C
A_or_B_or_C <- function()
c('A','B','C') %>%
# add a human-readable name via Name()
# if you want to use that generator in
# `docgen`
Name('A or B or C')
res3 <- gentest(paste0,
# `arg1` could be also specified as:
# 'A' %|% 'B' %|% 'C'
arg1 = A_or_B_or_C(),
arg2 = NumericInRange(1,10))
docgen(res3)
## Saved the doc file in the current working directory as:
## "man/paste0.Rd"
See the help file below (as rendered by GitHub):
<title> R: paste0 </title>
paste0 | R Documentation |
paste0(..., collapse = NULL)
arg1
|
A or B or C |
arg2
|
NumericInRange(1,10) |
character
docgen
generates the documentation only for those combinations of arguments that do not return an error:
res4 <- gentest(`+`,
x = 1:3,
y = list(101,102,'abc'))
res4
## x y x..type y..type ..value ..warning ..error ..value..type
## 1 1 101 integer numeric 102 NA NA numeric
## 2 2 101 integer numeric 103 NA NA numeric
## 3 3 101 integer numeric 104 NA NA numeric
## 4 1 102 integer numeric 103 NA NA numeric
## 5 2 102 integer numeric 104 NA NA numeric
## 6 3 102 integer numeric 105 NA NA numeric
## 7 1 abc integer character non-numeric argument to binary operator, ..f(...) NA Error in.... simpleError error condition
## 8 2 abc integer character non-numeric argument to binary operator, ..f(...) NA Error in.... simpleError error condition
## 9 3 abc integer character non-numeric argument to binary operator, ..f(...) NA Error in.... simpleError error condition
# 'character' as one of the possible classes/types for
# argument `y` is NOT included in the doc file:
docgen(res4)
## Saved the doc file in the current working directory as:
## "man/+.Rd"
See the help file below (as rendered by GitHub):
<title> R: + </title>
+ | R Documentation |
`+`(e1, e2)
x
|
integer |
y
|
numeric |
numeric
# More complex (non-atomic) objects (data frames, lists)
# are also supported:
myfun <- function(df)
within(df, {
b <- as.character(a + 1)
y <- !x
})
res5 <- gentest(myfun,
df = Replicate(DataFrame(a = NumericInRange(0, 1e6) %>% withZero,
x = Bool())))
docgen(res5)
## Saved the doc file in the current working directory as:
## "man/myfun.Rd"
See the help file below (as rendered by GitHub):
<title> R: myfun </title>
myfun | R Documentation |
myfun(df)
df
|
data.frame(a = NumericInRange(0,1e+06) withZero(in 10% of observations), x = Bool) |
data.frame(a = numeric, x = logical, y = logical, b = character)