Nothing
## RUnit : A unit test framework for the R programming language
## Copyright (C) 2003-2009 Thomas Koenig, Matthias Burger, Klaus Juenemann
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; version 2 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## $Id$
printHTMLProtocol <- function(testData,
fileName = "",
separateFailureList = TRUE,
traceBackCutOff=9,
testFileToLinkMap=function(x) x) {
##@bdescr
## Report generator
## Extracts the log information stored in the 'RUnitTestData' test run object
## and generates a well formated HTML output.
##@edescr
##
##@in testData : [RUnitTestData] S3 class object
##@in fileName : [character]
##@in separateFailureList : [logical] if TRUE (default) add a list of all failures
##@in traceBackCutOff : [integer] number of steps back in the trace back stack to be displayed
##@in testFileToLinkMap : [function] a function transforming the full name of the test file to a link location
##@ret : [logical] TRUE if execution completed w/o error
##
##@codestatus : testing
## --------------------------------
## CHECK OF INPUT DATA
## --------------------------------
if (!is(testData, "RUnitTestData"))
{
stop("Argument 'testData' must be of class 'RUnitTestData'.")
}
if (!is.character(fileName))
{
stop("Argument 'fileName' has to be of type character.")
}
if (length(fileName) != 1)
{
stop("Argument 'fileName' must contain exactly one element.")
}
if (!is.logical(separateFailureList))
{
stop("Argument 'separateFailureList' has to be of type logical.")
}
if (length(separateFailureList) != 1)
{
stop("Argument 'separateFailureList' must contain exactly one element.")
}
if (!is.numeric(traceBackCutOff))
{
stop("Argument 'traceBackCutOff' has to be of type logical.")
}
if (length(traceBackCutOff) != 1)
{
stop("Argument 'traceBackCutOff' must contain exactly one element.")
}
if (traceBackCutOff < 0 || traceBackCutOff > 100)
{
stop("Argument 'traceBackCutOff' out of valid range [0, 100].")
}
## --------------------------------
## HELPER FUNCTIONS
## --------------------------------
## get singular or plural right
sop <- function(number, word, plext="s") {
ifelse(number == 1, paste(number, word),
paste(number, paste(word, plext, sep="")))
}
pr <- function(...) {
writeRaw(paste(...), htmlFile=fileName)
writeRaw("<br/>", htmlFile=fileName)
}
writeP <- function(string, para="") {
writeBeginTag("p", para=para, htmlFile=fileName)
writeRaw(string, htmlFile=fileName)
writeEndTag("p", htmlFile=fileName)
writeCR(htmlFile=fileName)
}
writeLi <- function(..., para="") {
writeBeginTag("li", para=para, htmlFile=fileName)
writeRaw(paste(...), htmlFile=fileName)
writeEndTag("li", htmlFile=fileName)
}
createTestFuncRef <- function(testSuite, srcFileName, testFuncName,
asAnchor=FALSE) {
tmp <- paste(testSuite, srcFileName, testFuncName, sep="_")
if(asAnchor) {
return(paste("#", gsub("/", "_", tmp), sep=""))
} else {
return(gsub("/", "_", tmp))
}
}
printTraceBack <- function(traceBack) {
if(length(traceBack) > 0) {
writeRaw("Call Stack:<br/>", htmlFile=fileName)
if(traceBackCutOff > length(testFuncInfo$traceBack)) {
writeRaw("(traceBackCutOff argument larger than length of trace back: full trace back printed)<br/>", htmlFile=fileName)
writeBeginTag("ol", htmlFile=fileName)
for(i in seq_along(traceBack)) {
writeBeginTag("li", htmlFile=fileName)
writeRaw(traceBack[i], htmlFile=fileName)
writeEndTag("li", htmlFile=fileName)
}
} else {
writeBeginTag("ol", htmlFile=fileName)
for(i in traceBackCutOff:length(traceBack)) {
writeBeginTag("li", htmlFile=fileName)
writeRaw(traceBack[i], htmlFile=fileName)
writeEndTag("li", htmlFile=fileName)
}
}
writeEndTag("ol", htmlFile=fileName)
}
}
errorStyle <- "color:red"
deactivatedStyle <- "color:black"
## --------------------------------------------
## PART 1: TITLE AND BASIC ERROR INFORMATION
## --------------------------------------------
## title
title <- paste("RUNIT TEST PROTOCOL", date(), sep="--")
writeHtmlHeader(title, htmlFile=fileName)
writeHtmlSection(title, 1, htmlFile=fileName)
if(length(testData) == 0) {
writeP(" no test cases :-(")
return(invisible(TRUE))
}
## basic Info
errInfo <- getErrors(testData)
writeP(paste("Number of test functions:", errInfo$nTestFunc))
if(errInfo$nDeactivated > 0) {
writeP(paste("Number of deactivated test functions:", errInfo$nDeactivated),
para=ifelse(errInfo$nDeactivated == 0, "", paste("style", deactivatedStyle, sep="=")))
}
writeP(paste("Number of errors:", errInfo$nErr),
para=ifelse(errInfo$nErr == 0, "", paste("style", errorStyle, sep="=")))
writeP(paste("Number of failures:", errInfo$nFail),
para=ifelse(errInfo$nFail == 0, "", paste("style", errorStyle, sep="=")))
writeHtmlSep(htmlFile=fileName)
## --------------------------------
## PART 2: TABLE OF TEST SUITES
## --------------------------------
## summary of test suites
writeHtmlSection(sop(length(testData), "Test suite"), 3, htmlFile=fileName)
## table of test suites
if(errInfo$nDeactivated > 0) {
writeBeginTable(c("Name", "Test functions", "Deactivated", "Errors", "Failures"),
width="80%",
htmlFile=fileName,
columnWidth=c("20%", "20%", "20%", "20%", "20%"))
for(tsName in names(testData)) {
rowString <- c(paste("<a href=\"#", tsName, "\">", tsName, "</a>", sep=""),
testData[[tsName]]$nTestFunc,
testData[[tsName]]$nDeactivated,
testData[[tsName]]$nErr,
testData[[tsName]]$nFail)
rowCols <- c("", "",
ifelse(testData[[tsName]]$nDeactivated==0, "", "yellow"),
ifelse(testData[[tsName]]$nErr==0, "", "red"),
ifelse(testData[[tsName]]$nFail==0, "", "red"))
writeTableRow(row=rowString, bgcolor=rowCols, htmlFile=fileName)
}
writeEndTable(htmlFile=fileName)
}
else { ## skip 'deactivated' column if no function has been deactivated
writeBeginTable(c("Name", "Test functions", "Errors", "Failures"),
width="60%",
htmlFile=fileName,
columnWidth=c("30%", "30%", "20%", "20%"))
for(tsName in names(testData)) {
rowString <- c(paste("<a href=\"#", tsName, "\">", tsName, "</a>", sep=""),
testData[[tsName]]$nTestFunc,
testData[[tsName]]$nErr,
testData[[tsName]]$nFail)
rowCols <- c("", "",
ifelse(testData[[tsName]]$nErr==0, "", "red"),
ifelse(testData[[tsName]]$nFail==0, "", "red"))
writeTableRow(row=rowString, bgcolor=rowCols, htmlFile=fileName)
}
writeEndTable(htmlFile=fileName)
}
writeHtmlSep(htmlFile=fileName)
## ------------------------------------------------
## PART 3: ERROR, FAILURE AND DEACTIVATED TABLES
## -------------------------------------------------
## error table
if(separateFailureList && (errInfo$nErr > 0)) {
writeHtmlSection("Errors", 3, htmlFile=fileName)
writeBeginTable(c("Test suite : test function", "message"),
htmlFile=fileName,
columnWidth=c("30%", "70%"))
for(tsName in names(testData)) {
if(testData[[tsName]]$nErr > 0) {
srcFileRes <- testData[[tsName]]$sourceFileResults
srcFileNames <- names(srcFileRes)
for(i in seq_along(srcFileRes)) {
testFuncNames <- names(srcFileRes[[i]])
for(j in seq_along(testFuncNames)) {
funcList <- srcFileRes[[i]][[testFuncNames[j]]]
if(funcList$kind == "error") {
lnk <- paste("<a href=\"",
createTestFuncRef(tsName, srcFileNames[i],
testFuncNames[j], asAnchor=TRUE),
"\">",
paste(tsName, testFuncNames[j], sep=" : "),
"</a>", sep="")
writeTableRow(row=c(lnk, funcList$msg),
htmlFile=fileName)
}
}
}
}
}
writeEndTable(htmlFile=fileName)
writeHtmlSep(htmlFile=fileName)
}
## failure table
if(separateFailureList && (errInfo$nFail > 0)) {
writeHtmlSection("Failures", 3, htmlFile=fileName)
writeBeginTable(c("Test suite : test function", "message"),
htmlFile=fileName,
columnWidth=c("30%", "70%"))
for(tsName in names(testData)) {
if(testData[[tsName]]$nFail > 0) {
srcFileRes <- testData[[tsName]]$sourceFileResults
srcFileNames <- names(srcFileRes)
for(i in seq_along(srcFileRes)) {
testFuncNames <- names(srcFileRes[[i]])
for(j in seq_along(testFuncNames)) {
funcList <- srcFileRes[[i]][[testFuncNames[j]]]
if(funcList$kind == "failure") {
lnk <- paste("<a href=\"",
createTestFuncRef(tsName, srcFileNames[i],
testFuncNames[j], asAnchor=TRUE),
"\">",
paste(tsName, testFuncNames[j], sep=" : "),
"</a>", sep="")
writeTableRow(row=c(lnk, funcList$msg),
htmlFile=fileName)
}
}
}
}
}
writeEndTable(htmlFile=fileName)
writeHtmlSep(htmlFile=fileName)
}
## deactivated table
if(separateFailureList && (errInfo$nDeactivated > 0)) {
writeHtmlSection("Deactivated", 3, htmlFile=fileName)
writeBeginTable(c("Test suite : test function", "message"),
htmlFile=fileName,
columnWidth=c("30%", "70%"))
for(tsName in names(testData)) {
if(testData[[tsName]]$nDeactivated > 0) {
srcFileRes <- testData[[tsName]]$sourceFileResults
srcFileNames <- names(srcFileRes)
for(i in seq_along(srcFileNames)) {
testFuncNames <- names(srcFileRes[[i]])
for(j in seq_along(testFuncNames)) {
funcList <- srcFileRes[[i]][[testFuncNames[j]]]
if(funcList$kind == "deactivated") {
lnk <- paste("<a href=\"",
createTestFuncRef(tsName, srcFileNames[i],
testFuncNames[j], asAnchor=TRUE),
"\">",
paste(tsName, testFuncNames[j], sep=" : "),
"</a>", sep="")
writeTableRow(row=c(lnk, funcList$msg),
htmlFile=fileName)
}
}
}
}
}
writeEndTable(htmlFile=fileName)
writeHtmlSep(htmlFile=fileName)
}
## --------------------------------
## PART 4: DETAILS
## --------------------------------
writeHtmlSection("Details", 3, htmlFile=fileName)
## loop over all test suites
for(tsName in names(testData)) {
tsList <- testData[[tsName]]
writeBeginTag("p", htmlFile=fileName)
writeBeginTag("a", para=paste("name=\"", tsName, "\"", sep=""),
htmlFile=fileName)
writeHtmlSection(paste("Test Suite:", tsName), 5, htmlFile=fileName)
writeEndTag("a", htmlFile=fileName)
pr("Test function regexp:", tsList$testFuncRegexp)
pr("Test file regexp:", tsList$testFileRegexp)
if(length(tsList$dirs) == 0) {
pr("No directories !")
}
else {
if(length(tsList$dirs) == 1) {
pr("Involved directory:")
}
else {
pr("Involved directories:")
}
for(dir in tsList$dirs) {
pr(dir)
}
res <- tsList$sourceFileResults
testFileNames <- names(res)
if(length(res) == 0) {
pr(" no test files")
}
else {
## loop over all source files
writeBeginTag("ul", htmlFile=fileName)
for(testFileName in testFileNames) {
testFuncNames <- names(res[[testFileName]])
if(length(testFuncNames) > 0) {
writeBeginTag("li", htmlFile=fileName)
writeLink(target=testFileToLinkMap(testFileName),
name=paste("Test file:", basename(testFileName)),
htmlFile=fileName)
## loop over all test functions in the test file
writeBeginTag("ul", htmlFile=fileName)
for(testFuncName in testFuncNames) {
writeBeginTag("li", htmlFile=fileName)
testFuncInfo <- res[[testFileName]][[testFuncName]]
anchorName <- createTestFuncRef(tsName, testFileName, testFuncName)
writeBeginTag("a", para=paste("name=\"", anchorName, "\"", sep=""),
htmlFile=fileName)
if(testFuncInfo$kind == "success") {
pr(paste(testFuncName, ": (",testFuncInfo$checkNum, " checks) ... OK (", testFuncInfo$time,
" seconds)", sep=""))
writeEndTag("a", htmlFile=fileName)
}
else {
if(testFuncInfo$kind == "error") {
writeBeginTag("u", para=paste("style", errorStyle, sep="="),
htmlFile=fileName)
writeRaw(paste(testFuncName, ": ERROR !! ", sep=""),
htmlFile=fileName)
writeEndTag("u", htmlFile=fileName)
writeEndTag("a", htmlFile=fileName)
}
else if (testFuncInfo$kind == "failure") {
writeBeginTag("u", para=paste("style", errorStyle, sep="="),
htmlFile=fileName)
writeRaw(paste(testFuncName, ": FAILURE !! (check number ",
testFuncInfo$checkNum, ") ", sep=""),
htmlFile=fileName)
writeEndTag("u", htmlFile=fileName)
writeEndTag("a", htmlFile=fileName)
}
else if (testFuncInfo$kind == "deactivated") {
writeBeginTag("u", para=paste("style", deactivatedStyle, sep="="),
htmlFile=fileName)
writeRaw(paste(testFuncName, ": DEACTIVATED, ", sep=""),
htmlFile=fileName)
writeEndTag("a", htmlFile=fileName)
}
else {
writeLi(paste(testFuncName, ": unknown error kind", sep=""))
writeEndTag("a", htmlFile=fileName)
}
pr(testFuncInfo$msg)
printTraceBack(testFuncInfo$traceBack)
}
writeEndTag("li", htmlFile=fileName)
}
writeEndTag("ul", htmlFile=fileName)
}
writeEndTag("li", htmlFile=fileName)
}
writeEndTag("ul", htmlFile=fileName)
}
}
writeHtmlSep(htmlFile=fileName)
}
ver <- cbind(unlist(version))
## add host name
ver <- rbind(ver, Sys.info()["nodename"])
rownames(ver)[dim(ver)[1]] <- "host"
colnames(ver) <- "Value"
## compiler used (under *nix)
rhome <- Sys.getenv("R_HOME")
## on Windows Makeconf does not exist
## other than that we have no indication which compiler
## would be used for R CMD INSTALL so we report NA
gccVersion <- as.character(NA)
makeconfFile <- file.path(rhome, "etc", "Makeconf")
if (file.exists(makeconfFile) && identical(.Platform$OS.type, "unix")) {
gccVersion <- system(paste("cat ", makeconfFile," | grep \"^CXX =\" "),
intern=TRUE)
gccVersion <- sub("^CXX[ ]* =[ ]*", "", gccVersion)
}
ver <- rbind(ver, gccVersion)
rownames(ver)[dim(ver)[1]] <- "compiler"
writeHtmlTable(ver,
htmlFile=fileName,
border=0,
width="80%",
append=TRUE)
## finish html document
writeHtmlEnd(htmlFile=fileName)
return(invisible(TRUE))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.