knitr::opts_chunk$set(echo = TRUE)
options(width=200)
library(magrittr)
genHTML <- function(filename) {
    readLines(filename) %T>%
        gsub('\\tab \\tab \\tab','\\tab',.,fixed=TRUE) %>%
        gsub('\\tab \\tab \\tab','\\tab',.,fixed=TRUE) %>%
        gsub('\\tab \\tab',"",.,fixed=TRUE) %>%
        cat(file=filename, sep='\n')
    capture.output(filename %>% tools::Rd2HTML(stdout())) %>%
        sub('<link rel="stylesheet" type="text/css" href="R.css" />',"",.,fixed=TRUE) %>%
        c('\\ \n', 'See the help file below (as rendered by GitHub):\n',
          '- - -', ., '- - -', '\\ \n') %>%
        cat(sep='\n')
    invisible(file.remove(filename))
}

# API

## Testing

## Auto-Documentation

## Built-in generators of atomic vectors

## Modifiers

## Wrappers

## "Safety brakes"

Terminators if something goes wrong in tests:

# Examples

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
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()')
genHTML('man/mean.Rd')

# Using your own generator with docgen

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)
genHTML('man/paste0.Rd')

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
# 'character' as one of the possible classes/types for
# argument `y` is NOT included in the doc file:
docgen(res4)
genHTML('man/+.Rd')
# 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)
genHTML('man/myfun.Rd')


alekrutkowski/gentest documentation built on May 11, 2019, 11:24 p.m.